diff options
author | Lev Walkin <vlm@lionet.info> | 2005-11-26 11:25:14 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2005-11-26 11:25:14 +0000 |
commit | 59b176ee355b3e82e6a8649b164c187c7a17a28f (patch) | |
tree | 6d864f02cd16eb75f4ae6e40199d1879d8363152 /skeletons | |
parent | 708530582f5ba965fb596c3e189eec23c52337d9 (diff) |
upgrade: PER related changes
Diffstat (limited to 'skeletons')
64 files changed, 1268 insertions, 149 deletions
diff --git a/skeletons/ANY.c b/skeletons/ANY.c index 73702444..b1e35bf0 100644 --- a/skeletons/ANY.c +++ b/skeletons/ANY.c @@ -21,8 +21,10 @@ asn_TYPE_descriptor_t asn_DEF_ANY = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, ANY_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ 0, 0, 0, 0, + 0, /* No PER visible constraints */ 0, 0, /* No members */ &asn_DEF_ANY_specs, }; diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c index 8c83d689..900f41db 100644 --- a/skeletons/BIT_STRING.c +++ b/skeletons/BIT_STRING.c @@ -27,6 +27,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = { OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ OCTET_STRING_decode_xer_binary, BIT_STRING_encode_xer, + OCTET_STRING_decode_uper, /* Unaligned PER decoder */ 0, /* Use generic outmost tag fetcher */ asn_DEF_BIT_STRING_tags, sizeof(asn_DEF_BIT_STRING_tags) @@ -34,6 +35,7 @@ asn_TYPE_descriptor_t asn_DEF_BIT_STRING = { asn_DEF_BIT_STRING_tags, /* Same as above */ sizeof(asn_DEF_BIT_STRING_tags) / sizeof(asn_DEF_BIT_STRING_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ &asn_DEF_BIT_STRING_specs }; @@ -124,9 +126,7 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1); - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c index f3308bf7..10fd05e0 100644 --- a/skeletons/BMPString.c +++ b/skeletons/BMPString.c @@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = { OCTET_STRING_encode_der, BMPString_decode_xer, /* Convert from UTF-8 */ BMPString_encode_xer, /* Convert to UTF-8 */ + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_BMPString_tags, sizeof(asn_DEF_BMPString_tags) @@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = { asn_DEF_BMPString_tags, sizeof(asn_DEF_BMPString_tags) / sizeof(asn_DEF_BMPString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -156,7 +158,7 @@ BMPString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = BMPString__dump(st, cb, app_key); if(er.encoded < 0) _ASN_ENCODE_FAILED; - return er; + _ASN_ENCODED_OK(er); } int diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c index 360b6643..84e57858 100644 --- a/skeletons/BOOLEAN.c +++ b/skeletons/BOOLEAN.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -22,11 +22,13 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = { BOOLEAN_encode_der, BOOLEAN_decode_xer, BOOLEAN_encode_xer, + BOOLEAN_decode_uper, /* Unaligned PER decoder */ 0, /* Use generic outmost tag fetcher */ asn_DEF_BOOLEAN_tags, sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), asn_DEF_BOOLEAN_tags, /* Same as above */ sizeof(asn_DEF_BOOLEAN_tags) / sizeof(asn_DEF_BOOLEAN_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -126,7 +128,7 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr, erval.encoded += 1; - return erval; + _ASN_ENCODED_OK(erval); } @@ -196,7 +198,7 @@ BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = 8; } - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } @@ -234,3 +236,33 @@ BOOLEAN_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) { } } +asn_dec_rval_t +BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; + BOOLEAN_t *st = (BOOLEAN_t *)*sptr; + + (void)opt_codec_ctx; + (void)constraints; + + if(!st) { + st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st))); + if(!st) _ASN_DECODE_FAILED; + } + + /* + * Extract a single bit + */ + switch(per_get_few_bits(pd, 1)) { + case 1: *st = 1; break; + case 0: *st = 0; break; + case -1: default: _ASN_DECODE_FAILED; + } + + ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE"); + + rv.code = RC_OK; + rv.consumed = 1; + return rv; +} + diff --git a/skeletons/BOOLEAN.h b/skeletons/BOOLEAN.h index ec4dbac8..1cf19803 100644 --- a/skeletons/BOOLEAN.h +++ b/skeletons/BOOLEAN.h @@ -26,6 +26,7 @@ ber_type_decoder_f BOOLEAN_decode_ber; der_type_encoder_f BOOLEAN_encode_der; xer_type_decoder_f BOOLEAN_decode_xer; xer_type_encoder_f BOOLEAN_encode_xer; +per_type_decoder_f BOOLEAN_decode_uper; #ifdef __cplusplus } diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c index 12d4f6eb..c51f9265 100644 --- a/skeletons/ENUMERATED.c +++ b/skeletons/ENUMERATED.c @@ -1,9 +1,10 @@ /*- - * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> #include <ENUMERATED.h> +#include <NativeEnumerated.h> #include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */ /* @@ -22,12 +23,33 @@ asn_TYPE_descriptor_t asn_DEF_ENUMERATED = { INTEGER_encode_der, /* Implemented in terms of INTEGER */ INTEGER_decode_xer, /* This is temporary! */ INTEGER_encode_xer, + ENUMERATED_decode_uper, /* Unaligned PER decoder */ 0, /* Use generic outmost tag fetcher */ asn_DEF_ENUMERATED_tags, sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]), asn_DEF_ENUMERATED_tags, /* Same as above */ sizeof(asn_DEF_ENUMERATED_tags) / sizeof(asn_DEF_ENUMERATED_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; +asn_dec_rval_t +ENUMERATED_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rval; + ENUMERATED_t *st = (ENUMERATED_t *)*sptr; + long value, *vptr = &value; + + if(!st) { + st = (ENUMERATED_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(!st) _ASN_DECODE_FAILED; + } + + rval = NativeEnumerated_decode_uper(opt_codec_ctx, td, constraints, + (void **)&vptr, pd); + if(rval.code == RC_OK) + if(asn_long2INTEGER(st, value)) + rval.code = RC_FAIL; + return rval; +} diff --git a/skeletons/ENUMERATED.h b/skeletons/ENUMERATED.h index 53cc273e..e65a15af 100644 --- a/skeletons/ENUMERATED.h +++ b/skeletons/ENUMERATED.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _ENUMERATED_H_ @@ -15,6 +15,8 @@ typedef INTEGER_t ENUMERATED_t; /* Implemented via INTEGER */ extern asn_TYPE_descriptor_t asn_DEF_ENUMERATED; +per_type_decoder_f ENUMERATED_decode_uper; + #ifdef __cplusplus } #endif diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c index e4ea6f8a..c1a8823e 100644 --- a/skeletons/GeneralString.c +++ b/skeletons/GeneralString.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_GeneralString_tags, sizeof(asn_DEF_GeneralString_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralString = { asn_DEF_GeneralString_tags, sizeof(asn_DEF_GeneralString_tags) / sizeof(asn_DEF_GeneralString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c index 9103455d..aabe66d6 100644 --- a/skeletons/GeneralizedTime.c +++ b/skeletons/GeneralizedTime.c @@ -128,6 +128,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = { GeneralizedTime_encode_der, OCTET_STRING_decode_xer_utf8, GeneralizedTime_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_GeneralizedTime_tags, sizeof(asn_DEF_GeneralizedTime_tags) @@ -135,6 +136,7 @@ asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = { asn_DEF_GeneralizedTime_tags, sizeof(asn_DEF_GeneralizedTime_tags) / sizeof(asn_DEF_GeneralizedTime_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c index c5d4a30b..0c3ad47c 100644 --- a/skeletons/GraphicString.c +++ b/skeletons/GraphicString.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, /* Can't expect it to be ASCII/UTF8 */ + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_GraphicString_tags, sizeof(asn_DEF_GraphicString_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_GraphicString = { asn_DEF_GraphicString_tags, sizeof(asn_DEF_GraphicString_tags) / sizeof(asn_DEF_GraphicString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c index c4da875a..a4d7ff84 100644 --- a/skeletons/IA5String.c +++ b/skeletons/IA5String.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_IA5String_tags, sizeof(asn_DEF_IA5String_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_IA5String = { asn_DEF_IA5String_tags, sizeof(asn_DEF_IA5String_tags) / sizeof(asn_DEF_IA5String_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c index d2a66b5d..dbb14859 100644 --- a/skeletons/INTEGER.c +++ b/skeletons/INTEGER.c @@ -24,11 +24,13 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = { INTEGER_encode_der, INTEGER_decode_xer, INTEGER_encode_xer, + INTEGER_decode_uper, /* Unaligned PER decoder */ 0, /* Use generic outmost tag fetcher */ asn_DEF_INTEGER_tags, sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), asn_DEF_INTEGER_tags, /* Same as above */ sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -430,9 +432,102 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = INTEGER__dump(td, st, cb, app_key, 1); if(er.encoded < 0) _ASN_ENCODE_FAILED; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); +} + +asn_dec_rval_t +INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rval = { RC_OK, 0 }; + INTEGER_t *st = (INTEGER_t *)*sptr; + asn_per_constraint_t *ct; + int repeat; + + (void)opt_codec_ctx; + + if(!st) { + st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st))); + if(!st) _ASN_DECODE_FAILED; + } + + if(!constraints) constraints = td->per_constraints; + ct = constraints ? &constraints->value : 0; + + if(ct && ct->flags & APC_EXTENSIBLE) { + int inext = per_get_few_bits(pd, 1); + if(inext < 0) _ASN_DECODE_FAILED; + if(inext) ct = 0; + } + + FREEMEM(st->buf); + if(ct) { + if(ct->flags & APC_SEMI_CONSTRAINED) { + st->buf = (uint8_t *)CALLOC(1, 2); + if(!st->buf) _ASN_DECODE_FAILED; + st->size = 1; + } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) { + size_t size = (ct->range_bits + 7) >> 3; + st->buf = (uint8_t *)MALLOC(1 + size + 1); + if(!st->buf) _ASN_DECODE_FAILED; + st->size = size; + } else { + st->size = 0; + } + } else { + st->size = 0; + } + + /* X.691, #12.2.2 */ + if(ct && ct->flags != APC_UNCONSTRAINED) { + /* #10.5.6 */ + ASN_DEBUG("Integer with range %d bits", ct->range_bits); + if(ct->range_bits >= 0) { + long value = per_get_few_bits(pd, ct->range_bits); + if(value < 0) _ASN_DECODE_FAILED; + ASN_DEBUG("Got value %ld + low %ld", + value, ct->lower_bound); + value += ct->lower_bound; + if(asn_long2INTEGER(st, value)) + _ASN_DECODE_FAILED; + return rval; + } + } else { + ASN_DEBUG("Decoding unconstrained integer %s", td->name); + } + + /* X.691, #12.2.3, #12.2.4 */ + do { + ssize_t len; + void *p; + int ret; + + /* Get the PER length */ + len = uper_get_length(pd, -1, &repeat); + if(len < 0) _ASN_DECODE_FAILED; + + p = REALLOC(st->buf, st->size + len + 1); + if(!p) _ASN_DECODE_FAILED; + st->buf = (uint8_t *)p; + + ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len); + if(ret < 0) _ASN_DECODE_FAILED; + st->size += len; + } while(repeat); + st->buf[st->size] = 0; /* JIC */ + + /* #12.2.3 */ + if(ct && ct->lower_bound) { + /* + * TODO: replace by in-place arithmetics. + */ + long value; + if(asn_INTEGER2long(st, &value)) + _ASN_DECODE_FAILED; + if(asn_long2INTEGER(st, value + ct->lower_bound)) + _ASN_DECODE_FAILED; + } + + return rval; } int diff --git a/skeletons/INTEGER.h b/skeletons/INTEGER.h index 165c055f..410fbe90 100644 --- a/skeletons/INTEGER.h +++ b/skeletons/INTEGER.h @@ -28,7 +28,7 @@ typedef struct asn_INTEGER_specifics_s { asn_INTEGER_enum_map_t *value2enum; /* N -> "tag"; sorted by N */ unsigned int *enum2value; /* "tag" => N; sorted by tag */ int map_count; /* Elements in either map */ - int extensible; /* This map is extensible */ + int extension; /* This map is extensible */ int strict_enumeration; /* Enumeration set is fixed */ } asn_INTEGER_specifics_t; @@ -37,6 +37,7 @@ ber_type_decoder_f INTEGER_decode_ber; der_type_encoder_f INTEGER_encode_der; xer_type_decoder_f INTEGER_decode_xer; xer_type_encoder_f INTEGER_encode_xer; +per_type_decoder_f INTEGER_decode_uper; /*********************************** * Some handy conversion routines. * diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c index 035734b5..829af328 100644 --- a/skeletons/ISO646String.c +++ b/skeletons/ISO646String.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_ISO646String_tags, sizeof(asn_DEF_ISO646String_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_ISO646String = { asn_DEF_ISO646String_tags, sizeof(asn_DEF_ISO646String_tags) / sizeof(asn_DEF_ISO646String_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/NULL.c b/skeletons/NULL.c index 5b0351e3..504be954 100644 --- a/skeletons/NULL.c +++ b/skeletons/NULL.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -23,11 +23,13 @@ asn_TYPE_descriptor_t asn_DEF_NULL = { NULL_encode_der, /* Special handling of DER encoding */ NULL_decode_xer, NULL_encode_xer, + NULL_decode_uper, /* Unaligned PER decoder */ 0, /* Use generic outmost tag fetcher */ asn_DEF_NULL_tags, sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), asn_DEF_NULL_tags, /* Same as above */ sizeof(asn_DEF_NULL_tags) / sizeof(asn_DEF_NULL_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -44,7 +46,7 @@ NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr, erval.structure_ptr = ptr; } - return erval; + _ASN_ENCODED_OK(erval); } asn_enc_rval_t @@ -62,8 +64,7 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, /* XMLNullValue is empty */ er.encoded = 0; - - return er; + _ASN_ENCODED_OK(er); } @@ -101,3 +102,31 @@ NULL_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, return (cb("<absent>", 8, app_key) < 0) ? -1 : 0; } } + +asn_dec_rval_t +NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; + + (void)opt_codec_ctx; + (void)td; + (void)constraints; + (void)pd; + + if(!*sptr) { + *sptr = MALLOC(sizeof(NULL_t)); + if(*sptr) { + *(NULL_t *)*sptr = 0; + } else { + _ASN_DECODE_FAILED; + } + } + + /* + * NULL type does not have content octets. + */ + + rv.code = RC_OK; + rv.consumed = 0; + return rv; +} diff --git a/skeletons/NULL.h b/skeletons/NULL.h index 28a3630e..7126e1df 100644 --- a/skeletons/NULL.h +++ b/skeletons/NULL.h @@ -23,6 +23,7 @@ asn_struct_print_f NULL_print; der_type_encoder_f NULL_encode_der; xer_type_decoder_f NULL_decode_xer; xer_type_encoder_f NULL_encode_xer; +per_type_decoder_f NULL_decode_uper; #ifdef __cplusplus } diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c index fb77e06d..e130749f 100644 --- a/skeletons/NativeEnumerated.c +++ b/skeletons/NativeEnumerated.c @@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = { NativeInteger_encode_der, NativeInteger_decode_xer, NativeEnumerated_encode_xer, + NativeEnumerated_decode_uper, 0, /* Use generic outmost tag fetcher */ asn_DEF_NativeEnumerated_tags, sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), asn_DEF_NativeEnumerated_tags, /* Same as above */ sizeof(asn_DEF_NativeEnumerated_tags) / sizeof(asn_DEF_NativeEnumerated_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -59,13 +61,65 @@ NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name); assert(er.encoded > 0 && (size_t)er.encoded < srcsize); if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED; - return er; + _ASN_ENCODED_OK(er); } else { ASN_DEBUG("ASN.1 forbids dealing with " "unknown value of ENUMERATED type"); _ASN_ENCODE_FAILED; } +} + +asn_dec_rval_t +NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics; + asn_dec_rval_t rval = { RC_OK, 0 }; + long *native = (long *)*sptr; + asn_per_constraint_t *ct; + long value; + + (void)opt_codec_ctx; + + if(constraints) ct = &constraints->value; + else if(td->per_constraints) ct = &td->per_constraints->value; + else _ASN_DECODE_FAILED; /* Mandatory! */ + if(!specs) _ASN_DECODE_FAILED; + + if(!native) { + native = (long *)(*sptr = CALLOC(1, sizeof(*native))); + if(!native) _ASN_DECODE_FAILED; + } + + ASN_DEBUG("Decoding %s as NativeEnumerated", td->name); + + if(ct->flags & APC_EXTENSIBLE) { + int inext = per_get_few_bits(pd, 1); + if(inext < 0) _ASN_DECODE_FAILED; + if(inext) ct = 0; + } + + if(ct && ct->range_bits >= 0) { + value = per_get_few_bits(pd, ct->range_bits); + if(value < 0) _ASN_DECODE_FAILED; + if(value >= (specs->extension + ? specs->extension - 1 : specs->map_count)) + _ASN_DECODE_FAILED; + } else { + if(!specs->extension) + _ASN_DECODE_FAILED; + /* + * X.691, #10.6: normally small non-negative whole number; + */ + value = uper_get_nsnnwn(pd); + if(value < 0) _ASN_DECODE_FAILED; + value += specs->extension - 1; + if(value >= specs->map_count) + _ASN_DECODE_FAILED; + } + + *native = specs->value2enum[value].nat_value; + ASN_DEBUG("Decoded %s = %ld", td->name, *native); - return er; + return rval; } diff --git a/skeletons/NativeEnumerated.h b/skeletons/NativeEnumerated.h index 7e2bb1b9..5792beed 100644 --- a/skeletons/NativeEnumerated.h +++ b/skeletons/NativeEnumerated.h @@ -21,6 +21,7 @@ extern "C" { extern asn_TYPE_descriptor_t asn_DEF_NativeEnumerated; xer_type_encoder_f NativeEnumerated_encode_xer; +per_type_decoder_f NativeEnumerated_decode_uper; #ifdef __cplusplus } diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c index 96c78756..2e44eaa6 100644 --- a/skeletons/NativeInteger.c +++ b/skeletons/NativeInteger.c @@ -28,11 +28,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = { NativeInteger_encode_der, NativeInteger_decode_xer, NativeInteger_encode_xer, + NativeInteger_decode_uper, /* Unaligned PER decoder */ 0, /* Use generic outmost tag fetcher */ asn_DEF_NativeInteger_tags, sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), asn_DEF_NativeInteger_tags, /* Same as above */ sizeof(asn_DEF_NativeInteger_tags) / sizeof(asn_DEF_NativeInteger_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -108,18 +110,6 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx, } *native = l; - - /* - * Note that native integer size might be other than long. - * This expression hopefully will be optimized away - * by compiler. - */ - if(sizeof(*native) != sizeof(long) && ((long)*native != l)) { - *native = 0; /* Safe value */ - rval.code = RC_FAIL; - rval.consumed = 0; - return rval; - } } rval.code = RC_OK; @@ -176,38 +166,25 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname, const void *buf_ptr, size_t size) { asn_dec_rval_t rval; - INTEGER_t *st = 0; + INTEGER_t st; void *st_ptr = (void *)&st; long *native = (long *)*sptr; if(!native) { - *sptr = CALLOC(1, sizeof(int)); - native = (long *)*sptr; - if(!native) { - rval.code = RC_FAIL; - rval.consumed = 0; - return rval; - } + native = (long *)(*sptr = CALLOC(1, sizeof(*native))); + if(!native) _ASN_DECODE_FAILED; } - rval = INTEGER_decode_xer(opt_codec_ctx, td, (void **)st_ptr, + memset(&st, 0, sizeof(st)); + rval = INTEGER_decode_xer(opt_codec_ctx, td, &st_ptr, opt_mname, buf_ptr, size); if(rval.code == RC_OK) { long l; - if(asn_INTEGER2long(st, &l)) { + if(asn_INTEGER2long(&st, &l)) { rval.code = RC_FAIL; rval.consumed = 0; } else { *native = l; - - /* Native type might be shorter than long */ - if(sizeof(*native) != sizeof(long) - && ((long)*native != l)) { - *native = 0; /* Safe value */ - rval.code = RC_FAIL; - rval.consumed = 0; - return rval; - } } } else { /* @@ -217,7 +194,7 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx, */ rval.consumed = 0; } - asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, st, 0); + asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, &st, 1); return rval; } @@ -240,7 +217,39 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, || cb(scratch, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED; - return er; + _ASN_ENCODED_OK(er); +} + +asn_dec_rval_t +NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + + asn_dec_rval_t rval; + long *native = (long *)*sptr; + INTEGER_t tmpint; + void *tmpintptr = &tmpint; + + (void)opt_codec_ctx; + ASN_DEBUG("Decoding NativeInteger %s (UPER)", td->name); + + if(!native) { + native = (long *)(*sptr = CALLOC(1, sizeof(*native))); + if(!native) _ASN_DECODE_FAILED; + } + + memset(&tmpint, 0, sizeof tmpint); + rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints, + &tmpintptr, pd); + if(rval.code == RC_OK) + if(asn_INTEGER2long(&tmpint, native)) + rval.code = RC_FAIL; + else + ASN_DEBUG("NativeInteger %s got value %ld", + td->name, *native); + asn_DEF_INTEGER.free_struct(&asn_DEF_INTEGER, &tmpint, 1); + + return rval; } /* diff --git a/skeletons/NativeInteger.h b/skeletons/NativeInteger.h index f38fd477..e2ce22e9 100644 --- a/skeletons/NativeInteger.h +++ b/skeletons/NativeInteger.h @@ -27,6 +27,7 @@ ber_type_decoder_f NativeInteger_decode_ber; der_type_encoder_f NativeInteger_encode_der; xer_type_decoder_f NativeInteger_decode_xer; xer_type_encoder_f NativeInteger_encode_xer; +per_type_decoder_f NativeInteger_decode_uper; #ifdef __cplusplus } diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c index f7755db1..9b303681 100644 --- a/skeletons/NativeReal.c +++ b/skeletons/NativeReal.c @@ -29,11 +29,13 @@ asn_TYPE_descriptor_t asn_DEF_NativeReal = { NativeReal_encode_der, NativeReal_decode_xer, NativeReal_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_NativeReal_tags, sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), asn_DEF_NativeReal_tags, /* Same as above */ sizeof(asn_DEF_NativeReal_tags) / sizeof(asn_DEF_NativeReal_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -206,7 +208,7 @@ NativeReal_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = REAL__dump(*Dbl, flags & XER_F_CANONICAL, cb, app_key); if(er.encoded < 0) _ASN_ENCODE_FAILED; - return er; + _ASN_ENCODED_OK(er); } /* diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c index 39404c25..e3302c6a 100644 --- a/skeletons/NumericString.c +++ b/skeletons/NumericString.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_NumericString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_NumericString_tags, sizeof(asn_DEF_NumericString_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_NumericString = { asn_DEF_NumericString_tags, sizeof(asn_DEF_NumericString_tags) / sizeof(asn_DEF_NumericString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c index e815d480..0c45e4d9 100644 --- a/skeletons/OBJECT_IDENTIFIER.c +++ b/skeletons/OBJECT_IDENTIFIER.c @@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = { der_encode_primitive, OBJECT_IDENTIFIER_decode_xer, OBJECT_IDENTIFIER_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_OBJECT_IDENTIFIER_tags, sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) @@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = { asn_DEF_OBJECT_IDENTIFIER_tags, /* Same as above */ sizeof(asn_DEF_OBJECT_IDENTIFIER_tags) / sizeof(asn_DEF_OBJECT_IDENTIFIER_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -332,9 +334,7 @@ OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key); if(er.encoded < 0) _ASN_ENCODE_FAILED; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); } int diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c index 447b2425..fe29f83f 100644 --- a/skeletons/OCTET_STRING.c +++ b/skeletons/OCTET_STRING.c @@ -19,6 +19,9 @@ static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = { offsetof(OCTET_STRING_t, _asn_ctx), 0 }; +static asn_per_constraint_t asn_DEF_OCTET_STRING_constraint = { + APC_SEMI_CONSTRAINED, -1, 0, 0, 0 +}; asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { "OCTET STRING", /* Canonical name */ "OCTET_STRING", /* XML tag name */ @@ -29,6 +32,7 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, + OCTET_STRING_decode_uper, /* Unaligned PER decoder */ 0, /* Use generic outmost tag fetcher */ asn_DEF_OCTET_STRING_tags, sizeof(asn_DEF_OCTET_STRING_tags) @@ -36,6 +40,7 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { asn_DEF_OCTET_STRING_tags, /* Same as above */ sizeof(asn_DEF_OCTET_STRING_tags) / sizeof(asn_DEF_OCTET_STRING_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ &asn_DEF_OCTET_STRING_specs }; @@ -61,9 +66,10 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = { #undef RETURN #define RETURN(_code) do { \ - rval.code = _code; \ - rval.consumed = consumed_myself; \ - return rval; \ + asn_dec_rval_t tmprval; \ + tmprval.code = _code; \ + tmprval.consumed = consumed_myself; \ + return tmprval; \ } while(0) #undef APPEND @@ -167,11 +173,11 @@ _new_stack() { asn_dec_rval_t OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, - void **os_structure, const void *buf_ptr, size_t size, int tag_mode) { + void **sptr, const void *buf_ptr, size_t size, int tag_mode) { asn_OCTET_STRING_specifics_t *specs = td->specifics ? (asn_OCTET_STRING_specifics_t *)td->specifics : &asn_DEF_OCTET_STRING_specs; - BIT_STRING_t *st = (BIT_STRING_t *)*os_structure; + BIT_STRING_t *st = (BIT_STRING_t *)*sptr; asn_dec_rval_t rval; asn_struct_ctx_t *ctx; ssize_t consumed_myself = 0; @@ -190,10 +196,8 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx, * Create the string if does not exist. */ if(st == NULL) { - *os_structure = CALLOC(1, specs->struct_size); - st = (BIT_STRING_t *)*os_structure; - if(st == NULL) - RETURN(RC_FAIL); + st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(st == NULL) RETURN(RC_FAIL); } /* Restore parsing context */ @@ -549,9 +553,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, if(!cb) { er.encoded += (type_variant == _TT_BIT_STRING) + st->size; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); } /* @@ -574,9 +576,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr, } er.encoded += st->size; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } @@ -639,9 +639,7 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, } } - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } @@ -781,9 +779,7 @@ OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr, _ASN_ENCODE_FAILED; er.encoded = encoded_len; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); } /* @@ -1200,6 +1196,99 @@ OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx, OCTET_STRING__convert_entrefs); } +asn_dec_rval_t +OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx, + asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, + void **sptr, asn_per_data_t *pd) { + + asn_OCTET_STRING_specifics_t *specs = td->specifics + ? (asn_OCTET_STRING_specifics_t *)td->specifics + : &asn_DEF_OCTET_STRING_specs; + asn_per_constraint_t *ct = constraints ? &constraints->size + : (td->per_constraints + ? &td->per_constraints->size + : &asn_DEF_OCTET_STRING_constraint); + asn_dec_rval_t rval = { RC_OK, 0 }; + BIT_STRING_t *st = (BIT_STRING_t *)*sptr; + ssize_t consumed_myself = 0; + int repeat; + int unit_bits = (specs->subvariant != 1) * 7 + 1; + + (void)opt_codec_ctx; + + /* + * Allocate the string. + */ + if(!st) { + st = (BIT_STRING_t *)(*sptr = CALLOC(1, specs->struct_size)); + if(!st) RETURN(RC_FAIL); + } + + if(ct->flags & APC_EXTENSIBLE) { + int inext = per_get_few_bits(pd, 1); + if(inext < 0) RETURN(RC_FAIL); + if(inext) ct = &asn_DEF_OCTET_STRING_constraint; + consumed_myself = 0; + } + + if(ct->effective_bits >= 0 + && (!st->buf || st->size < ct->upper_bound)) { + FREEMEM(st->buf); + if(unit_bits == 1) { + st->size = (ct->upper_bound + 7) >> 3; + } else { + st->size = ct->upper_bound; + } + st->buf = (uint8_t *)MALLOC(st->size + 1); + if(!st->buf) { st->size = 0; RETURN(RC_FAIL); } + } + + /* X.691, #16.5: zero-length encoding */ + /* X.691, #16.6: short fixed length encoding (up to 2 octets) */ + /* X.691, #16.7: long fixed length encoding (up to 64K octets) */ + if(ct->effective_bits == 0) { + int ret = per_get_many_bits(pd, st->buf, 0, + unit_bits * ct->upper_bound); + if(ret < 0) RETURN(RC_FAIL); + consumed_myself += unit_bits * ct->upper_bound; + st->buf[st->size] = 0; + if(unit_bits == 1 && (ct->upper_bound & 0x7)) + st->bits_unused = 8 - (ct->upper_bound & 0x7); + RETURN(RC_OK); + } + + st->size = 0; + do { + ssize_t len_bytes; + ssize_t len_bits; + void *p; + int ret; + + /* Get the PER length */ + len_bits = uper_get_length(pd, ct->effective_bits, &repeat); + if(len_bits < 0) RETURN(RC_FAIL); + + if(unit_bits == 1) { + len_bytes = (len_bits + 7) >> 3; + if(len_bits & 0x7) + st->bits_unused = 8 - (len_bits & 0x7); + /* len_bits be multiple of 16K if repeat is set */ + } else { + len_bytes = len_bits; + len_bits = len_bytes << 3; + } + p = REALLOC(st->buf, st->size + len_bytes + 1); + if(!p) RETURN(RC_FAIL); + st->buf = (uint8_t *)p; + + ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits); + if(ret < 0) RETURN(RC_FAIL); + st->size += len_bytes; + } while(repeat); + st->buf[st->size] = 0; /* nul-terminate */ + + return rval; +} int OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h index 94c19a0b..22bd6272 100644 --- a/skeletons/OCTET_STRING.h +++ b/skeletons/OCTET_STRING.h @@ -30,6 +30,7 @@ xer_type_decoder_f OCTET_STRING_decode_xer_binary; /* 01010111010 */ xer_type_decoder_f OCTET_STRING_decode_xer_utf8; /* ASCII/UTF-8 */ xer_type_encoder_f OCTET_STRING_encode_xer; xer_type_encoder_f OCTET_STRING_encode_xer_utf8; +per_type_decoder_f OCTET_STRING_decode_uper; /****************************** * Handy conversion routines. * diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c index 9f52147e..37f51e8c 100644 --- a/skeletons/ObjectDescriptor.c +++ b/skeletons/ObjectDescriptor.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_ObjectDescriptor_tags, sizeof(asn_DEF_ObjectDescriptor_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = { asn_DEF_ObjectDescriptor_tags, sizeof(asn_DEF_ObjectDescriptor_tags) / sizeof(asn_DEF_ObjectDescriptor_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c index bc48c0f8..57f65731 100644 --- a/skeletons/PrintableString.c +++ b/skeletons/PrintableString.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_PrintableString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_PrintableString_tags, sizeof(asn_DEF_PrintableString_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_PrintableString = { asn_DEF_PrintableString_tags, sizeof(asn_DEF_PrintableString_tags) / sizeof(asn_DEF_PrintableString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/README b/skeletons/README index 29dbae63..92201ed9 100644 --- a/skeletons/README +++ b/skeletons/README @@ -1,6 +1,4 @@ - -Here are the canonical encoder/decoder algorithms that work with the tables -constructed by the compiler. The compiler itself does not generate code, -it just creates those tables and then copies (links) over these files -which contain generic algorithms. - +This directory contains encoder/decoder code for various encoding rules +(PER, DER, BER, XER) that work with the tables constructed by the compiler. +The compiler itself does not generate much code. It creates parsing tables +and then copies (links) over these files which contain generic codecs. diff --git a/skeletons/REAL.c b/skeletons/REAL.c index c4801538..689b05ec 100644 --- a/skeletons/REAL.c +++ b/skeletons/REAL.c @@ -42,11 +42,13 @@ asn_TYPE_descriptor_t asn_DEF_REAL = { der_encode_primitive, REAL_decode_xer, REAL_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_REAL_tags, sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), asn_DEF_REAL_tags, /* Same as above */ sizeof(asn_DEF_REAL_tags) / sizeof(asn_DEF_REAL_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -257,9 +259,7 @@ REAL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = REAL__dump(d, flags & XER_F_CANONICAL, cb, app_key); if(er.encoded < 0) _ASN_ENCODE_FAILED; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); } diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c index 2b32315e..74511b7b 100644 --- a/skeletons/RELATIVE-OID.c +++ b/skeletons/RELATIVE-OID.c @@ -25,6 +25,7 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = { der_encode_primitive, RELATIVE_OID_decode_xer, RELATIVE_OID_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_RELATIVE_OID_tags, sizeof(asn_DEF_RELATIVE_OID_tags) @@ -32,6 +33,7 @@ asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = { asn_DEF_RELATIVE_OID_tags, /* Same as above */ sizeof(asn_DEF_RELATIVE_OID_tags) / sizeof(asn_DEF_RELATIVE_OID_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -156,9 +158,7 @@ RELATIVE_OID_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = RELATIVE_OID__dump_body(st, cb, app_key); if(er.encoded < 0) _ASN_ENCODE_FAILED; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); } int diff --git a/skeletons/T61String.c b/skeletons/T61String.c index a37c176e..4157a6b2 100644 --- a/skeletons/T61String.c +++ b/skeletons/T61String.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_T61String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_T61String_tags, sizeof(asn_DEF_T61String_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_T61String = { asn_DEF_T61String_tags, sizeof(asn_DEF_T61String_tags) / sizeof(asn_DEF_T61String_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c index 47aad419..11f57033 100644 --- a/skeletons/TeletexString.c +++ b/skeletons/TeletexString.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_TeletexString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_TeletexString_tags, sizeof(asn_DEF_TeletexString_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_TeletexString = { asn_DEF_TeletexString_tags, sizeof(asn_DEF_TeletexString_tags) / sizeof(asn_DEF_TeletexString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c index c2079fbd..9032dbd6 100644 --- a/skeletons/UTCTime.c +++ b/skeletons/UTCTime.c @@ -28,6 +28,7 @@ asn_TYPE_descriptor_t asn_DEF_UTCTime = { OCTET_STRING_encode_der, /* Implemented in terms of OCTET STRING */ OCTET_STRING_decode_xer_utf8, UTCTime_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_UTCTime_tags, sizeof(asn_DEF_UTCTime_tags) @@ -35,6 +36,7 @@ asn_TYPE_descriptor_t asn_DEF_UTCTime = { asn_DEF_UTCTime_tags, sizeof(asn_DEF_UTCTime_tags) / sizeof(asn_DEF_UTCTime_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c index 64b3a712..5d0334f9 100644 --- a/skeletons/UTF8String.c +++ b/skeletons/UTF8String.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_UTF8String = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_UTF8String_tags, sizeof(asn_DEF_UTF8String_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_UTF8String = { asn_DEF_UTF8String_tags, sizeof(asn_DEF_UTF8String_tags) / sizeof(asn_DEF_UTF8String_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c index 938bf07b..0fab915f 100644 --- a/skeletons/UniversalString.c +++ b/skeletons/UniversalString.c @@ -23,6 +23,7 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = { OCTET_STRING_encode_der, UniversalString_decode_xer, /* Convert from UTF-8 */ UniversalString_encode_xer, /* Convert into UTF-8 */ + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_UniversalString_tags, sizeof(asn_DEF_UniversalString_tags) @@ -30,6 +31,7 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = { asn_DEF_UniversalString_tags, sizeof(asn_DEF_UniversalString_tags) / sizeof(asn_DEF_UniversalString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; @@ -167,7 +169,7 @@ UniversalString_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = UniversalString__dump(st, cb, app_key); if(er.encoded < 0) _ASN_ENCODE_FAILED; - return er; + _ASN_ENCODED_OK(er); } int diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c index 2a2baa81..c51c31aa 100644 --- a/skeletons/VideotexString.c +++ b/skeletons/VideotexString.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_VideotexString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_hex, OCTET_STRING_encode_xer, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_VideotexString_tags, sizeof(asn_DEF_VideotexString_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_VideotexString = { asn_DEF_VideotexString_tags, sizeof(asn_DEF_VideotexString_tags) / sizeof(asn_DEF_VideotexString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c index 30f29455..2a88169d 100644 --- a/skeletons/VisibleString.c +++ b/skeletons/VisibleString.c @@ -22,6 +22,7 @@ asn_TYPE_descriptor_t asn_DEF_VisibleString = { OCTET_STRING_encode_der, OCTET_STRING_decode_xer_utf8, OCTET_STRING_encode_xer_utf8, + 0, 0, /* Use generic outmost tag fetcher */ asn_DEF_VisibleString_tags, sizeof(asn_DEF_VisibleString_tags) @@ -29,6 +30,7 @@ asn_TYPE_descriptor_t asn_DEF_VisibleString = { asn_DEF_VisibleString_tags, sizeof(asn_DEF_VisibleString_tags) / sizeof(asn_DEF_VisibleString_tags[0]), + 0, /* No PER visible constraints */ 0, 0, /* No members */ 0 /* No specifics */ }; diff --git a/skeletons/asn-decoder-template.c b/skeletons/asn-decoder-template.c index 348c3731..c50d8b9c 100644 --- a/skeletons/asn-decoder-template.c +++ b/skeletons/asn-decoder-template.c @@ -21,7 +21,9 @@ #include <asn_application.h> extern asn_TYPE_descriptor_t asn_DEF; /* ASN.1 type to be decoded */ -static asn_TYPE_descriptor_t *pduType = &asn_DEF; +#ifdef ASN_PDU_COLLECTION /* Generated by asn1c: -pdu=... */ +extern asn_TYPE_descriptor_t *asn_pdu_collection[]; +#endif /* * Open file and parse its contens. @@ -37,7 +39,8 @@ static int opt_stack; /* -s */ /* Input data format selector */ static enum input_format { INP_BER, /* -iber: BER input */ - INP_XER /* -ixer: XER input */ + INP_XER, /* -ixer: XER input */ + INP_PER /* -iper: Unaligned PER input */ } iform; /* -i<format> */ /* Output data format selector */ @@ -56,19 +59,26 @@ static enum output_format { int main(int ac, char **av) { + static asn_TYPE_descriptor_t *pduType = &asn_DEF; ssize_t suggested_bufsize = 8192; /* close or equal to stdio buffer */ int number_of_iterations = 1; int num; int ch; + /* Figure out if Unaligned PER needs to be default */ + if(pduType->uper_decoder) + iform = INP_PER; + /* * Pocess the command-line argments. */ - while((ch = getopt(ac, av, "i:o:b:cdn:hs:")) != -1) + while((ch = getopt(ac, av, "i:o:b:cdn:p:hs:")) != -1) switch(ch) { case 'i': if(optarg[0] == 'b') { iform = INP_BER; break; } if(optarg[0] == 'x') { iform = INP_XER; break; } + if(pduType->uper_decoder + && optarg[0] == 'p') { iform = INP_PER; break; } fprintf(stderr, "-i<format>: '%s': improper format selector", optarg); exit(EX_UNAVAILABLE); @@ -80,6 +90,21 @@ main(int ac, char **av) { fprintf(stderr, "-o<format>: '%s': improper format selector", optarg); exit(EX_UNAVAILABLE); + case 'p': +#ifdef ASN_PDU_COLLECTION + { + asn_TYPE_descriptor_t **pdu = asn_pdu_collection; + if(optarg[0] < 'A' || optarg[0] > 'Z') { + fprintf(stderr, "Available PDU types:\n"); + for(; *pdu; pdu++) printf("%s\n", (*pdu)->name); + exit(0); + } + while(*pdu && strcmp((*pdu)->name, optarg)) pdu++; + if(*pdu) { pduType = *pdu; break; } + } +#endif /* ASN_PDU_COLLECTION */ + fprintf(stderr, "-p %s: Unrecognized PDU\n", optarg); + exit(EX_UNAVAILABLE); case 'b': suggested_bufsize = atoi(optarg); if(suggested_bufsize < 1 @@ -115,21 +140,32 @@ main(int ac, char **av) { break; case 'h': default: + fprintf(stderr, "Usage: %s [options] <data.ber> ...\n", av[0]); + fprintf(stderr, "Where options are:\n"); + if(pduType->uper_decoder) + fprintf(stderr, + " -iper (I) Input is in Unaligned PER (Packed Encoding Rules)\n"); + fprintf(stderr, + " -iber %s Input is in BER (Basic Encoding Rules)\n", + iform == INP_PER ? " " : "(I)"); fprintf(stderr, - "Usage: %s [options] <data.ber> ...\n" - "Where options are:\n" - " -iber (I) Input is in BER (Basic Encoding Rules)\n" " -ixer Input is in XER (XML Encoding Rules)\n" " -oder Output in DER (Distinguished Encoding Rules)\n" " -oxer (O) Output in XER (XML Encoding Rules)\n" " -otext Output in plain semi-structured text (dump)\n" - " -onull Verify (decode) input, but do not output\n" + " -onull Verify (decode) input, but do not output\n"); +#ifdef ASN_PDU_COLLECTION + fprintf(stderr, + " -p <PDU> Specify PDU type to decode\n" + " -p list List available PDUs\n"); +#endif /* ASN_PDU_COLLECTION */ + fprintf(stderr, " -b <size> Set the i/o buffer size (default is %ld)\n" " -c Check ASN.1 constraints after decoding\n" " -d Enable debugging (-dd is even better)\n" " -n <num> Process files <num> times\n" " -s <size> Set the stack usage limit\n" - , av[0], (long)suggested_bufsize); + , (long)suggested_bufsize); exit(EX_USAGE); } @@ -210,7 +246,8 @@ main(int ac, char **av) { /* Dump the buffer */ static int write_out(const void *buffer, size_t size, void *key) { - return (fwrite(buffer, 1, size, key) == size) ? 0 : -1; + FILE *fp = (FILE *)key; + return (fwrite(buffer, 1, size, fp) == size) ? 0 : -1; } static char *buffer; @@ -302,6 +339,7 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f rval.consumed = 0; while((rd = fread(fbuf, 1, fbuf_size, fp)) || !feof(fp)) { + asn_per_data_t pd; char *i_bptr; size_t i_size; @@ -330,6 +368,13 @@ static void *data_decode_from_file(asn_TYPE_descriptor_t *pduType, const char *f rval = xer_decode(opt_codec_ctx, pduType, (void **)&structure, i_bptr, i_size); break; + case INP_PER: + pd.buffer = (uint8_t *)i_bptr; + pd.nboff = 0; + pd.nbits = i_size * 8; + rval = pduType->uper_decoder(opt_codec_ctx, pduType, 0, + (void **)&structure, &pd); + break; } DEBUG("decode(%ld) consumed %ld, code %d", (long)buf_len, (long)rval.consumed, rval.code); diff --git a/skeletons/asn_codecs.h b/skeletons/asn_codecs.h index 9250adab..f25a7975 100644 --- a/skeletons/asn_codecs.h +++ b/skeletons/asn_codecs.h @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _ASN_CODECS_H_ @@ -61,6 +62,11 @@ typedef struct asn_enc_rval_s { tmp_error.structure_ptr = sptr; \ return tmp_error; \ } while(0) +#define _ASN_ENCODED_OK(rval) do { \ + rval.structure_ptr = 0; \ + rval.failed_type = 0; \ + return rval; \ +} while(0) /* * Type of the return value of the decoding functions (ber_decode, xer_decode) @@ -79,6 +85,12 @@ typedef struct asn_dec_rval_s { enum asn_dec_rval_code_e code; /* Result code */ size_t consumed; /* Number of bytes consumed */ } asn_dec_rval_t; +#define _ASN_DECODE_FAILED do { \ + asn_dec_rval_t tmp_error; \ + tmp_error.code = RC_FAIL; \ + tmp_error.consumed = 0; \ + return tmp_error; \ +} while(0) #ifdef __cplusplus } diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c index b599bdfa..97dc22af 100644 --- a/skeletons/asn_codecs_prim.c +++ b/skeletons/asn_codecs_prim.c @@ -119,9 +119,7 @@ der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr, } erval.encoded += st->size; - erval.structure_ptr = 0; - erval.failed_type = 0; - return erval; + _ASN_ENCODED_OK(erval); } void diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c index 6ab4a0bd..d3738df3 100644 --- a/skeletons/constr_CHOICE.c +++ b/skeletons/constr_CHOICE.c @@ -118,7 +118,7 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ssize_t consumed_myself = 0; /* Consumed bytes from ptr */ ASN_DEBUG("Decoding %s as CHOICE", td->name); - + /* * Create the target structure if it is not present already. */ @@ -196,7 +196,7 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, NEXT_PHASE(ctx); ctx->step = t2m->el_no; break; - } else if(specs->extensible == 0) { + } else if(specs->ext_start == -1) { ASN_DEBUG("Unexpected tag %s " "in non-extensible CHOICE %s", ber_tlv_tag_string(tlv_tag), td->name); @@ -252,16 +252,16 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, memb_ptr = (char *)st + elm->memb_offset; memb_ptr2 = &memb_ptr; } + /* Set presence to be able to free it properly at any time */ + _set_present_idx(st, specs->pres_offset, + specs->pres_size, ctx->step + 1); /* * Invoke the member fetch routine according to member's type */ rval = elm->type->ber_decoder(opt_codec_ctx, elm->type, - memb_ptr2, ptr, LEFT, - elm->tag_mode); + memb_ptr2, ptr, LEFT, elm->tag_mode); switch(rval.code) { case RC_OK: - _set_present_idx(st, specs->pres_offset, - specs->pres_size, ctx->step + 1); break; case RC_WMORE: /* More data expected */ if(!SIZE_VIOLATION) { @@ -377,7 +377,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, if(present == 0 && td->elements_count == 0) { /* The CHOICE is empty?! */ erval.encoded = 0; - return erval; + _ASN_ENCODED_OK(erval); } _ASN_ENCODE_FAILED; } @@ -391,7 +391,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr, if(memb_ptr == 0) { if(elm->optional) { erval.encoded = 0; - return erval; + _ASN_ENCODED_OK(erval); } /* Mandatory element absent */ _ASN_ENCODE_FAILED; @@ -729,7 +729,7 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, continue; /* It is expected extension */ - if(specs->extensible) { + if(specs->ext_start != -1) { ASN_DEBUG("Got anticipated extension"); /* * Check for (XCT_BOTH or XCT_UNKNOWN_BO) @@ -810,11 +810,86 @@ CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1); - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } +asn_dec_rval_t +CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics; + asn_dec_rval_t rv; + asn_per_constraint_t *ct; + asn_TYPE_member_t *elm; /* CHOICE's element */ + void *memb_ptr; + void **memb_ptr2; + void *st = *sptr; + int value; + + /* + * Create the target structure if it is not present already. + */ + if(!st) { + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) _ASN_DECODE_FAILED; + } + + if(constraints) ct = &constraints->value; + else if(td->per_constraints) ct = &td->per_constraints->value; + else ct = 0; + + if(ct && ct->flags & APC_EXTENSIBLE) { + value = per_get_few_bits(pd, 1); + if(value < 0) _ASN_DECODE_FAILED; + if(value) ct = 0; /* Not restricted */ + } + + if(ct && ct->range_bits >= 0) { + value = per_get_few_bits(pd, ct->range_bits); + if(value < 0) _ASN_DECODE_FAILED; + if(value > ct->upper_bound) + _ASN_DECODE_FAILED; + ASN_DEBUG("CHOICE %s got index %d in range %d", + td->name, value, ct->range_bits); + } else { + if(specs->ext_start == -1) + _ASN_DECODE_FAILED; + value = uper_get_nsnnwn(pd); + if(value < 0) _ASN_DECODE_FAILED; + value += specs->ext_start; + if(value >= td->elements_count) + _ASN_DECODE_FAILED; + ASN_DEBUG("NOT IMPLEMENTED YET"); + _ASN_DECODE_FAILED; + } + + /* Adjust if canonical order is different from natural order */ + if(specs->canonical_order) + value = specs->canonical_order[value]; + + /* Set presence to be able to free it later */ + _set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1); + + elm = &td->elements[value]; + if(elm->flags & ATF_POINTER) { + /* Member is a pointer to another structure */ + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name); + + rv = elm->type->uper_decoder(opt_codec_ctx, elm->type, + elm->per_constraints, memb_ptr2, pd); + if(rv.code != RC_OK) + ASN_DEBUG("Failed to decode %s in %s (CHOICE)", + elm->name, td->name); + return rv; +} + + int CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h index 859c5329..6276d7e4 100644 --- a/skeletons/constr_CHOICE.h +++ b/skeletons/constr_CHOICE.h @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #ifndef _CONSTR_CHOICE_H_ @@ -26,10 +27,13 @@ typedef struct asn_CHOICE_specifics_s { asn_TYPE_tag2member_t *tag2el; int tag2el_count; + /* Canonical ordering of CHOICE elements, for PER */ + int *canonical_order; + /* * Extensions-related stuff. */ - int extensible; /* Whether CHOICE is extensible */ + int ext_start; /* First member of extensions, or -1 */ } asn_CHOICE_specifics_t; /* @@ -42,6 +46,7 @@ ber_type_decoder_f CHOICE_decode_ber; der_type_encoder_f CHOICE_encode_der; xer_type_decoder_f CHOICE_decode_xer; xer_type_encoder_f CHOICE_encode_xer; +per_type_decoder_f CHOICE_decode_uper; asn_outmost_tag_f CHOICE_outmost_tag; #ifdef __cplusplus diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c index 7dcb5da1..e3dfd1d4 100644 --- a/skeletons/constr_SEQUENCE.c +++ b/skeletons/constr_SEQUENCE.c @@ -551,7 +551,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, _ASN_ENCODE_FAILED; erval.encoded = computed_size + ret; - if(!cb) return erval; + if(!cb) _ASN_ENCODED_OK(erval); /* * Encode all members. @@ -583,7 +583,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td, */ _ASN_ENCODE_FAILED; - return erval; + _ASN_ENCODED_OK(erval); } @@ -883,7 +883,7 @@ SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1); - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } @@ -1014,3 +1014,135 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return 0; } + +asn_dec_rval_t +SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics; + void *st = *sptr; /* Target structure. */ + int extpresent = 0; /* Extension additions are present */ + uint8_t *opres; /* Presence of optional root members */ + asn_per_data_t opmd; + asn_dec_rval_t rv; + int edx; + + (void)constraints; + + if(!st) { + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) _ASN_DECODE_FAILED; + } + + ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name); + + /* Handle extensions */ + if(specs->ext_before >= 0) { + extpresent = per_get_few_bits(pd, 1); + if(extpresent < 0) _ASN_DECODE_FAILED; + } + + /* Prepare a place and read-in the presence bitmap */ + if(specs->roms_count) { + opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1); + if(!opres) _ASN_DECODE_FAILED; + /* Get the presence map */ + if(per_get_many_bits(pd, opres, 0, specs->roms_count)) { + FREEMEM(opres); + _ASN_DECODE_FAILED; + } + opmd.buffer = opres; + opmd.nboff = 0; + opmd.nbits = specs->roms_count; + ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)", + td->name, specs->roms_count, *opres); + } else { + opres = 0; + memset(&opmd, 0, sizeof opmd); + } + + /* + * Get the sequence ROOT elements. + */ + for(edx = 0; edx < ((specs->ext_before < 0) + ? td->elements_count : specs->ext_before + 1); edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + /* Deal with optionality */ + if(elm->optional) { + int present = per_get_few_bits(&opmd, 1); + ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)", + td->name, elm->name, present, + (int)opmd.nboff, (int)opmd.nbits); + if(present == 0) { + /* This element is not present */ + if(elm->default_value) { + /* Fill-in DEFAULT */ + if(elm->default_value(memb_ptr2)) { + FREEMEM(opres); + _ASN_DECODE_FAILED; + } + } + /* The member is just not present */ + continue; + } + /* Fall through */ + } + + /* Fetch the member from the stream */ + ASN_DEBUG("Decoding member %s in %s", elm->name, td->name); + rv = elm->type->uper_decoder(opt_codec_ctx, elm->type, + elm->per_constraints, memb_ptr2, pd); + if(rv.code != RC_OK) { + ASN_DEBUG("Failed decode %s in %s", + elm->name, td->name); + FREEMEM(opres); + return rv; + } + } + + /* + * Deal with extensions. + */ + if(extpresent) { + ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name); + _ASN_DECODE_FAILED; + } else { + for(edx = specs->roms_count; edx < specs->roms_count + + specs->aoms_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + + if(!elm->default_value) continue; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + /* Set default value */ + if(elm->default_value(memb_ptr2)) { + FREEMEM(opres); + _ASN_DECODE_FAILED; + } + } + } + + rv.consumed = 0; + rv.code = RC_OK; + return rv; +} + diff --git a/skeletons/constr_SEQUENCE.h b/skeletons/constr_SEQUENCE.h index ab8a8ec1..b4ee47f9 100644 --- a/skeletons/constr_SEQUENCE.h +++ b/skeletons/constr_SEQUENCE.h @@ -25,10 +25,18 @@ typedef struct asn_SEQUENCE_specifics_s { int tag2el_count; /* + * Optional members of the extensions root (roms) or additions (aoms). + * Meaningful for PER. + */ + int *oms; /* Optional MemberS */ + int roms_count; /* Root optional members count */ + int aoms_count; /* Additions optional members count */ + + /* * Description of an extensions group. */ - int ext_after; /* Extensions start after this member */ - int ext_before; /* Extensions stop before this member */ + int ext_after; /* Extensions start after this member */ + int ext_before; /* Extensions stop before this member */ } asn_SEQUENCE_specifics_t; @@ -42,6 +50,7 @@ ber_type_decoder_f SEQUENCE_decode_ber; der_type_encoder_f SEQUENCE_encode_der; xer_type_decoder_f SEQUENCE_decode_xer; xer_type_encoder_f SEQUENCE_encode_xer; +per_type_decoder_f SEQUENCE_decode_uper; #ifdef __cplusplus } diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c index 12233a6c..3ddd5a39 100644 --- a/skeletons/constr_SEQUENCE_OF.c +++ b/skeletons/constr_SEQUENCE_OF.c @@ -51,9 +51,7 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, computed_size += encoding_size; if(!cb) { erval.encoded = computed_size; - erval.structure_ptr = 0; - erval.failed_type = 0; - return erval; + _ASN_ENCODED_OK(erval); } ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name); @@ -136,7 +134,7 @@ SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1); - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } diff --git a/skeletons/constr_SEQUENCE_OF.h b/skeletons/constr_SEQUENCE_OF.h index 94b04cdc..32078cb3 100644 --- a/skeletons/constr_SEQUENCE_OF.h +++ b/skeletons/constr_SEQUENCE_OF.h @@ -21,6 +21,7 @@ extern "C" { #define SEQUENCE_OF_constraint SET_OF_constraint #define SEQUENCE_OF_decode_ber SET_OF_decode_ber #define SEQUENCE_OF_decode_xer SET_OF_decode_xer +#define SEQUENCE_OF_decode_uper SET_OF_decode_uper der_type_encoder_f SEQUENCE_OF_encode_der; xer_type_encoder_f SEQUENCE_OF_encode_xer; diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c index f99d66f4..e83abd78 100644 --- a/skeletons/constr_SET.c +++ b/skeletons/constr_SET.c @@ -536,7 +536,7 @@ SET_encode_der(asn_TYPE_descriptor_t *td, if(ret == -1) _ASN_ENCODE_FAILED; er.encoded = computed_size + ret; - if(!cb) return er; + if(!cb) _ASN_ENCODED_OK(er); /* * Encode all members. @@ -570,7 +570,7 @@ SET_encode_der(asn_TYPE_descriptor_t *td, _ASN_ENCODE_FAILED; } - return er; + _ASN_ENCODED_OK(er); } #undef XER_ADVANCE @@ -857,7 +857,7 @@ SET_encode_xer(asn_TYPE_descriptor_t *td, void *sptr, if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1); - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c index bd25b3d8..251da390 100644 --- a/skeletons/constr_SET_OF.c +++ b/skeletons/constr_SET_OF.c @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ #include <asn_internal.h> @@ -356,7 +357,7 @@ SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, if(!cb) { erval.encoded = computed_size; - return erval; + _ASN_ENCODED_OK(erval); } /* @@ -448,7 +449,7 @@ SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr, erval.encoded = computed_size; } - return erval; + _ASN_ENCODED_OK(erval); } #undef XER_ADVANCE @@ -748,7 +749,7 @@ cleanup: } free(encs); } - return er; + _ASN_ENCODED_OK(er); } int @@ -850,3 +851,88 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr, return 0; } + +asn_dec_rval_t +SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, + asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) { + asn_dec_rval_t rv; + asn_SET_OF_specifics_t *specs = (asn_SET_OF_specifics_t *)td->specifics; + asn_TYPE_member_t *elm = td->elements; /* Single one */ + void *st = *sptr; + asn_anonymous_set_ *list; + asn_per_constraint_t *ct; + int repeat = 0; + ssize_t nelems; + + /* + * Create the target structure if it is not present already. + */ + if(!st) { + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) _ASN_DECODE_FAILED; + } + list = _A_SET_FROM_VOID(st); + + /* Figure out which constraints to use */ + if(constraints) ct = &constraints->size; + else if(td->per_constraints) ct = &td->per_constraints->size; + else ct = 0; + + if(ct && ct->flags & APC_EXTENSIBLE) { + int value = per_get_few_bits(pd, 1); + if(value < 0) _ASN_DECODE_FAILED; + if(value) ct = 0; /* Not restricted! */ + } + + if(ct && ct->effective_bits >= 0) { + /* X.691, #19.5: No length determinant */ + nelems = per_get_few_bits(pd, ct->effective_bits); + ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s", + (long)nelems, ct->lower_bound, td->name); + if(nelems < 0) _ASN_DECODE_FAILED; + nelems += ct->lower_bound; + } else { + nelems = -1; + } + + do { + int i; + if(nelems < 0) { + nelems = uper_get_length(pd, + ct ? ct->effective_bits : -1, &repeat); + ASN_DEBUG("Got to decode %d elements (eff %d)", + nelems, ct ? ct->effective_bits : -1); + if(nelems < 0) _ASN_DECODE_FAILED; + } + + for(i = 0; i < nelems; i++) { + void *ptr = 0; + ASN_DEBUG("SET OF %s decoding", elm->type->name); + rv = elm->type->uper_decoder(opt_codec_ctx, elm->type, + elm->per_constraints, &ptr, pd); + ASN_DEBUG("%s SET OF %s decoded %d, %p", + td->name, elm->type->name, rv.code, ptr); + if(rv.code == RC_OK) { + if(ASN_SET_ADD(list, ptr) == 0) + continue; + ASN_DEBUG("Failed to add element into %s", + td->name); + /* Fall through */ + } else { + ASN_DEBUG("Failed decoding %s of %s (SET OF)", + elm->type->name, td->name); + } + if(ptr) elm->type->free_struct(elm->type, ptr, 0); + _ASN_DECODE_FAILED; + } + + nelems = -1; /* Allow uper_get_length() */ + } while(repeat); + + ASN_DEBUG("Decoded %s as SET OF", td->name); + + rv.code = RC_OK; + rv.consumed = 0; + return rv; +} + diff --git a/skeletons/constr_SET_OF.h b/skeletons/constr_SET_OF.h index 410be26b..14209316 100644 --- a/skeletons/constr_SET_OF.h +++ b/skeletons/constr_SET_OF.h @@ -32,6 +32,7 @@ ber_type_decoder_f SET_OF_decode_ber; der_type_encoder_f SET_OF_encode_der; xer_type_decoder_f SET_OF_decode_xer; xer_type_encoder_f SET_OF_encode_xer; +per_type_decoder_f SET_OF_decode_uper; #ifdef __cplusplus } diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h index 90b6578c..37d21f6d 100644 --- a/skeletons/constr_TYPE.h +++ b/skeletons/constr_TYPE.h @@ -1,5 +1,6 @@ /*- - * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ /* @@ -38,6 +39,7 @@ typedef struct asn_struct_ctx_s { #include <der_encoder.h> /* Distinguished Encoding Rules encoder */ #include <xer_decoder.h> /* Decoder of XER (XML, text) */ #include <xer_encoder.h> /* Encoder into XER (XML, text) */ +#include <per_decoder.h> /* Packet Encoding Rules decoder */ #include <constraints.h> /* Subtype constraints support */ /* @@ -91,6 +93,7 @@ typedef struct asn_TYPE_descriptor_s { der_type_encoder_f *der_encoder; /* Canonical DER encoder */ xer_type_decoder_f *xer_decoder; /* Generic XER decoder */ xer_type_encoder_f *xer_encoder; /* [Canonical] XER encoder */ + per_type_decoder_f *uper_decoder; /* Unaligned PER decoder */ /*********************************************************************** * Internally useful members. Not to be used by applications directly. * @@ -105,6 +108,8 @@ typedef struct asn_TYPE_descriptor_s { ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */ int all_tags_count; /* Number of tags */ + asn_per_constraints_t *per_constraints; /* PER compiled constraints */ + /* * An ASN.1 production type members (members of SEQUENCE, SET, CHOICE). */ @@ -135,6 +140,8 @@ typedef struct asn_TYPE_member_s { int tag_mode; /* IMPLICIT/no/EXPLICIT tag at current level */ asn_TYPE_descriptor_t *type; /* Member type descriptor */ asn_constr_check_f *memb_constraints; /* Constraints validator */ + asn_per_constraints_t *per_constraints; /* PER compiled constraints */ + int (*default_value)(void **sptr); /* DEFAULT <value> */ char *name; /* ASN.1 identifier of the element */ } asn_TYPE_member_t; diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies index ce9c0010..87e96098 100644 --- a/skeletons/file-dependencies +++ b/skeletons/file-dependencies @@ -9,7 +9,7 @@ ANY.h ANY.c BMPString.h BMPString.c UTF8String.h BOOLEAN.h BOOLEAN.c -ENUMERATED.h ENUMERATED.c INTEGER.h +ENUMERATED.h ENUMERATED.c INTEGER.h NativeEnumerated.h GeneralString.h GeneralString.c GeneralizedTime.h GeneralizedTime.c GraphicString.h GraphicString.c @@ -58,4 +58,10 @@ constraints.h constraints.c # Subtype constraints support xer_support.h xer_support.c # XML parsing xer_decoder.h xer_decoder.c # XER decoding support xer_encoder.h xer_encoder.c # XER encoding support +per_decoder.h per_support.h # PER declarations, just in case #asn-decoder-template.c # Template for quick decoder creation + +CODEC-PER: # THIS IS A SPECIAL SECTION +per_support.h per_support.c # PER parsing +per_decoder.h per_decoder.c # PER decoding support + diff --git a/skeletons/per_decoder.c b/skeletons/per_decoder.c new file mode 100644 index 00000000..55c04cb5 --- /dev/null +++ b/skeletons/per_decoder.c @@ -0,0 +1,2 @@ +#include <asn_application.h> +#include <per_decoder.h> diff --git a/skeletons/per_decoder.h b/skeletons/per_decoder.h new file mode 100644 index 00000000..6303b3cf --- /dev/null +++ b/skeletons/per_decoder.h @@ -0,0 +1,55 @@ +/*- + * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef _PER_DECODER_H_ +#define _PER_DECODER_H_ + +#include <asn_application.h> +#include <per_support.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +/* + * Pre-computed PER constraints. + */ + enum asn_per_constraint_flags { + APC_UNCONSTRAINED = 0x0, /* No PER visible constraints */ + APC_SEMI_CONSTRAINED = 0x1, /* Constrained at "lb" */ + APC_CONSTRAINED = 0x2, /* Fully constrained */ + APC_EXTENSIBLE = 0x4 /* May have extension */ + }; +typedef struct asn_per_constraint_s { + + enum asn_per_constraint_flags flags; + int range_bits; /* Full number of bits in the range */ + int effective_bits; /* Effective bits */ + long lower_bound; /* "lb" value */ + long upper_bound; /* "ub" value */ +} asn_per_constraint_t; +typedef struct asn_per_constraints_s { + asn_per_constraint_t value; + asn_per_constraint_t size; +} asn_per_constraints_t; + + +struct asn_TYPE_descriptor_s; /* Forward declaration */ + +/* + * Type of the type-specific PER decoder function. + */ +typedef asn_dec_rval_t (per_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx, + struct asn_TYPE_descriptor_s *type_descriptor, + asn_per_constraints_t *constraints, + void **struct_ptr, + asn_per_data_t *per_data + ); + +#ifdef __cplusplus +} +#endif + +#endif /* _PER_DECODER_H_ */ diff --git a/skeletons/per_support.c b/skeletons/per_support.c new file mode 100644 index 00000000..506ca780 --- /dev/null +++ b/skeletons/per_support.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#include <asn_system.h> +#include <per_support.h> + +/* + * Extract a small number of bits (<= 24) from the specified PER data pointer. + */ +int32_t +per_get_few_bits(asn_per_data_t *pd, int nbits) { + size_t off; /* Next after last bit offset */ + uint32_t accum; + uint8_t *buf; + + if(nbits < 0 || pd->nboff + nbits > pd->nbits) + return -1; + if(nbits == 0) + return 0; + + /* + * Normalize position indicator. + */ + if(pd->nboff >= 8) { + pd->buffer += (pd->nboff >> 3); + pd->nbits -= (pd->nboff & ~0x07); + pd->nboff &= 0x07; + } + off = (pd->nboff += nbits); + buf = pd->buffer; + + /* + * Extract specified number of bits. + */ + if(off <= 8) + accum = (buf[0]) >> (8 - off); + else if(off <= 16) + accum = ((buf[0] << 8) + buf[1]) >> (16 - off); + else if(off <= 24) + accum = ((buf[0] << 16) + (buf[1] << 8) + buf[2]) >> (24 - off); + else if(off <= 31) + accum = ((buf[0] << 24) + (buf[1] << 16) + + (buf[2] << 8) + (buf[3])) >> (32 - off); + else { + pd->nboff -= nbits; /* Oops, revert back */ + return -1; + } + + return (accum & ((1 << nbits) - 1)); +} + +/* + * Extract a large number of bits from the specified PER data pointer. + */ +int +per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int alright, int nbits) { + int32_t value; + + if(alright && (nbits & 7)) { + /* Perform right alignment of a first few bits */ + value = per_get_few_bits(pd, nbits & 0x07); + if(value < 0) return -1; + *dst++ = value; /* value is already right-aligned */ + nbits &= ~7; + } + + while(nbits) { + if(nbits >= 24) { + value = per_get_few_bits(pd, 24); + if(value < 0) return -1; + *(dst++) = value >> 16; + *(dst++) = value >> 8; + *(dst++) = value; + nbits -= 24; + } else { + value = per_get_few_bits(pd, nbits); + if(value < 0) return -1; + if(nbits & 7) { /* implies alright */ + value <<= 8 - (nbits & 7), + nbits += 8 - (nbits & 7); + if(nbits > 24) + *dst++ = value >> 24; + } + if(nbits > 16) + *dst++ = value >> 16; + if(nbits > 8) + *dst++ = value >> 8; + *dst++ = value; + break; + } + } + + return 0; +} + +/* + * Get the length "n" from the stream. + */ +ssize_t +uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) { + ssize_t value; + + *repeat = 0; + + if(ebits >= 0) return per_get_few_bits(pd, ebits); + + value = per_get_few_bits(pd, 8); + if(value < 0) return -1; + if((value & 128) == 0) /* #10.9.3.6 */ + return (value & 0x7F); + if((value & 64) == 0) { /* #10.9.3.7 */ + value = ((value & 63) << 8) | per_get_few_bits(pd, 8); + if(value < 0) return -1; + return value; + } + value &= 63; /* this is "m" from X.691, #10.9.3.8 */ + if(value < 1 || value > 4) + return -1; + *repeat = 1; + return (16384 * value); +} + +/* + * Get the normally small non-negative whole number. + * X.691, #10.6 + */ +ssize_t +uper_get_nsnnwn(asn_per_data_t *pd) { + ssize_t value; + + value = per_get_few_bits(pd, 7); + if(value & 64) { /* implicit (value < 0) */ + value &= 63; + value <<= 2; + value |= per_get_few_bits(pd, 2); + if(value & 128) /* implicit (value < 0) */ + return -1; + if(value == 0) + return 0; + if(value >= 3) + return -1; + value = per_get_few_bits(pd, 8 * value); + return value; + } + + return value; +} diff --git a/skeletons/per_support.h b/skeletons/per_support.h new file mode 100644 index 00000000..25c92566 --- /dev/null +++ b/skeletons/per_support.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved. + * Redistribution and modifications are permitted subject to BSD license. + */ +#ifndef _PER_SUPPORT_H_ +#define _PER_SUPPORT_H_ + +#include <asn_system.h> /* Platform-specific types */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure describes a position inside a PER bit stream. + */ +typedef struct asn_per_data_s { + uint8_t *buffer; /* Pointer to the octet stream */ + size_t nboff; /* Bit offset to the meaningful bit */ + size_t nbits; /* Number of bits in the stream */ +} asn_per_data_t; + +/* + * Extract a small number of bits (<= 24) from the specified PER data pointer. + * This function returns -1 if the specified number of bits could not be + * extracted due to EOD or other conditions. + */ +int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits); + +/* + * Extract a large number of bits from the specified PER data pointer. + * This function returns -1 if the specified number of bits could not be + * extracted due to EOD or other conditions. + */ +int per_get_many_bits(asn_per_data_t *pd, uint8_t *dst, int right_align, + int get_nbits); + +/* + * Get the length "n" from the Unaligned PER stream. + */ +ssize_t uper_get_length(asn_per_data_t *pd, + int effective_bound_bits, + int *repeat); + +/* + * Get the normally small non-negative whole number. + */ +ssize_t uper_get_nsnnwn(asn_per_data_t *pd); + +#ifdef __cplusplus +} +#endif + +#endif /* _PER_SUPPORT_H_ */ diff --git a/skeletons/tests/Makefile.am b/skeletons/tests/Makefile.am index c374438d..a664a6f6 100644 --- a/skeletons/tests/Makefile.am +++ b/skeletons/tests/Makefile.am @@ -10,7 +10,8 @@ check_PROGRAMS = \ check-UTCTime \ check-INTEGER \ check-REAL \ - check-XER + check-XER \ + check-PER LDADD = -lm diff --git a/skeletons/tests/Makefile.in b/skeletons/tests/Makefile.in index f5a3c689..d0f980f2 100644 --- a/skeletons/tests/Makefile.in +++ b/skeletons/tests/Makefile.in @@ -13,7 +13,7 @@ # PARTICULAR PURPOSE. @SET_MAKE@ -SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OCTET_STRING.c check-OIDs.c check-REAL.c check-UTCTime.c check-UTF8String.c check-XER.c check-ber_tlv_tag.c check-length.c +SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OCTET_STRING.c check-OIDs.c check-PER.c check-REAL.c check-UTCTime.c check-UTF8String.c check-XER.c check-ber_tlv_tag.c check-length.c srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -40,7 +40,7 @@ check_PROGRAMS = check-ber_tlv_tag$(EXEEXT) check-length$(EXEEXT) \ check-OIDs$(EXEEXT) check-GeneralizedTime$(EXEEXT) \ check-OCTET_STRING$(EXEEXT) check-UTF8String$(EXEEXT) \ check-UTCTime$(EXEEXT) check-INTEGER$(EXEEXT) \ - check-REAL$(EXEEXT) check-XER$(EXEEXT) + check-REAL$(EXEEXT) check-XER$(EXEEXT) check-PER$(EXEEXT) subdir = skeletons/tests DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -66,6 +66,10 @@ check_OIDs_SOURCES = check-OIDs.c check_OIDs_OBJECTS = check-OIDs.$(OBJEXT) check_OIDs_LDADD = $(LDADD) check_OIDs_DEPENDENCIES = +check_PER_SOURCES = check-PER.c +check_PER_OBJECTS = check-PER.$(OBJEXT) +check_PER_LDADD = $(LDADD) +check_PER_DEPENDENCIES = check_REAL_SOURCES = check-REAL.c check_REAL_OBJECTS = check-REAL.$(OBJEXT) check_REAL_LDADD = $(LDADD) @@ -96,7 +100,7 @@ am__depfiles_maybe = depfiles @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/check-GeneralizedTime.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/check-INTEGER.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/check-OCTET_STRING.Po \ -@AMDEP_TRUE@ ./$(DEPDIR)/check-OIDs.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/check-OIDs.Po ./$(DEPDIR)/check-PER.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/check-REAL.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/check-UTCTime.Po \ @AMDEP_TRUE@ ./$(DEPDIR)/check-UTF8String.Po \ @@ -112,12 +116,13 @@ CCLD = $(CC) LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OCTET_STRING.c \ - check-OIDs.c check-REAL.c check-UTCTime.c check-UTF8String.c \ - check-XER.c check-ber_tlv_tag.c check-length.c -DIST_SOURCES = check-GeneralizedTime.c check-INTEGER.c \ - check-OCTET_STRING.c check-OIDs.c check-REAL.c check-UTCTime.c \ + check-OIDs.c check-PER.c check-REAL.c check-UTCTime.c \ check-UTF8String.c check-XER.c check-ber_tlv_tag.c \ check-length.c +DIST_SOURCES = check-GeneralizedTime.c check-INTEGER.c \ + check-OCTET_STRING.c check-OIDs.c check-PER.c check-REAL.c \ + check-UTCTime.c check-UTF8String.c check-XER.c \ + check-ber_tlv_tag.c check-length.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -285,6 +290,9 @@ check-OCTET_STRING$(EXEEXT): $(check_OCTET_STRING_OBJECTS) $(check_OCTET_STRING_ check-OIDs$(EXEEXT): $(check_OIDs_OBJECTS) $(check_OIDs_DEPENDENCIES) @rm -f check-OIDs$(EXEEXT) $(LINK) $(check_OIDs_LDFLAGS) $(check_OIDs_OBJECTS) $(check_OIDs_LDADD) $(LIBS) +check-PER$(EXEEXT): $(check_PER_OBJECTS) $(check_PER_DEPENDENCIES) + @rm -f check-PER$(EXEEXT) + $(LINK) $(check_PER_LDFLAGS) $(check_PER_OBJECTS) $(check_PER_LDADD) $(LIBS) check-REAL$(EXEEXT): $(check_REAL_OBJECTS) $(check_REAL_DEPENDENCIES) @rm -f check-REAL$(EXEEXT) $(LINK) $(check_REAL_LDFLAGS) $(check_REAL_OBJECTS) $(check_REAL_LDADD) $(LIBS) @@ -314,6 +322,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-INTEGER.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-OCTET_STRING.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-OIDs.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-PER.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-REAL.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-UTCTime.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-UTF8String.Po@am__quote@ diff --git a/skeletons/tests/check-INTEGER.c b/skeletons/tests/check-INTEGER.c index bb692c50..fccce287 100644 --- a/skeletons/tests/check-INTEGER.c +++ b/skeletons/tests/check-INTEGER.c @@ -6,6 +6,7 @@ #include <der_encoder.c> #include <xer_decoder.c> #include <xer_support.c> +#include <per_support.c> #include <constraints.c> static char *shared_scratch_start; diff --git a/skeletons/tests/check-OCTET_STRING.c b/skeletons/tests/check-OCTET_STRING.c index 51f6eb3b..b3e298f1 100644 --- a/skeletons/tests/check-OCTET_STRING.c +++ b/skeletons/tests/check-OCTET_STRING.c @@ -3,6 +3,7 @@ #include <BIT_STRING.c> #include <xer_decoder.c> #include <xer_support.c> +#include <per_support.c> #include <ber_decoder.c> #include <ber_tlv_length.c> #include <ber_tlv_tag.c> diff --git a/skeletons/tests/check-PER.c b/skeletons/tests/check-PER.c new file mode 100644 index 00000000..94f5fe42 --- /dev/null +++ b/skeletons/tests/check-PER.c @@ -0,0 +1,105 @@ +#include <per_support.c> +#include <assert.h> + +int +main() { + uint8_t buf[] = { 0xB7, 0x19, 0x2F, 0xEE, 0xAD }; + uint8_t tmpbuf[10]; + int32_t z; + asn_per_data_t pos; + + pos.buffer = buf; + pos.nboff = 0; + pos.nbits = sizeof(buf) * 8; + + z = per_get_few_bits(&pos, 32); + assert(z == -1); + + z = per_get_few_bits(&pos, 0); + assert(z == 0); + assert(pos.nboff == 0); + + z = per_get_few_bits(&pos, 1); + assert(z == 1); + assert(pos.nboff == 1); + + z = per_get_few_bits(&pos, 2); + assert(z == 1); + assert(pos.nboff == 3); + + z = per_get_few_bits(&pos, 2); + assert(z == 2); + assert(pos.nboff == 5); + + z = per_get_few_bits(&pos, 3); + assert(z == 7); + assert(pos.nboff == 8); + assert(pos.nbits == sizeof(buf) * 8); + + z = per_get_few_bits(&pos, 8); + assert(z == 0x19); + assert(pos.nboff == 8); + assert(pos.nbits == (sizeof(buf) - 1) * 8); + + z = per_get_few_bits(&pos, 1); + assert(z == 0); + assert(pos.nboff == 1); + assert(pos.nbits == (sizeof(buf) - 2) * 8); + + z = per_get_few_bits(&pos, 3); + assert(z == 2); + assert(pos.nboff == 4); + assert(pos.nbits == (sizeof(buf) - 2) * 8); + + z = per_get_few_bits(&pos, 8); + assert(z == 254); + assert(pos.nboff == 12); + + pos.buffer = buf; + pos.nboff = 2; + pos.nbits = sizeof(buf) * 8; + z = per_get_few_bits(&pos, 24); + assert(z == 14443711); + + pos.buffer = buf; + pos.nboff = 0; + pos.nbits = sizeof(buf) * 8; + z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8); + assert(z == 0); + assert(buf[0] == tmpbuf[0]); + assert(buf[1] == tmpbuf[1]); + assert(buf[2] == tmpbuf[2]); + assert(buf[3] == tmpbuf[3]); + assert(buf[4] == tmpbuf[4]); + + pos.buffer = buf; + pos.nboff = 1; + pos.nbits = sizeof(buf) * 8; + z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8); + assert(z == -1); + + pos.buffer = buf; + pos.nboff = 1; + pos.nbits = sizeof(buf) * 8; + z = per_get_many_bits(&pos, tmpbuf, 0, sizeof(buf) * 8 - 1); + assert(z == 0); + assert(tmpbuf[0] == 110); + assert(tmpbuf[1] == 50); + assert(tmpbuf[2] == 95); + assert(tmpbuf[3] == 221); + assert(tmpbuf[4] == 90); + + pos.buffer = buf; + pos.nboff = 1; + pos.nbits = sizeof(buf) * 8; + z = per_get_many_bits(&pos, tmpbuf, 1, sizeof(buf) * 8 - 1); + assert(z == 0); + assert(tmpbuf[0] == 55); + assert(tmpbuf[0] != buf[0]); + assert(tmpbuf[1] == buf[1]); + assert(tmpbuf[2] == buf[2]); + assert(tmpbuf[3] == buf[3]); + assert(tmpbuf[4] == buf[4]); + + return 0; +} diff --git a/skeletons/tests/check-UTF8String.c b/skeletons/tests/check-UTF8String.c index 10592a19..8a90b242 100644 --- a/skeletons/tests/check-UTF8String.c +++ b/skeletons/tests/check-UTF8String.c @@ -6,6 +6,7 @@ #include <der_encoder.c> #include <xer_decoder.c> #include <xer_support.c> +#include <per_support.c> #include <constraints.c> #include <sys/time.h> diff --git a/skeletons/tests/check-length.c b/skeletons/tests/check-length.c index 9a6d8d67..cf104050 100644 --- a/skeletons/tests/check-length.c +++ b/skeletons/tests/check-length.c @@ -4,6 +4,7 @@ #include <der_encoder.c> #include <xer_decoder.c> #include <xer_support.c> +#include <per_support.c> #include <constraints.c> #undef ADVANCE #undef RETURN diff --git a/skeletons/xer_encoder.c b/skeletons/xer_encoder.c index 3ee62cb8..aa7cf040 100644 --- a/skeletons/xer_encoder.c +++ b/skeletons/xer_encoder.c @@ -32,9 +32,7 @@ xer_encode(asn_TYPE_descriptor_t *td, void *sptr, er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded; - er.structure_ptr = 0; - er.failed_type = 0; - return er; + _ASN_ENCODED_OK(er); cb_failed: _ASN_ENCODE_FAILED; } diff --git a/skeletons/xer_support.c b/skeletons/xer_support.c index 1d0b42c5..9e34e692 100644 --- a/skeletons/xer_support.c +++ b/skeletons/xer_support.c @@ -4,11 +4,7 @@ * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> - +#include <asn_system.h> #include <xer_support.h> /* Parser states */ |