-
Notifications
You must be signed in to change notification settings - Fork 563
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BNER support: Add top-level bner {en,de}coding
The BNER support in the asn1c compiler will only support the BNER variable encoding rules. The bner_{en,de}code() functions will to see if the PDU being {en,de}coded is one that requires BNER fixed encoding rules (these are "BACnet.*PDU". If it is, then it will call bner_fixed_{en,de}coder() These two functions are declared as weak functions that will return an error. The intent here is that an external project will provide replacement functions for these two functions.
- Loading branch information
Showing
6 changed files
with
277 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* | ||
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved. | ||
* Redistribution and modifications are permitted subject to BSD license. | ||
*/ | ||
#include <asn_internal.h> | ||
#include <bner_decoder.h> | ||
#include <errno.h> | ||
|
||
/* | ||
* The BNER decoder of any type. | ||
*/ | ||
asn_dec_rval_t | ||
bner_decode(const asn_codec_ctx_t *opt_codec_ctx, | ||
const asn_TYPE_descriptor_t *td, void **struct_ptr, const void *ptr, | ||
size_t size) { | ||
asn_codec_ctx_t s_codec_ctx; | ||
|
||
if(!td) { | ||
asn_dec_rval_t tmp_error = {RC_FAIL, 0}; | ||
ASN_DEBUG("%s: Failed to decode. type_descriptor NULL", __func__); | ||
return tmp_error; | ||
} | ||
|
||
/* | ||
* Stack checker requires that the codec context | ||
* must be allocated on the stack. | ||
*/ | ||
if(opt_codec_ctx) { | ||
if(opt_codec_ctx->max_stack_size) { | ||
s_codec_ctx = *opt_codec_ctx; | ||
opt_codec_ctx = &s_codec_ctx; | ||
} | ||
} else { | ||
/* If context is not given, be security-conscious anyway */ | ||
memset(&s_codec_ctx, 0, sizeof(s_codec_ctx)); | ||
s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX; | ||
opt_codec_ctx = &s_codec_ctx; | ||
} | ||
|
||
if(is_bner_fixed_pdu(td->name)) { | ||
return bner_fixed_decoder(opt_codec_ctx, td, | ||
struct_ptr, /* Pointer to the dest struct */ | ||
ptr, size /* Buffer and its size */ | ||
); | ||
} | ||
|
||
/* | ||
* Invoke type-specific decoder. | ||
*/ | ||
return td->op->bner_decoder(opt_codec_ctx, td, | ||
struct_ptr, /* Pointer to the dest struct */ | ||
ptr, size, /* Buffer and its size */ | ||
0 /* Default tag mode is 0 */ | ||
); | ||
} | ||
|
||
|
||
__attribute__((weak)) asn_dec_rval_t | ||
bner_fixed_decoder(const struct asn_codec_ctx_s *opt_codec_ctx, | ||
const struct asn_TYPE_descriptor_s *td, | ||
void **struct_ptr, /* Ptr to a target struct's ptr */ | ||
const void *buffer, /* Data to be decoded */ | ||
size_t size /* Size of that buffer */ | ||
) { | ||
(void)opt_codec_ctx; | ||
(void)td; | ||
(void)struct_ptr; | ||
(void)buffer; | ||
(void)size; | ||
|
||
asn_dec_rval_t tmp_error = {RC_FAIL, 0}; | ||
ASN_DEBUG("Failed to decode %s. No bner_fixed_decoder function provided", | ||
td->name); | ||
return tmp_error; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved. | ||
* Redistribution and modifications are permitted subject to BSD license. | ||
*/ | ||
#ifndef _BNER_DECODER_H_ | ||
#define _BNER_DECODER_H_ | ||
|
||
#include <asn_application.h> | ||
#include <bner_support.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
struct asn_TYPE_descriptor_s; /* Forward declaration */ | ||
struct asn_codec_ctx_s; /* Forward declaration */ | ||
|
||
/* | ||
* Type of generic function which decodes the byte stream into the structure. | ||
*/ | ||
typedef asn_dec_rval_t(bner_type_decoder_f)( | ||
const struct asn_codec_ctx_s *opt_codec_ctx, | ||
const struct asn_TYPE_descriptor_s *td, void **struct_ptr, | ||
const void *buf_ptr, size_t size, int tag_mode); | ||
|
||
/* | ||
* The BNER decoder of any type. | ||
* This function may be invoked directly from the application. | ||
*/ | ||
asn_dec_rval_t bner_decode(const struct asn_codec_ctx_s *opt_codec_ctx, | ||
const struct asn_TYPE_descriptor_s *td, | ||
void **struct_ptr, /* Ptr to target's struct ptr */ | ||
const void *buffer, /* Data to be decoded */ | ||
size_t size /* Size of that buffer */ | ||
); | ||
|
||
asn_dec_rval_t bner_fixed_decoder(const struct asn_codec_ctx_s *opt_codec_ctx, | ||
const struct asn_TYPE_descriptor_s *td, | ||
void **struct_ptr, /* Ptr to target ptr */ | ||
const void *buffer, /* Data to be decoded */ | ||
size_t size /* Size of that buffer */ | ||
); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* _BNER_DECODER_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved. | ||
* Redistribution and modifications are permitted subject to BSD license. | ||
*/ | ||
#include <asn_internal.h> | ||
#include <bner_encoder.h> | ||
#include <errno.h> | ||
|
||
/* | ||
* The BNER encoder of any type. | ||
*/ | ||
asn_enc_rval_t | ||
bner_encode(const asn_TYPE_descriptor_t *td, const void *sptr, | ||
asn_app_consume_bytes_f *consume_bytes, void *app_key) { | ||
if(!td) ASN__ENCODE_FAILED; | ||
|
||
ASN_DEBUG("BNER encoder invoked for %s", td->name); | ||
|
||
if(is_bner_fixed_pdu(td->name)) { | ||
return bner_fixed_encoder(td, sptr, consume_bytes, app_key); | ||
} | ||
|
||
/* | ||
* Invoke type-specific encoder. | ||
*/ | ||
return td->op->bner_encoder(td, sptr, 0, 0, consume_bytes, app_key); | ||
} | ||
|
||
/* | ||
* Argument type and callback necessary for bner_encode_to_buffer(). | ||
*/ | ||
typedef struct enc_to_buf_arg { | ||
void *buffer; | ||
size_t left; | ||
} enc_to_buf_arg; | ||
|
||
static int | ||
encode_to_buffer_cb(const void *buffer, size_t size, void *key) { | ||
enc_to_buf_arg *arg = (enc_to_buf_arg *)key; | ||
|
||
if(arg->left < size) return -1; /* Data exceeds the available buffer size */ | ||
|
||
memcpy(arg->buffer, buffer, size); | ||
arg->buffer = ((char *)arg->buffer) + size; | ||
arg->left -= size; | ||
|
||
return 0; | ||
} | ||
|
||
/* | ||
* A variant of the bner_encode() which encodes the data into the provided | ||
* buffer | ||
*/ | ||
asn_enc_rval_t | ||
bner_encode_to_buffer(const asn_TYPE_descriptor_t *td, | ||
const void *struct_ptr, void *buffer, | ||
size_t buffer_size) { | ||
enc_to_buf_arg arg; | ||
asn_enc_rval_t ec; | ||
|
||
arg.buffer = buffer; | ||
arg.left = buffer_size; | ||
|
||
if(is_bner_fixed_pdu(td->name)) { | ||
ec = bner_fixed_encoder(td, struct_ptr, | ||
encode_to_buffer_cb, &arg); | ||
} else { | ||
ec = td->op->bner_encoder( | ||
td, | ||
struct_ptr, /* Pointer to the destination structure */ | ||
0, 0, encode_to_buffer_cb, &arg); | ||
} | ||
|
||
if(ec.encoded != -1) { | ||
assert(ec.encoded == (ssize_t)(buffer_size - arg.left)); | ||
/* Return the encoded contents size */ | ||
} | ||
return ec; | ||
} | ||
|
||
__attribute__((weak)) asn_enc_rval_t | ||
bner_fixed_encoder(const struct asn_TYPE_descriptor_s *td, | ||
const void *sptr, /* Structure to be encoded */ | ||
asn_app_consume_bytes_f *consume_bytes_cb, | ||
void *app_key /* Arbitrary callback argument */ | ||
) { | ||
(void)td; | ||
(void)sptr; | ||
(void)consume_bytes_cb; | ||
(void)app_key; | ||
|
||
ASN_DEBUG("Failed to decode %s. No bner_fixed_encoder function provided", | ||
td->name); | ||
ASN__ENCODE_FAILED; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved. | ||
* Redistribution and modifications are permitted subject to BSD license. | ||
*/ | ||
#ifndef _BNER_ENCODER_H_ | ||
#define _BNER_ENCODER_H_ | ||
|
||
#include <asn_application.h> | ||
#include <bner_support.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
struct asn_TYPE_descriptor_s; /* Forward declaration */ | ||
struct asn_codec_ctx_s; /* Forward declaration */ | ||
|
||
/* | ||
* Type of the generic BNER encoder. | ||
*/ | ||
typedef asn_enc_rval_t(bner_type_encoder_f)( | ||
const struct asn_TYPE_descriptor_s *td, | ||
const void *struct_ptr, /* Structure to be encoded */ | ||
int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */ | ||
ber_tlv_tag_t tag, asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */ | ||
void *app_key /* Arbitrary callback argument */ | ||
); | ||
|
||
/* | ||
* The BNER encoder of any type. | ||
* This function may be invoked directly by the application. | ||
*/ | ||
asn_enc_rval_t bner_encode(const struct asn_TYPE_descriptor_s *td, | ||
const void *struct_ptr, /* Structure to be encoded */ | ||
asn_app_consume_bytes_f *consume_bytes_cb, | ||
void *app_key /* Arbitrary callback argument */ | ||
); | ||
|
||
/* A variant of bner_encode() which encodes data into a pre-allocated buffer */ | ||
asn_enc_rval_t bner_encode_to_buffer(const struct asn_TYPE_descriptor_s *td, | ||
const void *struct_ptr, void *buffer, | ||
size_t buffer_size); | ||
|
||
asn_enc_rval_t bner_fixed_encoder(const struct asn_TYPE_descriptor_s *td, | ||
const void *sptr, /* Struct to encode */ | ||
asn_app_consume_bytes_f *consume_bytes_cb, | ||
void *app_key /* Arbitrary callback arg */ | ||
); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* _BNER_ENCODER_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters