Skip to content

Commit ecf7c04

Browse files
committed
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.
1 parent 2f90a4f commit ecf7c04

File tree

6 files changed

+277
-0
lines changed

6 files changed

+277
-0
lines changed

skeletons/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ check_PROGRAMS = \
107107

108108
# BNER Support
109109
libasn1cskeletons_la_SOURCES += \
110+
bner_decoder.c bner_decoder.h \
111+
bner_encoder.c bner_encoder.h \
110112
bner_support.c bner_support.h \
111113
constr_CHOICE_bner.c \
112114
constr_SEQUENCE_bner.c \

skeletons/bner_decoder.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved.
3+
* Redistribution and modifications are permitted subject to BSD license.
4+
*/
5+
#include <asn_internal.h>
6+
#include <bner_decoder.h>
7+
#include <errno.h>
8+
9+
/*
10+
* The BNER decoder of any type.
11+
*/
12+
asn_dec_rval_t
13+
bner_decode(const asn_codec_ctx_t *opt_codec_ctx,
14+
const asn_TYPE_descriptor_t *td, void **struct_ptr, const void *ptr,
15+
size_t size) {
16+
asn_codec_ctx_t s_codec_ctx;
17+
18+
if(!td) {
19+
asn_dec_rval_t tmp_error = {RC_FAIL, 0};
20+
ASN_DEBUG("%s: Failed to decode. type_descriptor NULL", __func__);
21+
return tmp_error;
22+
}
23+
24+
/*
25+
* Stack checker requires that the codec context
26+
* must be allocated on the stack.
27+
*/
28+
if(opt_codec_ctx) {
29+
if(opt_codec_ctx->max_stack_size) {
30+
s_codec_ctx = *opt_codec_ctx;
31+
opt_codec_ctx = &s_codec_ctx;
32+
}
33+
} else {
34+
/* If context is not given, be security-conscious anyway */
35+
memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
36+
s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
37+
opt_codec_ctx = &s_codec_ctx;
38+
}
39+
40+
if(is_bner_fixed_pdu(td->name)) {
41+
return bner_fixed_decoder(opt_codec_ctx, td,
42+
struct_ptr, /* Pointer to the dest struct */
43+
ptr, size /* Buffer and its size */
44+
);
45+
}
46+
47+
/*
48+
* Invoke type-specific decoder.
49+
*/
50+
return td->op->bner_decoder(opt_codec_ctx, td,
51+
struct_ptr, /* Pointer to the dest struct */
52+
ptr, size, /* Buffer and its size */
53+
0 /* Default tag mode is 0 */
54+
);
55+
}
56+
57+
58+
__attribute__((weak)) asn_dec_rval_t
59+
bner_fixed_decoder(const struct asn_codec_ctx_s *opt_codec_ctx,
60+
const struct asn_TYPE_descriptor_s *td,
61+
void **struct_ptr, /* Ptr to a target struct's ptr */
62+
const void *buffer, /* Data to be decoded */
63+
size_t size /* Size of that buffer */
64+
) {
65+
(void)opt_codec_ctx;
66+
(void)td;
67+
(void)struct_ptr;
68+
(void)buffer;
69+
(void)size;
70+
71+
asn_dec_rval_t tmp_error = {RC_FAIL, 0};
72+
ASN_DEBUG("Failed to decode %s. No bner_fixed_decoder function provided",
73+
td->name);
74+
return tmp_error;
75+
}

skeletons/bner_decoder.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved.
3+
* Redistribution and modifications are permitted subject to BSD license.
4+
*/
5+
#ifndef _BNER_DECODER_H_
6+
#define _BNER_DECODER_H_
7+
8+
#include <asn_application.h>
9+
#include <bner_support.h>
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
struct asn_TYPE_descriptor_s; /* Forward declaration */
16+
struct asn_codec_ctx_s; /* Forward declaration */
17+
18+
/*
19+
* Type of generic function which decodes the byte stream into the structure.
20+
*/
21+
typedef asn_dec_rval_t(bner_type_decoder_f)(
22+
const struct asn_codec_ctx_s *opt_codec_ctx,
23+
const struct asn_TYPE_descriptor_s *td, void **struct_ptr,
24+
const void *buf_ptr, size_t size, int tag_mode);
25+
26+
/*
27+
* The BNER decoder of any type.
28+
* This function may be invoked directly from the application.
29+
*/
30+
asn_dec_rval_t bner_decode(const struct asn_codec_ctx_s *opt_codec_ctx,
31+
const struct asn_TYPE_descriptor_s *td,
32+
void **struct_ptr, /* Ptr to target's struct ptr */
33+
const void *buffer, /* Data to be decoded */
34+
size_t size /* Size of that buffer */
35+
);
36+
37+
asn_dec_rval_t bner_fixed_decoder(const struct asn_codec_ctx_s *opt_codec_ctx,
38+
const struct asn_TYPE_descriptor_s *td,
39+
void **struct_ptr, /* Ptr to target ptr */
40+
const void *buffer, /* Data to be decoded */
41+
size_t size /* Size of that buffer */
42+
);
43+
44+
#ifdef __cplusplus
45+
}
46+
#endif
47+
48+
#endif /* _BNER_DECODER_H_ */

skeletons/bner_encoder.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved.
3+
* Redistribution and modifications are permitted subject to BSD license.
4+
*/
5+
#include <asn_internal.h>
6+
#include <bner_encoder.h>
7+
#include <errno.h>
8+
9+
/*
10+
* The BNER encoder of any type.
11+
*/
12+
asn_enc_rval_t
13+
bner_encode(const asn_TYPE_descriptor_t *td, const void *sptr,
14+
asn_app_consume_bytes_f *consume_bytes, void *app_key) {
15+
if(!td) ASN__ENCODE_FAILED;
16+
17+
ASN_DEBUG("BNER encoder invoked for %s", td->name);
18+
19+
if(is_bner_fixed_pdu(td->name)) {
20+
return bner_fixed_encoder(td, sptr, consume_bytes, app_key);
21+
}
22+
23+
/*
24+
* Invoke type-specific encoder.
25+
*/
26+
return td->op->bner_encoder(td, sptr, 0, 0, consume_bytes, app_key);
27+
}
28+
29+
/*
30+
* Argument type and callback necessary for bner_encode_to_buffer().
31+
*/
32+
typedef struct enc_to_buf_arg {
33+
void *buffer;
34+
size_t left;
35+
} enc_to_buf_arg;
36+
37+
static int
38+
encode_to_buffer_cb(const void *buffer, size_t size, void *key) {
39+
enc_to_buf_arg *arg = (enc_to_buf_arg *)key;
40+
41+
if(arg->left < size) return -1; /* Data exceeds the available buffer size */
42+
43+
memcpy(arg->buffer, buffer, size);
44+
arg->buffer = ((char *)arg->buffer) + size;
45+
arg->left -= size;
46+
47+
return 0;
48+
}
49+
50+
/*
51+
* A variant of the bner_encode() which encodes the data into the provided
52+
* buffer
53+
*/
54+
asn_enc_rval_t
55+
bner_encode_to_buffer(const asn_TYPE_descriptor_t *td,
56+
const void *struct_ptr, void *buffer,
57+
size_t buffer_size) {
58+
enc_to_buf_arg arg;
59+
asn_enc_rval_t ec;
60+
61+
arg.buffer = buffer;
62+
arg.left = buffer_size;
63+
64+
if(is_bner_fixed_pdu(td->name)) {
65+
ec = bner_fixed_encoder(td, struct_ptr,
66+
encode_to_buffer_cb, &arg);
67+
} else {
68+
ec = td->op->bner_encoder(
69+
td,
70+
struct_ptr, /* Pointer to the destination structure */
71+
0, 0, encode_to_buffer_cb, &arg);
72+
}
73+
74+
if(ec.encoded != -1) {
75+
assert(ec.encoded == (ssize_t)(buffer_size - arg.left));
76+
/* Return the encoded contents size */
77+
}
78+
return ec;
79+
}
80+
81+
__attribute__((weak)) asn_enc_rval_t
82+
bner_fixed_encoder(const struct asn_TYPE_descriptor_s *td,
83+
const void *sptr, /* Structure to be encoded */
84+
asn_app_consume_bytes_f *consume_bytes_cb,
85+
void *app_key /* Arbitrary callback argument */
86+
) {
87+
(void)td;
88+
(void)sptr;
89+
(void)consume_bytes_cb;
90+
(void)app_key;
91+
92+
ASN_DEBUG("Failed to decode %s. No bner_fixed_encoder function provided",
93+
td->name);
94+
ASN__ENCODE_FAILED;
95+
}

skeletons/bner_encoder.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2017 Jon Ringle <[email protected]>. All rights reserved.
3+
* Redistribution and modifications are permitted subject to BSD license.
4+
*/
5+
#ifndef _BNER_ENCODER_H_
6+
#define _BNER_ENCODER_H_
7+
8+
#include <asn_application.h>
9+
#include <bner_support.h>
10+
11+
#ifdef __cplusplus
12+
extern "C" {
13+
#endif
14+
15+
struct asn_TYPE_descriptor_s; /* Forward declaration */
16+
struct asn_codec_ctx_s; /* Forward declaration */
17+
18+
/*
19+
* Type of the generic BNER encoder.
20+
*/
21+
typedef asn_enc_rval_t(bner_type_encoder_f)(
22+
const struct asn_TYPE_descriptor_s *td,
23+
const void *struct_ptr, /* Structure to be encoded */
24+
int tag_mode, /* {-1,0,1}: IMPLICIT, no, EXPLICIT */
25+
ber_tlv_tag_t tag, asn_app_consume_bytes_f *consume_bytes_cb, /* Callback */
26+
void *app_key /* Arbitrary callback argument */
27+
);
28+
29+
/*
30+
* The BNER encoder of any type.
31+
* This function may be invoked directly by the application.
32+
*/
33+
asn_enc_rval_t bner_encode(const struct asn_TYPE_descriptor_s *td,
34+
const void *struct_ptr, /* Structure to be encoded */
35+
asn_app_consume_bytes_f *consume_bytes_cb,
36+
void *app_key /* Arbitrary callback argument */
37+
);
38+
39+
/* A variant of bner_encode() which encodes data into a pre-allocated buffer */
40+
asn_enc_rval_t bner_encode_to_buffer(const struct asn_TYPE_descriptor_s *td,
41+
const void *struct_ptr, void *buffer,
42+
size_t buffer_size);
43+
44+
asn_enc_rval_t bner_fixed_encoder(const struct asn_TYPE_descriptor_s *td,
45+
const void *sptr, /* Struct to encode */
46+
asn_app_consume_bytes_f *consume_bytes_cb,
47+
void *app_key /* Arbitrary callback arg */
48+
);
49+
50+
#ifdef __cplusplus
51+
}
52+
#endif
53+
54+
#endif /* _BNER_ENCODER_H_ */

skeletons/constr_TYPE.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ typedef void asn_oer_constraints_t;
5252
#include <oer_encoder.h> /* Octet Encoding Rules encoder */
5353
#endif
5454

55+
#include <bner_decoder.h> /* BACnet Encoding Rules decoder */
56+
#include <bner_encoder.h> /* BACnet Encoding Rules encoder */
57+
5558
/*
5659
* Free the structure according to its specification.
5760
* Use one of ASN_STRUCT_{FREE,RESET,CONTENTS_ONLY} macros instead.

0 commit comments

Comments
 (0)