From dc06f6b0d27f506513fe94f2d02b2d4f3544925f Mon Sep 17 00:00:00 2001
From: Lev Walkin <vlm@lionet.info>
Date: Wed, 20 Oct 2004 15:50:55 +0000
Subject: [PATCH] XER support

---
 libasn1compiler/asn1c_C.c                  |   6 +-
 skeletons/ANY.c                            |   5 +-
 skeletons/BIT_STRING.c                     |   3 +-
 skeletons/BMPString.c                      |   3 +-
 skeletons/BOOLEAN.c                        |   5 +-
 skeletons/ENUMERATED.c                     |   1 +
 skeletons/GeneralString.c                  |   7 +-
 skeletons/GeneralizedTime.c                |   7 +-
 skeletons/GraphicString.c                  |   7 +-
 skeletons/IA5String.c                      |   9 +-
 skeletons/INTEGER.c                        |   1 +
 skeletons/ISO646String.c                   |   9 +-
 skeletons/NULL.c                           |   1 +
 skeletons/NativeEnumerated.c               |   1 +
 skeletons/NativeInteger.c                  |   5 +-
 skeletons/NativeReal.c                     |   5 +-
 skeletons/NumericString.c                  |   9 +-
 skeletons/OBJECT_IDENTIFIER.c              |   1 +
 skeletons/OCTET_STRING.c                   | 457 ++++++++++++++++++++-
 skeletons/OCTET_STRING.h                   |   7 +-
 skeletons/ObjectDescriptor.c               |   9 +-
 skeletons/PrintableString.c                |  11 +-
 skeletons/REAL.c                           |   1 +
 skeletons/RELATIVE-OID.c                   |   1 +
 skeletons/T61String.c                      |   7 +-
 skeletons/TeletexString.c                  |   7 +-
 skeletons/UTCTime.c                        |   5 +-
 skeletons/UTF8String.c                     |   7 +-
 skeletons/UniversalString.c                |   3 +-
 skeletons/VideotexString.c                 |   7 +-
 skeletons/VisibleString.c                  |   9 +-
 skeletons/asn_SEQUENCE_OF.c                |   1 -
 skeletons/asn_SET_OF.c                     |   1 -
 skeletons/asn_application.h                |   3 +-
 skeletons/asn_codecs.h                     |  76 ++++
 skeletons/asn_internal.h                   |   2 +-
 skeletons/{asn_types.h => asn_system.h}    |   8 +-
 skeletons/ber_codec_prim.c                 |   4 +-
 skeletons/ber_decoder.c                    |   6 +-
 skeletons/ber_decoder.h                    |  27 +-
 skeletons/constr_CHOICE.c                  |   4 +-
 skeletons/constr_CHOICE.h                  |   2 +-
 skeletons/constr_SEQUENCE.c                |   4 +-
 skeletons/constr_SEQUENCE_OF.c             |   3 +-
 skeletons/constr_SET.c                     |   4 +-
 skeletons/constr_SET_OF.c                  |   7 +-
 skeletons/constr_TYPE.h                    |  68 +--
 skeletons/constraints.h                    |   2 +-
 skeletons/file-dependencies                |   4 +-
 skeletons/tests/Makefile.am                |   4 +-
 skeletons/tests/Makefile.in                |  38 +-
 skeletons/tests/check-GeneralizedTime.c    |   2 +-
 skeletons/tests/check-OIDs.c               |   4 +-
 skeletons/tests/check-UTCTime.c            |   2 +-
 skeletons/tests/check-UTF8String.c         |   2 +
 skeletons/tests/check-length.c             |   4 +-
 skeletons/xer_decoder.c                    | 288 +++++++++++++
 skeletons/xer_decoder.h                    |  82 ++++
 skeletons/xer_encoder.c                    |   2 +-
 skeletons/xer_support.c                    | 234 +++++++++++
 skeletons/xer_support.h                    |  45 ++
 tests/19-param-OK.asn1.-P                  |   4 +
 tests/30-set-OK.asn1.-P                    |   1 +
 tests/31-set-of-OK.asn1.-P                 |   7 +
 tests/32-sequence-of-OK.asn1.-P            |   3 +
 tests/39-sequence-of-OK.asn1.-P            |   3 +
 tests/42-real-life-OK.asn1.-PR             |  10 +
 tests/43-recursion-OK.asn1.-P              |   7 +
 tests/44-choice-in-sequence-OK.asn1.-P     |   4 +
 tests/46-redefine-OK.asn1.-PR              |   4 +-
 tests/47-set-ext-OK.asn1.-P                |   4 +
 tests/50-constraint-OK.asn1.-P             |  60 ++-
 tests/60-any-OK.asn1.-P                    |   2 +
 tests/65-multi-tag-OK.asn1.-P              |  19 +-
 tests/65-multi-tag-OK.asn1.-Pfnative-types |  19 +-
 tests/66-ref-simple-OK.asn1.-P             |   4 +-
 76 files changed, 1471 insertions(+), 229 deletions(-)
 create mode 100644 skeletons/asn_codecs.h
 rename skeletons/{asn_types.h => asn_system.h} (92%)
 create mode 100644 skeletons/xer_decoder.c
 create mode 100644 skeletons/xer_decoder.h
 create mode 100644 skeletons/xer_support.c
 create mode 100644 skeletons/xer_support.h

diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index c91a50ba..882ed507 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -944,7 +944,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
 	OUT("\n");
 
 	p = MKID(expr->Identifier);
-	OUT("ber_dec_rval_t\n");
+	OUT("asn_dec_rval_t\n");
 	OUT("%s_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n", p);
 	INDENTED(
 	OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
@@ -1472,6 +1472,9 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
 	return 0;
 }
 
+/*
+ * Generate "asn_DEF_XXX" type definition.
+ */
 static int
 emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec spec) {
 	char *p;
@@ -1482,6 +1485,7 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
 	OUT("asn_TYPE_descriptor_t asn_DEF_%s = {\n", p);
 	INDENT(+1);
 		OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
+		OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
 
 		if(expr->expr_type & ASN_CONSTR_MASK) {
 			p = asn1c_type_name(arg, arg->expr, TNF_SAFE);
diff --git a/skeletons/ANY.c b/skeletons/ANY.c
index d501ca1a..4c51963b 100644
--- a/skeletons/ANY.c
+++ b/skeletons/ANY.c
@@ -13,13 +13,14 @@ static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = {
 	2	/* Special indicator that this is an ANY type */
 };
 asn_TYPE_descriptor_t asn_DEF_ANY = {
+	"ANY",
 	"ANY",
 	OCTET_STRING_free,
 	OCTET_STRING_print,
 	asn_generic_no_constraint,
 	OCTET_STRING_decode_ber,
 	OCTET_STRING_encode_der,
-	0,				/* Not implemented yet */
+	OCTET_STRING_decode_xer_hex,
 	ANY_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	0, 0, 0, 0,
@@ -111,7 +112,7 @@ ANY_new_fromType(asn_TYPE_descriptor_t *td, void *sptr) {
 
 int
 ANY_to_type(ANY_t *st, asn_TYPE_descriptor_t *td, void **struct_ptr) {
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	void *newst = 0;
 
 	if(!st || !td || !struct_ptr) {
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index 6c582a04..e21594a5 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -19,12 +19,13 @@ static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
 };
 asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
 	"BIT STRING",
+	"BIT_STRING",
 	OCTET_STRING_free,         /* Implemented in terms of OCTET STRING */
 	BIT_STRING_print,
 	BIT_STRING_constraint,
 	OCTET_STRING_decode_ber,   /* Implemented in terms of OCTET STRING */
 	OCTET_STRING_encode_der,   /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
+	OCTET_STRING_decode_xer_binary,
 	BIT_STRING_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_BIT_STRING_tags,
diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c
index e03d334d..cca6e3c5 100644
--- a/skeletons/BMPString.c
+++ b/skeletons/BMPString.c
@@ -13,6 +13,7 @@ static ber_tlv_tag_t asn_DEF_BMPString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_BMPString = {
+	"BMPString",
 	"BMPString",
 	OCTET_STRING_free,          /* Implemented in terms of OCTET STRING */
 	BMPString_print,
@@ -20,7 +21,7 @@ asn_TYPE_descriptor_t asn_DEF_BMPString = {
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
 	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
 	0,				/* Not implemented yet */
-	BMPString_encode_xer,		/* Conver to UTF8 */
+	BMPString_encode_xer,		/* Convert to UTF8 */
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_BMPString_tags,
 	sizeof(asn_DEF_BMPString_tags)
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 43b890f2..61eb58ff 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -12,6 +12,7 @@ static ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
+	"BOOLEAN",
 	"BOOLEAN",
 	BOOLEAN_free,
 	BOOLEAN_print,
@@ -32,13 +33,13 @@ asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
 /*
  * Decode BOOLEAN type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 BOOLEAN_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 		asn_TYPE_descriptor_t *td,
 		void **bool_value, void *buf_ptr, size_t size,
 		int tag_mode) {
 	BOOLEAN_t *st = (BOOLEAN_t *)*bool_value;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	ber_tlv_len_t length;
 	ber_tlv_len_t lidx;
 
diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c
index 13d7e058..83a71d07 100644
--- a/skeletons/ENUMERATED.c
+++ b/skeletons/ENUMERATED.c
@@ -13,6 +13,7 @@ static ber_tlv_tag_t asn_DEF_ENUMERATED_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_ENUMERATED = {
+	"ENUMERATED",
 	"ENUMERATED",
 	ASN__PRIMITIVE_TYPE_free,
 	INTEGER_print,			/* Implemented in terms of INTEGER */
diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c
index f846c026..e4ea6f8a 100644
--- a/skeletons/GeneralString.c
+++ b/skeletons/GeneralString.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_GeneralString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_GeneralString = {
+	"GeneralString",
 	"GeneralString",
 	OCTET_STRING_free,
 	OCTET_STRING_print,         /* non-ascii string */
 	asn_generic_unknown_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer,    /* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_hex,
+	OCTET_STRING_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_GeneralString_tags,
 	sizeof(asn_DEF_GeneralString_tags)
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index 9d5fe4ac..2a28d734 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -122,13 +122,14 @@ static ber_tlv_tag_t asn_DEF_GeneralizedTime_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))    /* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_GeneralizedTime = {
+	"GeneralizedTime",
 	"GeneralizedTime",
 	OCTET_STRING_free,
 	GeneralizedTime_print,
 	GeneralizedTime_constraint, /* Check validity of time */
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	GeneralizedTime_encode_der, /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
+	GeneralizedTime_encode_der,
+	OCTET_STRING_decode_xer_utf8,
 	GeneralizedTime_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_GeneralizedTime_tags,
@@ -231,7 +232,7 @@ GeneralizedTime_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		sptr = &st;
 	}
 
-	return OCTET_STRING_encode_xer_ascii(td, sptr, ilevel, flags,
+	return OCTET_STRING_encode_xer_utf8(td, sptr, ilevel, flags,
 		cb, app_key);
 }
 
diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c
index 67442fc1..c5d4a30b 100644
--- a/skeletons/GraphicString.c
+++ b/skeletons/GraphicString.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_GraphicString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_GraphicString = {
+	"GraphicString",
 	"GraphicString",
 	OCTET_STRING_free,
 	OCTET_STRING_print,         /* non-ascii string */
 	asn_generic_unknown_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer,    /* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_hex,
+	OCTET_STRING_encode_xer,	/* Can't expect it to be ASCII/UTF8 */
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_GraphicString_tags,
 	sizeof(asn_DEF_GraphicString_tags)
diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c
index 42eb17c4..32a7a7f8 100644
--- a/skeletons/IA5String.c
+++ b/skeletons/IA5String.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_IA5String_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_IA5String = {
+	"IA5String",
 	"IA5String",
 	OCTET_STRING_free,
-	OCTET_STRING_print_ascii,  /* ASCII subset */
+	OCTET_STRING_print_utf8,	/* ASCII subset */
 	IA5String_constraint,       /* Constraint on the alphabet */
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_IA5String_tags,
 	sizeof(asn_DEF_IA5String_tags)
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index f485bacb..fbd92724 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -15,6 +15,7 @@ static ber_tlv_tag_t asn_DEF_INTEGER_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_INTEGER = {
+	"INTEGER",
 	"INTEGER",
 	ASN__PRIMITIVE_TYPE_free,
 	INTEGER_print,
diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c
index 751139d8..035734b5 100644
--- a/skeletons/ISO646String.c
+++ b/skeletons/ISO646String.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_ISO646String_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_ISO646String = {
+	"ISO646String",
 	"ISO646String",
 	OCTET_STRING_free,
-	OCTET_STRING_print_ascii,   /* ASCII subset */
+	OCTET_STRING_print_utf8,	/* ASCII subset */
 	VisibleString_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_ISO646String_tags,
 	sizeof(asn_DEF_ISO646String_tags)
diff --git a/skeletons/NULL.c b/skeletons/NULL.c
index 7375d0fb..3b41be2f 100644
--- a/skeletons/NULL.c
+++ b/skeletons/NULL.c
@@ -13,6 +13,7 @@ static ber_tlv_tag_t asn_DEF_NULL_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_NULL = {
+	"NULL",
 	"NULL",
 	BOOLEAN_free,
 	NULL_print,
diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c
index 19c7559b..191afb77 100644
--- a/skeletons/NativeEnumerated.c
+++ b/skeletons/NativeEnumerated.c
@@ -20,6 +20,7 @@ static ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
 };
 asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
 	"ENUMERATED",			/* The ASN.1 type is still ENUMERATED */
+	"ENUMERATED",
 	NativeInteger_free,
 	NativeInteger_print,
 	asn_generic_no_constraint,
diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c
index ae71c044..695b9631 100644
--- a/skeletons/NativeInteger.c
+++ b/skeletons/NativeInteger.c
@@ -22,6 +22,7 @@ static ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
 };
 asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
 	"INTEGER",			/* The ASN.1 type is still INTEGER */
+	"INTEGER",
 	NativeInteger_free,
 	NativeInteger_print,
 	asn_generic_no_constraint,
@@ -41,12 +42,12 @@ asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
 /*
  * Decode INTEGER type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td,
 	void **int_ptr, void *buf_ptr, size_t size, int tag_mode) {
 	int *Int = (int *)*int_ptr;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	ber_tlv_len_t length;
 
 	/*
diff --git a/skeletons/NativeReal.c b/skeletons/NativeReal.c
index 83b1676e..b8a4926d 100644
--- a/skeletons/NativeReal.c
+++ b/skeletons/NativeReal.c
@@ -22,6 +22,7 @@ static ber_tlv_tag_t asn_DEF_NativeReal_tags[] = {
 };
 asn_TYPE_descriptor_t asn_DEF_NativeReal = {
 	"REAL",			/* The ASN.1 type is still REAL */
+	"REAL",
 	NativeReal_free,
 	NativeReal_print,
 	asn_generic_no_constraint,
@@ -41,12 +42,12 @@ asn_TYPE_descriptor_t asn_DEF_NativeReal = {
 /*
  * Decode REAL type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 NativeReal_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td,
 	void **dbl_ptr, void *buf_ptr, size_t size, int tag_mode) {
 	double *Dbl = (double *)*dbl_ptr;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	ber_tlv_len_t length;
 
 	/*
diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c
index 7d471985..dbff6e21 100644
--- a/skeletons/NumericString.c
+++ b/skeletons/NumericString.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_NumericString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_NumericString = {
+	"NumericString",
 	"NumericString",
 	OCTET_STRING_free,
-	OCTET_STRING_print_ascii,   /* ASCII subset */
+	OCTET_STRING_print_utf8,   /* ASCII subset */
 	NumericString_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_NumericString_tags,
 	sizeof(asn_DEF_NumericString_tags)
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index db2fd7a3..a08f18a9 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -16,6 +16,7 @@ static ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
 };
 asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
 	"OBJECT IDENTIFIER",
+	"OBJECT_IDENTIFIER",
 	ASN__PRIMITIVE_TYPE_free,
 	OBJECT_IDENTIFIER_print,
 	OBJECT_IDENTIFIER_constraint,
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 66f3a4ba..16d3a895 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -20,13 +20,14 @@ static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
 	0
 };
 asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
-	"OCTET STRING",
+	"OCTET STRING",		/* Canonical name */
+	"OCTET_STRING",		/* XML tag name */
 	OCTET_STRING_free,
 	OCTET_STRING_print,	/* non-ascii stuff, generally */
 	asn_generic_no_constraint,
 	OCTET_STRING_decode_ber,
 	OCTET_STRING_encode_der,
-	0,				/* Not implemented yet */
+	OCTET_STRING_decode_xer_hex,
 	OCTET_STRING_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_OCTET_STRING_tags,
@@ -160,14 +161,15 @@ _new_stack() {
 /*
  * Decode OCTET STRING type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td,
 	void **os_structure, void *buf_ptr, size_t size, int tag_mode) {
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
-				? td->specifics : &asn_DEF_OCTET_STRING_specs;
+				? (asn_OCTET_STRING_specifics_t *)td->specifics
+				: &asn_DEF_OCTET_STRING_specs;
 	BIT_STRING_t *st = (BIT_STRING_t *)*os_structure;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	asn_struct_ctx_t *ctx;
 	ssize_t consumed_myself = 0;
 	struct _stack *stck;		/* Expectations stack structure */
@@ -511,7 +513,8 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 	asn_app_consume_bytes_f *cb, void *app_key) {
 	asn_enc_rval_t er;
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
-				? td->specifics : &asn_DEF_OCTET_STRING_specs;
+				? (asn_OCTET_STRING_specifics_t *)td->specifics
+				: &asn_DEF_OCTET_STRING_specs;
 	BIT_STRING_t *st = (BIT_STRING_t *)sptr;
 	OS_type_e type_variant = (OS_type_e)specs->subvariant;
 	int fix_last_byte = 0;
@@ -683,8 +686,48 @@ static struct OCTET_STRING__xer_escape_table_s {
 	OSXET("\046\147\164\073"),	/* &gt; */
 };
 
+static int
+OS__check_escaped_control_char(void *buf, int size) {
+	size_t i;
+	/*
+	 * Inefficient algorithm which translates the escape sequences
+	 * defined above into characters. Returns -1 if not found.
+	 * TODO: replace by a faster algorithm (bsearch(), hash or
+	 * nested table lookups).
+	 */
+	for(i = 0; i < 32 /* Don't spend time on the bottom half */; i++) {
+		struct OCTET_STRING__xer_escape_table_s *el;
+		el = &OCTET_STRING__xer_escape_table[i];
+		if(el->size == size && memcmp(buf, el->string, size) == 0)
+			return i;
+	}
+	return -1;
+}
+
+static int
+OCTET_STRING__handle_control_chars(void *struct_ptr, void *chunk_buf, size_t chunk_size) {
+	/*
+	 * This might be one of the escape sequences
+	 * for control characters. Check it out.
+	 * #11.15.5
+	 */
+	int control_char = OS__check_escaped_control_char(chunk_buf,chunk_size);
+	if(control_char >= 0) {
+		OCTET_STRING_t *st = (OCTET_STRING_t *)struct_ptr;
+		void *p = REALLOC(st->buf, st->size + 2);
+		if(p) {
+			st->buf = (uint8_t *)p;
+			st->buf[st->size++] = control_char;
+			st->buf[st->size] = '\0';	/* nul-termination */
+			return 0;
+		}
+	}
+	
+	return -1;	/* No, it's not */
+}
+
 asn_enc_rval_t
-OCTET_STRING_encode_xer_ascii(asn_TYPE_descriptor_t *td, void *sptr,
+OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
 	int ilevel, enum xer_encoder_flags_e flags,
 		asn_app_consume_bytes_f *cb, void *app_key) {
 	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
@@ -728,6 +771,396 @@ OCTET_STRING_encode_xer_ascii(asn_TYPE_descriptor_t *td, void *sptr,
 	return er;
 }
 
+/*
+ * Convert from hexadecimal format (cstring): "AB CD EF"
+ */
+static ssize_t OCTET_STRING__convert_hexadecimal(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) {
+	OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
+	char *chunk_stop = (char *)chunk_buf;
+	char *p = chunk_stop;
+	char *pend = p + chunk_size;
+	unsigned int clv = 0;
+	int half = 0;	/* Half bit */
+	uint8_t *buf;
+
+	/* Reallocate buffer according to high cap estimation */
+	ssize_t _ns = st->size + (chunk_size + 1) / 2;
+	void *nptr = REALLOC(st->buf, _ns + 1);
+	if(!nptr) return -1;
+	st->buf = (uint8_t *)nptr;
+	buf = st->buf + st->size;
+
+	/*
+	 * If something like " a b c " appears here, the " a b":3 will be
+	 * converted, and the rest skipped. That is, unless buf_size is greater
+	 * than chunk_size, then it'll be equivalent to "ABC0".
+	 */
+	for(; p < pend; p++) {
+		int ch = *(unsigned char *)p;
+		switch(ch) {
+		case 0x09: case 0x0a: case 0x0c: case 0x0d:
+		case 0x20:
+			/* Ignore whitespace */
+			continue;
+		case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
+		case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
+			clv = (clv << 4) + (ch - 0x30);
+			break;
+		case 0x41: case 0x42: case 0x43:	/* ABC */
+		case 0x44: case 0x45: case 0x46:	/* DEF */
+			clv = (clv << 4) + (ch - (0x41 + 10));
+			break;
+		case 0x61: case 0x62: case 0x63:	/* abc */
+		case 0x64: case 0x65: case 0x66:	/* def */
+			clv = (clv << 4) + (ch - (0x61 + 10));
+			break;
+		default:
+			*buf = 0;	/* JIC */
+			return -1;
+		}
+		if(half++) {
+			half = 0;
+			*buf++ = clv;
+			chunk_stop = p + 1;
+		}
+	}
+
+	/*
+	 * Check partial decoding.
+	 */
+	if(half) {
+		if(have_more) {
+			/*
+			 * Partial specification is fine,
+			 * because no more more PXER_TEXT data is available.
+			 */
+			*buf++ = clv << 4;
+			chunk_stop = p;
+		}
+	} else {
+		chunk_stop = p;
+	}
+
+	st->size = buf - st->buf;	/* Adjust the buffer size */
+	assert(st->size <= _ns);
+	st->buf[st->size] = 0;		/* Courtesy termination */
+
+	return (chunk_stop - (char *)chunk_buf);	/* Converted size */
+}
+
+/*
+ * Convert from binary format: "00101011101"
+ */
+static ssize_t OCTET_STRING__convert_binary(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) {
+	BIT_STRING_t *st = (BIT_STRING_t *)sptr;
+	char *p = (char *)chunk_buf;
+	char *pend = p + chunk_size;
+	int bits_unused = st->bits_unused & 0x7;
+	uint8_t *buf;
+
+	/* Reallocate buffer according to high cap estimation */
+	ssize_t _ns = st->size + (chunk_size + 7) / 8;
+	void *nptr = REALLOC(st->buf, _ns + 1);
+	if(!nptr) return -1;
+	st->buf = (uint8_t *)nptr;
+	buf = st->buf + st->size;
+
+	(void)have_more;
+
+	if(bits_unused == 0)
+		bits_unused = 8;
+	else if(st->size)
+		buf--;
+
+	/*
+	 * Convert series of 0 and 1 into the octet string.
+	 */
+	for(; p < pend; p++) {
+		int ch = *(unsigned char *)p;
+		switch(ch) {
+		case 0x09: case 0x0a: case 0x0c: case 0x0d:
+		case 0x20:
+			/* Ignore whitespace */
+			break;
+		case 0x30:
+		case 0x31:
+			if(bits_unused-- <= 0) {
+				*++buf = 0;	/* Clean the cell */
+				bits_unused = 7;
+			}
+			*buf |= (ch&1) << bits_unused;
+			break;
+		default:
+			st->bits_unused = bits_unused;
+			return -1;
+		}
+	}
+
+	if(bits_unused == 8) {
+		st->size = buf - st->buf;
+		st->bits_unused = 0;
+	} else {
+		st->size = buf - st->buf + 1;
+		st->bits_unused = bits_unused;
+	}
+
+	assert(st->size <= _ns);
+	st->buf[st->size] = 0;		/* Courtesy termination */
+
+	return chunk_size;	/* Converted in full */
+}
+
+/*
+ * Something like strtod(), but with stricter rules.
+ */
+static int
+OS__strtoent(int base, char *buf, char *end, long *return_value) {
+	long val = 0;
+	char *p;
+
+	for(p = buf; p < end; p++) {
+		int ch = *p;
+		if((val * base + base) < 0) return -1;	/* Strange huge value */
+		switch(ch) {
+		case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: /*01234*/
+		case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: /*56789*/
+			val = val * base + (ch - 0x30);
+			break;
+		case 0x41: case 0x42: case 0x43:	/* ABC */
+		case 0x44: case 0x45: case 0x46:	/* DEF */
+			val = val * base + (ch - (0x41 + 10));
+			break;
+		case 0x61: case 0x62: case 0x63:	/* abc */
+		case 0x64: case 0x65: case 0x66:	/* def */
+			val = val * base + (ch - (0x61 + 10));
+			break;
+		case 0x3b:	/* ';' */
+			*return_value = val;
+			return (p - buf) + 1;
+		default:
+			return -1;	/* Character set error */
+		}
+	}
+
+	/* Do not return value. It's an error we're talking about here. */
+	return (p - buf);
+}
+
+/*
+ * Convert from the plain UTF-8 format, expanding entity references: "2 &lt; 3"
+ */
+static ssize_t OCTET_STRING__convert_entrefs(void *sptr, void *chunk_buf, size_t chunk_size, int have_more) {
+	OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
+	char *p = (char *)chunk_buf;
+	char *pend = p + chunk_size;
+	uint8_t *buf;
+
+	/* Reallocate buffer */
+	ssize_t _ns = st->size + chunk_size;
+	void *nptr = REALLOC(st->buf, _ns + 1);
+	if(!nptr) return -1;
+	st->buf = (uint8_t *)nptr;
+	buf = st->buf + st->size;
+
+	/*
+	 * Convert series of 0 and 1 into the octet string.
+	 */
+	for(; p < pend; p++) {
+		int ch = *(unsigned char *)p;
+		int len;	/* Length of the rest of the chunk */
+
+		if(ch != 0x26 /* '&' */) {
+			*buf++ = ch;
+			continue;	/* That was easy... */
+		}
+
+		/*
+		 * Process entity reference.
+		 */
+		len = chunk_size - (p - (char *)chunk_buf);
+		if(len == 1 /* "&" */) goto want_more;
+		if(p[1] == 0x23 /* '#' */) {
+			char *pval;	/* Pointer to start of digits */
+			long val;	/* Entity reference value */
+			int base;
+
+			if(len == 2 /* "&#" */) goto want_more;
+			if(p[2] == 0x78 /* 'x' */)
+				pval = p + 3, base = 16;
+			else
+				pval = p + 2, base = 10;
+			len = OS__strtoent(base, pval, p + len, &val);
+			if(len == -1) {
+				/* Invalid charset. Just copy verbatim. */
+				*buf++ = ch;
+				continue;
+			}
+			if(!len || pval[len-1] != 0x3b) goto want_more;
+			assert(val > 0);
+			p += (pval - p) + len - 1; /* Advance past entref */
+
+			if(val < 0x80) {
+				*buf++ = (char)val;
+			} else if(val < 0x800) {
+				*buf++ = 0xc0 | ((val >> 6));
+				*buf++ = 0x80 | ((val & 0x3f));
+			} else if(val < 0x10000) {
+				*buf++ = 0xe0 | ((val >> 12));
+				*buf++ = 0x80 | ((val >> 6) & 0x3f);
+				*buf++ = 0x80 | ((val & 0x3f));
+			} else if(val < 0x200000) {
+				*buf++ = 0xf0 | ((val >> 18));
+				*buf++ = 0x80 | ((val >> 12) & 0x3f);
+				*buf++ = 0x80 | ((val >> 6) & 0x3f);
+				*buf++ = 0x80 | ((val & 0x3f));
+			} else if(val < 0x4000000) {
+				*buf++ = 0xf8 | ((val >> 24));
+				*buf++ = 0x80 | ((val >> 18) & 0x3f);
+				*buf++ = 0x80 | ((val >> 12) & 0x3f);
+				*buf++ = 0x80 | ((val >> 6) & 0x3f);
+				*buf++ = 0x80 | ((val & 0x3f));
+			} else {
+				*buf++ = 0xfc | ((val >> 30) & 0x1);
+				*buf++ = 0x80 | ((val >> 24) & 0x3f);
+				*buf++ = 0x80 | ((val >> 18) & 0x3f);
+				*buf++ = 0x80 | ((val >> 12) & 0x3f);
+				*buf++ = 0x80 | ((val >> 6) & 0x3f);
+				*buf++ = 0x80 | ((val & 0x3f));
+			}
+		} else {
+			/*
+			 * Ugly, limited parsing of &amp; &gt; &lt;
+			 */
+			char *sc = (char *)memchr(p, 0x3b, len > 5 ? 5 : len);
+			if(!sc) goto want_more;
+			if((sc - p) == 4
+				&& p[1] == 0x61	/* 'a' */
+				&& p[2] == 0x6d	/* 'm' */
+				&& p[3] == 0x70	/* 'p' */) {
+				*buf++ = 0x26;
+				p = sc;
+				continue;
+			}
+			if((sc - p) == 3) {
+				if(p[1] == 0x6c) {
+					*buf = 0x3c;	/* '<' */
+				} else if(p[1] == 0x67) {
+					*buf = 0x3e;	/* '>' */
+				} else {
+					/* Unsupported entity reference */
+					*buf++ = ch;
+					continue;
+				}
+				if(p[2] != 0x74) {
+					/* Unsupported entity reference */
+					*buf++ = ch;
+					continue;
+				}
+				buf++;
+				p = sc;
+				continue;
+			}
+			/* Unsupported entity reference */
+			*buf++ = ch;
+		}
+
+		continue;
+	want_more:
+		if(have_more) {
+			/*
+			 * We know that no more data (of the same type)
+			 * is coming. Copy the rest verbatim.
+			 */
+			*buf++ = ch;
+			continue;
+		}
+		*buf = 0;	/* JIC */
+		/* Processing stalled: need more data */
+		return (p - (char *)chunk_buf);
+	}
+
+	st->size = buf - st->buf;
+	assert(st->size <= _ns);
+	st->buf[st->size] = 0;		/* Courtesy termination */
+
+	return chunk_size;	/* Converted in full */
+}
+
+/*
+ * Decode OCTET STRING from the XML element's body.
+ */
+static asn_dec_rval_t
+OCTET_STRING__decode_xer(asn_codec_ctx_t *opt_codec_ctx,
+	asn_TYPE_descriptor_t *td, void **sptr,
+	const char *opt_mname, void *buf_ptr, size_t size,
+	int (*opt_unexpected_tag_decoder)
+		(void *struct_ptr, void *chunk_buf, size_t chunk_size),
+	ssize_t (*body_receiver)
+		(void *struct_ptr, void *chunk_buf, size_t chunk_size,
+			int have_more)
+) {
+	asn_OCTET_STRING_specifics_t *specs = td->specifics
+				? (asn_OCTET_STRING_specifics_t *)td->specifics
+				: &asn_DEF_OCTET_STRING_specs;
+	const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
+	asn_struct_ctx_t *ctx;		/* Per-structure parser context */
+
+	/*
+	 * Create the string if does not exist.
+	 */
+	if(!*sptr) {
+		*sptr = CALLOC(1, specs->struct_size);
+		if(*sptr == NULL) {
+			asn_dec_rval_t rval;
+			rval.code = RC_FAIL;
+			rval.consumed = 0;
+			return rval;
+		}
+	}
+
+	/* Restore parsing context */
+	ctx = (asn_struct_ctx_t *)(((char *)*sptr) + specs->ctx_offset);
+
+	return xer_decode_general(opt_codec_ctx, ctx, *sptr, xml_tag,
+		buf_ptr, size, opt_unexpected_tag_decoder, body_receiver);
+}
+
+/*
+ * Decode OCTET STRING from the hexadecimal data.
+ */
+asn_dec_rval_t
+OCTET_STRING_decode_xer_hex(asn_codec_ctx_t *opt_codec_ctx,
+	asn_TYPE_descriptor_t *td, void **sptr,
+		const char *opt_mname, void *buf_ptr, size_t size) {
+	return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
+		buf_ptr, size, 0, OCTET_STRING__convert_hexadecimal);
+}
+
+/*
+ * Decode OCTET STRING from the binary (0/1) data.
+ */
+asn_dec_rval_t
+OCTET_STRING_decode_xer_binary(asn_codec_ctx_t *opt_codec_ctx,
+	asn_TYPE_descriptor_t *td, void **sptr,
+		const char *opt_mname, void *buf_ptr, size_t size) {
+	return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
+		buf_ptr, size, 0, OCTET_STRING__convert_binary);
+}
+
+/*
+ * Decode OCTET STRING from the string (ASCII/UTF-8) data.
+ */
+asn_dec_rval_t
+OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx,
+	asn_TYPE_descriptor_t *td, void **sptr,
+		const char *opt_mname, void *buf_ptr, size_t size) {
+	return OCTET_STRING__decode_xer(opt_codec_ctx, td, sptr, opt_mname,
+		buf_ptr, size,
+		OCTET_STRING__handle_control_chars,
+		OCTET_STRING__convert_entrefs);
+}
+
+
 int
 OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 	asn_app_consume_bytes_f *cb, void *app_key) {
@@ -770,7 +1203,7 @@ OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 }
 
 int
-OCTET_STRING_print_ascii(asn_TYPE_descriptor_t *td, const void *sptr,
+OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr,
 		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
 	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
 
@@ -788,10 +1221,11 @@ void
 OCTET_STRING_free(asn_TYPE_descriptor_t *td, void *sptr, int contents_only) {
 	OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
-				? td->specifics : &asn_DEF_OCTET_STRING_specs;
+				? (asn_OCTET_STRING_specifics_t *)td->specifics
+				: &asn_DEF_OCTET_STRING_specs;
 	asn_struct_ctx_t *ctx = (asn_struct_ctx_t *)
 					((char *)st + specs->ctx_offset);
-	struct _stack *stck = ctx->ptr;
+	struct _stack *stck = (struct _stack *)ctx->ptr;
 
 	if(!td || !st)
 		return;
@@ -863,7 +1297,8 @@ OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
 OCTET_STRING_t *
 OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) {
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
-				? td->specifics : &asn_DEF_OCTET_STRING_specs;
+				? (asn_OCTET_STRING_specifics_t *)td->specifics
+				: &asn_DEF_OCTET_STRING_specs;
 	OCTET_STRING_t *st;
 
 	st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
diff --git a/skeletons/OCTET_STRING.h b/skeletons/OCTET_STRING.h
index dd5262e8..10816358 100644
--- a/skeletons/OCTET_STRING.h
+++ b/skeletons/OCTET_STRING.h
@@ -18,11 +18,14 @@ extern asn_TYPE_descriptor_t asn_DEF_OCTET_STRING;
 
 asn_struct_free_f OCTET_STRING_free;
 asn_struct_print_f OCTET_STRING_print;
-asn_struct_print_f OCTET_STRING_print_ascii;
+asn_struct_print_f OCTET_STRING_print_utf8;
 ber_type_decoder_f OCTET_STRING_decode_ber;
 der_type_encoder_f OCTET_STRING_encode_der;
+xer_type_decoder_f OCTET_STRING_decode_xer_hex;		/* Hexadecimal */
+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_ascii;
+xer_type_encoder_f OCTET_STRING_encode_xer_utf8;
 
 /******************************
  * Handy conversion routines. *
diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c
index 125e6959..9f52147e 100644
--- a/skeletons/ObjectDescriptor.c
+++ b/skeletons/ObjectDescriptor.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_ObjectDescriptor_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_ObjectDescriptor = {
+	"ObjectDescriptor",
 	"ObjectDescriptor",
 	OCTET_STRING_free,
-	OCTET_STRING_print_ascii,   /* Treat as ASCII subset (it's not) */
+	OCTET_STRING_print_utf8,   /* Treat as ASCII subset (it's not) */
 	asn_generic_unknown_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_ObjectDescriptor_tags,
 	sizeof(asn_DEF_ObjectDescriptor_tags)
diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c
index dfe4f9c9..dc363d84 100644
--- a/skeletons/PrintableString.c
+++ b/skeletons/PrintableString.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_PrintableString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_PrintableString = {
+	"PrintableString",
 	"PrintableString",
 	OCTET_STRING_free,
-	OCTET_STRING_print_ascii,   /* ASCII subset */
+	OCTET_STRING_print_utf8,	/* ASCII subset */
 	PrintableString_constraint,
-	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
+	OCTET_STRING_decode_ber,      /* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_PrintableString_tags,
 	sizeof(asn_DEF_PrintableString_tags)
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index d395c848..c61f7233 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -24,6 +24,7 @@ static ber_tlv_tag_t asn_DEF_REAL_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_REAL = {
+	"REAL",
 	"REAL",
 	ASN__PRIMITIVE_TYPE_free,
 	REAL_print,
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 899e69c6..eba1eaa4 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -17,6 +17,7 @@ static ber_tlv_tag_t asn_DEF_RELATIVE_OID_tags[] = {
 };
 asn_TYPE_descriptor_t asn_DEF_RELATIVE_OID = {
 	"RELATIVE-OID",
+	"RELATIVE_OID",
 	ASN__PRIMITIVE_TYPE_free,
 	RELATIVE_OID_print,
 	asn_generic_no_constraint,
diff --git a/skeletons/T61String.c b/skeletons/T61String.c
index 41835c4b..a37c176e 100644
--- a/skeletons/T61String.c
+++ b/skeletons/T61String.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_T61String_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_T61String = {
+	"T61String",
 	"T61String",
 	OCTET_STRING_free,
 	OCTET_STRING_print,         /* non-ascii string */
 	asn_generic_unknown_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer,    /* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_hex,
+	OCTET_STRING_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_T61String_tags,
 	sizeof(asn_DEF_T61String_tags)
diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c
index aa8d2a90..47aad419 100644
--- a/skeletons/TeletexString.c
+++ b/skeletons/TeletexString.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_TeletexString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_TeletexString = {
+	"TeletexString",
 	"TeletexString",
 	OCTET_STRING_free,
 	OCTET_STRING_print,         /* non-ascii string */
 	asn_generic_unknown_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer,    /* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_hex,
+	OCTET_STRING_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_TeletexString_tags,
 	sizeof(asn_DEF_TeletexString_tags)
diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c
index 045b172f..f9de9dd3 100644
--- a/skeletons/UTCTime.c
+++ b/skeletons/UTCTime.c
@@ -20,13 +20,14 @@ static ber_tlv_tag_t asn_DEF_UTCTime_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))    /* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_UTCTime = {
+	"UTCTime",
 	"UTCTime",
 	OCTET_STRING_free,
 	UTCTime_print,
 	UTCTime_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
 	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
+	OCTET_STRING_decode_xer_utf8,
 	UTCTime_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_UTCTime_tags,
@@ -88,7 +89,7 @@ UTCTime_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		sptr = &st;
 	}
 
-	return OCTET_STRING_encode_xer_ascii(td, sptr, ilevel, flags,
+	return OCTET_STRING_encode_xer_utf8(td, sptr, ilevel, flags,
 		cb, app_key);
 }
 
diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c
index 934a424a..1c0c731d 100644
--- a/skeletons/UTF8String.c
+++ b/skeletons/UTF8String.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_UTF8String_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2)),	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_UTF8String = {
+	"UTF8String",
 	"UTF8String",
 	OCTET_STRING_free,
 	UTF8String_print,
 	UTF8String_constraint,      /* Check for invalid codes, etc. */
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer_ascii,	/* Already in UTF-8 format */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_UTF8String_tags,
 	sizeof(asn_DEF_UTF8String_tags)
diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c
index f43de182..2221000f 100644
--- a/skeletons/UniversalString.c
+++ b/skeletons/UniversalString.c
@@ -13,6 +13,7 @@ static ber_tlv_tag_t asn_DEF_UniversalString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_UniversalString = {
+	"UniversalString",
 	"UniversalString",
 	OCTET_STRING_free,
 	UniversalString_print,      /* Convert into UTF8 and print */
@@ -20,7 +21,7 @@ asn_TYPE_descriptor_t asn_DEF_UniversalString = {
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
 	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
 	0,				/* Not implemented yet */
-	UniversalString_encode_xer,	/* Conver into UTF8 */
+	UniversalString_encode_xer,	/* Convert into UTF8 */
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_UniversalString_tags,
 	sizeof(asn_DEF_UniversalString_tags)
diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c
index fa6892ec..2a2baa81 100644
--- a/skeletons/VideotexString.c
+++ b/skeletons/VideotexString.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_VideotexString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_VideotexString = {
+	"VideotexString",
 	"VideotexString",
 	OCTET_STRING_free,
 	OCTET_STRING_print,         /* non-ascii string */
 	asn_generic_unknown_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer,    /* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_hex,
+	OCTET_STRING_encode_xer,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_VideotexString_tags,
 	sizeof(asn_DEF_VideotexString_tags)
diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c
index 8e361e71..7170b542 100644
--- a/skeletons/VisibleString.c
+++ b/skeletons/VisibleString.c
@@ -13,14 +13,15 @@ static ber_tlv_tag_t asn_DEF_VisibleString_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
 asn_TYPE_descriptor_t asn_DEF_VisibleString = {
+	"VisibleString",
 	"VisibleString",
 	OCTET_STRING_free,
-	OCTET_STRING_print_ascii,   /* ASCII subset */
+	OCTET_STRING_print_utf8,   /* ASCII subset */
 	VisibleString_constraint,
 	OCTET_STRING_decode_ber,    /* Implemented in terms of OCTET STRING */
-	OCTET_STRING_encode_der,    /* Implemented in terms of OCTET STRING */
-	0,				/* Not implemented yet */
-	OCTET_STRING_encode_xer_ascii,/* Implemented in terms of OCTET STRING */
+	OCTET_STRING_encode_der,
+	OCTET_STRING_decode_xer_utf8,
+	OCTET_STRING_encode_xer_utf8,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_VisibleString_tags,
 	sizeof(asn_DEF_VisibleString_tags)
diff --git a/skeletons/asn_SEQUENCE_OF.c b/skeletons/asn_SEQUENCE_OF.c
index b2d5f1fa..ec952fc9 100644
--- a/skeletons/asn_SEQUENCE_OF.c
+++ b/skeletons/asn_SEQUENCE_OF.c
@@ -3,7 +3,6 @@
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #include <asn_internal.h>
-#include <asn_types.h>	/* for MALLOC/REALLOC/FREEMEM */
 #include <asn_SEQUENCE_OF.h>
 
 typedef A_SEQUENCE_OF(void) asn_sequence;
diff --git a/skeletons/asn_SET_OF.c b/skeletons/asn_SET_OF.c
index 7aeafddb..5e268c07 100644
--- a/skeletons/asn_SET_OF.c
+++ b/skeletons/asn_SET_OF.c
@@ -3,7 +3,6 @@
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #include <asn_internal.h>
-#include <asn_types.h>	/* for MALLOC/REALLOC/FREEMEM */
 #include <asn_SET_OF.h>
 #include <errno.h>
 
diff --git a/skeletons/asn_application.h b/skeletons/asn_application.h
index 33de699a..4987e5cd 100644
--- a/skeletons/asn_application.h
+++ b/skeletons/asn_application.h
@@ -8,7 +8,8 @@
 #ifndef	_ASN_APPLICATION_H_
 #define	_ASN_APPLICATION_H_
 
-#include <asn_types.h>		/* for platform-dependent types */
+#include <asn_system.h>		/* for platform-dependent types */
+#include <asn_codecs.h>		/* for ASN.1 codecs specifics */
 
 /*
  * Generic type of an application-defined callback to return various
diff --git a/skeletons/asn_codecs.h b/skeletons/asn_codecs.h
new file mode 100644
index 00000000..2f8ed10b
--- /dev/null
+++ b/skeletons/asn_codecs.h
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef	_ASN_CODECS_H_
+#define	_ASN_CODECS_H_
+
+struct asn_TYPE_descriptor_s;	/* Forward declaration */
+
+/*
+ * This structure defines a context that may be passed to every ASN.1 encoder
+ * or decoder function.
+ * WARNING: if max_stack_size member is set, and you are calling the
+ * function pointers of the asn_TYPE_descriptor_t directly,
+ * this structure must be ALLOCATED ON THE STACK!
+ */
+typedef struct asn_codec_ctx_s {
+	/*
+	 * Limit the decoder routines to use no (much) more stack than a given
+	 * number of bytes. Most of decoders are stack-based, and this
+	 * would protect against stack overflows if the number of nested
+	 * encodings is high.
+	 * The OCTET STRING, BIT STRING and ANY BER decoders are heap-based,
+	 * and are safe from this kind of overflow.
+	 * A value from getrlimit(RLIMIT_STACK) may be used to initialize
+	 * this variable. Be careful in multithreaded environments, as the
+	 * stack size is rather limited.
+	 */
+	size_t  max_stack_size; /* 0 disables stack bounds checking */
+} asn_codec_ctx_t;
+
+/*
+ * Type of the return value of the encoding functions (der_encode, xer_encode).
+ */
+typedef struct asn_enc_rval_s {
+	/*
+	 * Number of bytes encoded.
+	 * -1 indicates failure to encode the structure.
+	 * In this case, the members below this one are meaningful.
+	 */
+	ssize_t encoded;
+
+	/*
+	 * Members meaningful when (encoded == -1), for post mortem analysis.
+	 */
+
+	/* Type which cannot be encoded */
+	struct asn_TYPE_descriptor_s *failed_type;
+
+	/* Pointer to the structure of that type */
+	void *structure_ptr;
+} asn_enc_rval_t;
+#define	_ASN_ENCODE_FAILED do {					\
+	asn_enc_rval_t __er = { -1, td, sptr };			\
+	return __er;						\
+} while(0)
+
+/*
+ * Type of the return value of the decoding functions (ber_decode, xer_decode)
+ * 
+ * Please note that the number of consumed bytes is ALWAYS meaningful,
+ * even if code==RC_FAIL. This is to indicate the number of successfully
+ * decoded bytes, hence providing a possibility to fail with more diagnostics
+ * (i.e., print the offending remainder of the buffer).
+ */
+enum asn_dec_rval_code_e {
+	RC_OK,		/* Decoded successfully */
+	RC_WMORE,	/* More data expected, call again */
+	RC_FAIL		/* Failure to decode data */
+};
+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;
+
+#endif	/* _ASN_CODECS_H_ */
diff --git a/skeletons/asn_internal.h b/skeletons/asn_internal.h
index a7690eb0..c2aa9e51 100644
--- a/skeletons/asn_internal.h
+++ b/skeletons/asn_internal.h
@@ -8,7 +8,7 @@
 #ifndef	_ASN_INTERNAL_H_
 #define	_ASN_INTERNAL_H_
 
-#define	ASN1C_ENVIRONMENT_VERSION	96	/* Compile-time version */
+#define	ASN1C_ENVIRONMENT_VERSION	98	/* Compile-time version */
 int get_asn1c_environment_version(void);	/* Run-time version */
 
 #include <asn_application.h>	/* Application-visible API */
diff --git a/skeletons/asn_types.h b/skeletons/asn_system.h
similarity index 92%
rename from skeletons/asn_types.h
rename to skeletons/asn_system.h
index cf5c87e4..ee64a0ca 100644
--- a/skeletons/asn_types.h
+++ b/skeletons/asn_system.h
@@ -5,8 +5,8 @@
 /*
  * Miscellaneous system-dependent types.
  */
-#ifndef	_ASN_TYPES_H_
-#define	_ASN_TYPES_H_
+#ifndef	_ASN_SYSTEM_H_
+#define	_ASN_SYSTEM_H_
 
 #ifdef	HAVE_CONFIG_H
 #include "config.h"
@@ -31,7 +31,7 @@
  * 2. Sun Solaris requires <alloca.h> for alloca(3),
  * but does not have <stdint.h>.
  */
-#if	(!defined(__FreeBSD__) || !defined(_SYS_INTTYPES_H_))
+#if	(!defined(__FreeBSD__) || !defined(_SYS_INTSYSTEM_H_))
 #if	defined(sun)
 #include <alloca.h>	/* For alloca(3) */
 #else
@@ -62,4 +62,4 @@
 #endif /* __GNUC__ */
 #endif	/* MIN */
 
-#endif	/* _ASN_TYPES_H_ */
+#endif	/* _ASN_SYSTEM_H_ */
diff --git a/skeletons/ber_codec_prim.c b/skeletons/ber_codec_prim.c
index c4d06e16..2c367aea 100644
--- a/skeletons/ber_codec_prim.c
+++ b/skeletons/ber_codec_prim.c
@@ -10,12 +10,12 @@
 /*
  * Decode an always-primitive type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td,
 	void **sptr, void *buf_ptr, size_t size, int tag_mode) {
 	ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	ber_tlv_len_t length;
 
 	/*
diff --git a/skeletons/ber_decoder.c b/skeletons/ber_decoder.c
index cda6c16d..c78cfee3 100644
--- a/skeletons/ber_decoder.c
+++ b/skeletons/ber_decoder.c
@@ -14,7 +14,7 @@
 	} while(0)
 #undef	RETURN
 #define	RETURN(_code)	do {						\
-		ber_dec_rval_t rval;					\
+		asn_dec_rval_t rval;					\
 		rval.code = _code;					\
 		if(opt_ctx) opt_ctx->step = step; /* Save context */	\
 		if(_code == RC_OK || opt_ctx)				\
@@ -27,7 +27,7 @@
 /*
  * The BER decoder of any type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 ber_decode(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *type_descriptor,
 	void **struct_ptr, void *ptr, size_t size) {
@@ -55,7 +55,7 @@ ber_decode(asn_codec_ctx_t *opt_codec_ctx,
 /*
  * Check the set of <TL<TL<TL...>>> tags matches the definition.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 ber_check_tags(asn_codec_ctx_t *opt_codec_ctx,
 		asn_TYPE_descriptor_t *td, asn_struct_ctx_t *opt_ctx,
 		void *ptr, size_t size, int tag_mode, int last_tag_form,
diff --git a/skeletons/ber_decoder.h b/skeletons/ber_decoder.h
index 8499c6a1..b835b0f5 100644
--- a/skeletons/ber_decoder.h
+++ b/skeletons/ber_decoder.h
@@ -10,30 +10,11 @@
 struct asn_TYPE_descriptor_s;	/* Forward declaration */
 struct asn_codec_ctx_s;		/* Forward declaration */
 
-/*
- * This structure describes the return value common across the
- * various BER decoders.
- * 
- * Please note that the number of consumed bytes is ALWAYS meaningful,
- * even if code!=RC_OK. This is so to indicate the number of successfully
- * decoded bytes, hence provide a possibility, to fail with more diagnostics
- * (i.e., print the offending remainder of the buffer).
- */
-  enum ber_dec_rval_code_e {
-	RC_OK,		/* Decoded successfully */
-	RC_WMORE,	/* More data expected, call again */
-	RC_FAIL		/* Failure to decode data */
-  };
-typedef struct ber_dec_rval_s {
-	enum ber_dec_rval_code_e code;	/* Result code */
-	size_t consumed;		/* Number of bytes consumed */
-} ber_dec_rval_t;
-
 /*
  * The BER decoder of any type.
  * This function may be invoked directly from the application.
  */
-ber_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx,
+asn_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx,
 	struct asn_TYPE_descriptor_s *type_descriptor,
 	void **struct_ptr,	/* Pointer to a target structure's pointer */
 	void *buffer,		/* Data to be decoded */
@@ -43,10 +24,10 @@ ber_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx,
 /*
  * Type of generic function which decodes the byte stream into the structure.
  */
-typedef ber_dec_rval_t (ber_type_decoder_f)(
+typedef asn_dec_rval_t (ber_type_decoder_f)(
 		struct asn_codec_ctx_s *opt_codec_ctx,
 		struct asn_TYPE_descriptor_s *type_descriptor,
-		void **type_structure, void *buf_ptr, size_t size,
+		void **struct_ptr, void *buf_ptr, size_t size,
 		int tag_mode);
 
 /*******************************
@@ -60,7 +41,7 @@ typedef ber_dec_rval_t (ber_type_decoder_f)(
  * "end of content" sequences. The number may only be negative if the
  * head->last_tag_form is non-zero.
  */
-ber_dec_rval_t ber_check_tags(
+asn_dec_rval_t ber_check_tags(
 		struct asn_codec_ctx_s *opt_codec_ctx,	/* optional context */
 		struct asn_TYPE_descriptor_s *type_dsc,
 		asn_struct_ctx_t *opt_ctx,	/* saved decoding context */
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index 236b9ad5..9305313e 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -96,7 +96,7 @@ _search4tag(const void *ap, const void *bp) {
 /*
  * The decoder of the CHOICE type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	void **struct_ptr, void *ptr, size_t size, int tag_mode) {
 	/*
@@ -113,7 +113,7 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 	ber_tlv_tag_t tlv_tag;	/* T from TLV */
 	ssize_t tag_len;	/* Length of TLV's T */
-	ber_dec_rval_t rval;	/* Return code from subparsers */
+	asn_dec_rval_t rval;	/* Return code from subparsers */
 
 	ssize_t consumed_myself = 0;	/* Consumed bytes from ptr */
 
diff --git a/skeletons/constr_CHOICE.h b/skeletons/constr_CHOICE.h
index 8cd323a2..2685134b 100644
--- a/skeletons/constr_CHOICE.h
+++ b/skeletons/constr_CHOICE.h
@@ -12,7 +12,7 @@ typedef struct asn_CHOICE_specifics_s {
 	 * Target structure description.
 	 */
 	int struct_size;	/* Size of the target structure. */
-	int ctx_offset;		/* Offset of the ber_dec_ctx_t member */
+	int ctx_offset;		/* Offset of the asn_codec_ctx_t member */
 	int pres_offset;	/* Identifier of the present member */
 	int pres_size;		/* Size of the identifier (enum) */
 
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 693ddd20..fcca4799 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -107,7 +107,7 @@ _t2e_cmp(const void *ap, const void *bp) {
 /*
  * The decoder of the SEQUENCE type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	void **struct_ptr, void *ptr, size_t size, int tag_mode) {
 	/*
@@ -123,7 +123,7 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	asn_struct_ctx_t *ctx;	/* Decoder context */
 
 	ber_tlv_tag_t tlv_tag;	/* T from TLV */
-	ber_dec_rval_t rval;	/* Return code from subparsers */
+	asn_dec_rval_t rval;	/* Return code from subparsers */
 
 	ssize_t consumed_myself = 0;	/* Consumed bytes from ptr */
 	int edx;			/* SEQUENCE element's index */
diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c
index 3d526d01..f126d78a 100644
--- a/skeletons/constr_SEQUENCE_OF.c
+++ b/skeletons/constr_SEQUENCE_OF.c
@@ -92,7 +92,8 @@ SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	asn_TYPE_member_t *element = td->elements;
 	A_SEQUENCE_OF(void) *list;
 	const char *mname = specs->as_XMLValueList
-		? 0 : ((*element->name) ? element->name : element->type->name);
+		? 0 : ((*element->name)
+			? element->name : element->type->xml_tag);
 	unsigned int mlen = mname ? strlen(mname) : 0;
 	int xcan = (flags & XER_F_CANONICAL);
 	int i;
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index ce6afd6d..be360162 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -96,7 +96,7 @@ _t2e_cmp(const void *ap, const void *bp) {
 /*
  * The decoder of the SET type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	void **struct_ptr, void *ptr, size_t size, int tag_mode) {
 	/*
@@ -112,7 +112,7 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	asn_struct_ctx_t *ctx;	/* Decoder context */
 
 	ber_tlv_tag_t tlv_tag;	/* T from TLV */
-	ber_dec_rval_t rval;	/* Return code from subparsers */
+	asn_dec_rval_t rval;	/* Return code from subparsers */
 
 	ssize_t consumed_myself = 0;	/* Consumed bytes from ptr */
 	int edx;			/* SET element's index */
diff --git a/skeletons/constr_SET_OF.c b/skeletons/constr_SET_OF.c
index 518713ca..164668c8 100644
--- a/skeletons/constr_SET_OF.c
+++ b/skeletons/constr_SET_OF.c
@@ -65,7 +65,7 @@
 /*
  * The decoder of the SET OF type.
  */
-ber_dec_rval_t
+asn_dec_rval_t
 SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	void **struct_ptr, void *ptr, size_t size, int tag_mode) {
 	/*
@@ -81,7 +81,7 @@ SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	asn_struct_ctx_t *ctx;	/* Decoder context */
 
 	ber_tlv_tag_t tlv_tag;	/* T from TLV */
-	ber_dec_rval_t rval;	/* Return code from subparsers */
+	asn_dec_rval_t rval;	/* Return code from subparsers */
 
 	ssize_t consumed_myself = 0;	/* Consumed bytes from ptr */
 
@@ -495,7 +495,8 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	asn_TYPE_member_t *element = td->elements;
 	A_SET_OF(void) *list;
 	const char *mname = specs->as_XMLValueList
-		? 0 : ((*element->name) ? element->name : element->type->name);
+		? 0 : ((*element->name)
+			? element->name : element->type->xml_tag);
 	size_t mlen = mname ? strlen(mname) : 0;
 	int xcan = (flags & XER_F_CANONICAL);
 	xer_tmp_enc_t *encs = 0;
diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h
index 7e3254ed..79bd0a26 100644
--- a/skeletons/constr_TYPE.h
+++ b/skeletons/constr_TYPE.h
@@ -8,8 +8,8 @@
  * This structure even contains pointer to these encoding and decoding routines
  * for each defined ASN.1 type.
  */
-#ifndef	_CONSTR_TYPE_H
-#define	_CONSTR_TYPE_H
+#ifndef	_CONSTR_TYPE_H_
+#define	_CONSTR_TYPE_H_
 
 #include <ber_tlv_length.h>
 #include <ber_tlv_tag.h>
@@ -29,58 +29,11 @@ typedef struct asn_struct_ctx_s {
 	void *ptr;		/* Decoder-specific stuff (stack elements) */
 } asn_struct_ctx_t;
 
-/*
- * This structure defines a context that may be passed to every ASN.1 encoder
- * or decoder function.
- * WARNING: if max_stack_size member is set, and you are calling the
- * function pointers of the asn_TYPE_descriptor_t directly,
- * this structure must be ALLOCATED ON THE STACK!
- */
-typedef struct asn_codec_ctx_s {
-	/*
-	 * Limit the decoder routines to use no (much) more stack than a given
-	 * number of bytes. Most of decoders are stack-based, and this
-	 * would protect against stack overflows if the number of nested
-	 * encodings is high.
-	 * The OCTET STRING, BIT STRING and ANY BER decoders are heap-based,
-	 * and are safe from this kind of overflow.
-	 * A value from getrlimit(RLIMIT_STACK) may be used to initialize
-	 * this variable. Be careful in multithreaded environments, as the
-	 * stack size is rather limited.
-	 */
-	size_t  max_stack_size; /* 0 disables stack bounds checking */
-} asn_codec_ctx_t;
-
-/*
- * Type of the return value of the encoding functions (der_encode, xer_encode).
- */
-typedef struct asn_enc_rval_s {
-	/*
-	 * Number of bytes encoded.
-	 * -1 indicates failure to encode the structure.
-	 * In this case, the members below this one are meaningful.
-	 */
-	ssize_t encoded;
-
-	/*
-	 * Members meaningful when (encoded == -1), for post mortem analysis.
-	 */
-
-	/* Type which cannot be encoded */
-	struct asn_TYPE_descriptor_s *failed_type;
-
-	/* Pointer to the structure of that type */
-	void *structure_ptr;
-} asn_enc_rval_t;
-#define	_ASN_ENCODE_FAILED do {					\
-	asn_enc_rval_t __er = { -1, td, sptr };			\
-	return __er;						\
-} while(0)
-
-#include <ber_decoder.h>
-#include <der_encoder.h>
-#include <xer_encoder.h>
-#include <constraints.h>
+#include <ber_decoder.h>	/* Basic Encoding Rules decoder */
+#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 <constraints.h>	/* Subtype constraints support */
 
 /*
  * Free the structure according to its specification.
@@ -119,7 +72,8 @@ asn_outmost_tag_f asn_TYPE_outmost_tag;
  * The definitive description of the destination language's structure.
  */
 typedef struct asn_TYPE_descriptor_s {
-	char *name;	/* A name of the ASN.1 type */
+	char *name;	/* A name of the ASN.1 type. "" in some cases. */
+	char *xml_tag;	/* Name used in XML tag */
 
 	/*
 	 * Generalized functions for dealing with the specific type.
@@ -128,9 +82,9 @@ typedef struct asn_TYPE_descriptor_s {
 	asn_struct_free_f  *free_struct;	/* Free the structure */
 	asn_struct_print_f *print_struct;	/* Human readable output */
 	asn_constr_check_f *check_constraints;	/* Constraints validator */
-	ber_type_decoder_f *ber_decoder;	/* Free-form BER decoder */
+	ber_type_decoder_f *ber_decoder;	/* Generic BER decoder */
 	der_type_encoder_f *der_encoder;	/* Canonical DER encoder */
-	int (*xer_decoder);/* PLACEHOLDER */ /* Free-form XER decoder */
+	xer_type_decoder_f *xer_decoder;	/* Generic XER decoder */
 	xer_type_encoder_f *xer_encoder;	/* [Canonical] XER encoder */
 
 	/***********************************************************************
diff --git a/skeletons/constraints.h b/skeletons/constraints.h
index 07eb8362..d8434e4e 100644
--- a/skeletons/constraints.h
+++ b/skeletons/constraints.h
@@ -5,7 +5,7 @@
 #ifndef	_ASN1_CONSTRAINTS_VALIDATOR_H_
 #define	_ASN1_CONSTRAINTS_VALIDATOR_H_
 
-#include <asn_types.h>	/* System-dependent types */
+#include <asn_system.h>		/* Platform-dependent types */
 
 struct asn_TYPE_descriptor_s;		/* Forward declaration */
 
diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies
index 6b7ac697..a95d98bf 100644
--- a/skeletons/file-dependencies
+++ b/skeletons/file-dependencies
@@ -44,7 +44,8 @@ constr_SET_OF.h constr_SET_OF.c asn_SET_OF.h
 COMMON-FILES:	# This is a special section
 asn_application.h
 asn_internal.h
-asn_types.h
+asn_codecs.h
+asn_system.h			# Platform-dependent types
 OCTET_STRING.h OCTET_STRING.c	# This one is used too widely
 BIT_STRING.h BIT_STRING.c	# This one is necessary for the above one
 ber_decoder.h ber_decoder.c
@@ -54,4 +55,5 @@ ber_tlv_tag.h ber_tlv_tag.c
 constr_TYPE.h constr_TYPE.c
 constraints.h constraints.c
 der_encoder.h der_encoder.c
+xer_decoder.h xer_decoder.c xer_support.h xer_support.c	# XER/XML decoding
 xer_encoder.h xer_encoder.c
diff --git a/skeletons/tests/Makefile.am b/skeletons/tests/Makefile.am
index a58e469c..c374438d 100644
--- a/skeletons/tests/Makefile.am
+++ b/skeletons/tests/Makefile.am
@@ -5,10 +5,12 @@ check_PROGRAMS = \
 	check-length		\
 	check-OIDs		\
 	check-GeneralizedTime	\
+	check-OCTET_STRING	\
 	check-UTF8String	\
 	check-UTCTime		\
 	check-INTEGER		\
-	check-REAL
+	check-REAL		\
+	check-XER
 
 LDADD = -lm
 
diff --git a/skeletons/tests/Makefile.in b/skeletons/tests/Makefile.in
index 835df71e..f5a3c689 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-OIDs.c check-REAL.c check-UTCTime.c check-UTF8String.c check-ber_tlv_tag.c check-length.c
+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
 
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
@@ -38,8 +38,9 @@ POST_UNINSTALL = :
 host_triplet = @host@
 check_PROGRAMS = check-ber_tlv_tag$(EXEEXT) check-length$(EXEEXT) \
 	check-OIDs$(EXEEXT) check-GeneralizedTime$(EXEEXT) \
-	check-UTF8String$(EXEEXT) check-UTCTime$(EXEEXT) \
-	check-INTEGER$(EXEEXT) check-REAL$(EXEEXT)
+	check-OCTET_STRING$(EXEEXT) check-UTF8String$(EXEEXT) \
+	check-UTCTime$(EXEEXT) check-INTEGER$(EXEEXT) \
+	check-REAL$(EXEEXT) check-XER$(EXEEXT)
 subdir = skeletons/tests
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -57,6 +58,10 @@ check_INTEGER_SOURCES = check-INTEGER.c
 check_INTEGER_OBJECTS = check-INTEGER.$(OBJEXT)
 check_INTEGER_LDADD = $(LDADD)
 check_INTEGER_DEPENDENCIES =
+check_OCTET_STRING_SOURCES = check-OCTET_STRING.c
+check_OCTET_STRING_OBJECTS = check-OCTET_STRING.$(OBJEXT)
+check_OCTET_STRING_LDADD = $(LDADD)
+check_OCTET_STRING_DEPENDENCIES =
 check_OIDs_SOURCES = check-OIDs.c
 check_OIDs_OBJECTS = check-OIDs.$(OBJEXT)
 check_OIDs_LDADD = $(LDADD)
@@ -73,6 +78,10 @@ check_UTF8String_SOURCES = check-UTF8String.c
 check_UTF8String_OBJECTS = check-UTF8String.$(OBJEXT)
 check_UTF8String_LDADD = $(LDADD)
 check_UTF8String_DEPENDENCIES =
+check_XER_SOURCES = check-XER.c
+check_XER_OBJECTS = check-XER.$(OBJEXT)
+check_XER_LDADD = $(LDADD)
+check_XER_DEPENDENCIES =
 check_ber_tlv_tag_SOURCES = check-ber_tlv_tag.c
 check_ber_tlv_tag_OBJECTS = check-ber_tlv_tag.$(OBJEXT)
 check_ber_tlv_tag_LDADD = $(LDADD)
@@ -86,10 +95,12 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
 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-REAL.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/check-UTCTime.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/check-UTF8String.Po \
+@AMDEP_TRUE@	./$(DEPDIR)/check-XER.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/check-ber_tlv_tag.Po \
 @AMDEP_TRUE@	./$(DEPDIR)/check-length.Po
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -100,12 +111,13 @@ LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \
 CCLD = $(CC)
 LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OIDs.c \
-	check-REAL.c check-UTCTime.c check-UTF8String.c \
-	check-ber_tlv_tag.c check-length.c
-DIST_SOURCES = check-GeneralizedTime.c check-INTEGER.c check-OIDs.c \
-	check-REAL.c check-UTCTime.c check-UTF8String.c \
-	check-ber_tlv_tag.c check-length.c
+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-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)
@@ -267,6 +279,9 @@ check-GeneralizedTime$(EXEEXT): $(check_GeneralizedTime_OBJECTS) $(check_General
 check-INTEGER$(EXEEXT): $(check_INTEGER_OBJECTS) $(check_INTEGER_DEPENDENCIES) 
 	@rm -f check-INTEGER$(EXEEXT)
 	$(LINK) $(check_INTEGER_LDFLAGS) $(check_INTEGER_OBJECTS) $(check_INTEGER_LDADD) $(LIBS)
+check-OCTET_STRING$(EXEEXT): $(check_OCTET_STRING_OBJECTS) $(check_OCTET_STRING_DEPENDENCIES) 
+	@rm -f check-OCTET_STRING$(EXEEXT)
+	$(LINK) $(check_OCTET_STRING_LDFLAGS) $(check_OCTET_STRING_OBJECTS) $(check_OCTET_STRING_LDADD) $(LIBS)
 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)
@@ -279,6 +294,9 @@ check-UTCTime$(EXEEXT): $(check_UTCTime_OBJECTS) $(check_UTCTime_DEPENDENCIES)
 check-UTF8String$(EXEEXT): $(check_UTF8String_OBJECTS) $(check_UTF8String_DEPENDENCIES) 
 	@rm -f check-UTF8String$(EXEEXT)
 	$(LINK) $(check_UTF8String_LDFLAGS) $(check_UTF8String_OBJECTS) $(check_UTF8String_LDADD) $(LIBS)
+check-XER$(EXEEXT): $(check_XER_OBJECTS) $(check_XER_DEPENDENCIES) 
+	@rm -f check-XER$(EXEEXT)
+	$(LINK) $(check_XER_LDFLAGS) $(check_XER_OBJECTS) $(check_XER_LDADD) $(LIBS)
 check-ber_tlv_tag$(EXEEXT): $(check_ber_tlv_tag_OBJECTS) $(check_ber_tlv_tag_DEPENDENCIES) 
 	@rm -f check-ber_tlv_tag$(EXEEXT)
 	$(LINK) $(check_ber_tlv_tag_LDFLAGS) $(check_ber_tlv_tag_OBJECTS) $(check_ber_tlv_tag_LDADD) $(LIBS)
@@ -294,10 +312,12 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-GeneralizedTime.Po@am__quote@
 @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-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@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-XER.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-ber_tlv_tag.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check-length.Po@am__quote@
 
diff --git a/skeletons/tests/check-GeneralizedTime.c b/skeletons/tests/check-GeneralizedTime.c
index 0cec17d1..ff20772b 100644
--- a/skeletons/tests/check-GeneralizedTime.c
+++ b/skeletons/tests/check-GeneralizedTime.c
@@ -116,7 +116,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *ptr, int tag_mode, ber_
 }
 
 asn_enc_rval_t
-OCTET_STRING_encode_xer_ascii(asn_TYPE_descriptor_t *td, void *ptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) {
+OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *ptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) {
 	asn_enc_rval_t erval;
 
 	(void)td;
diff --git a/skeletons/tests/check-OIDs.c b/skeletons/tests/check-OIDs.c
index 0cd4d140..436e0132 100644
--- a/skeletons/tests/check-OIDs.c
+++ b/skeletons/tests/check-OIDs.c
@@ -19,7 +19,7 @@ _print(const void *buffer, size_t size, void *app_key) {
 static void
 check_OID(uint8_t *buf, size_t len, int *ck_buf, int ck_len) {
 	OBJECT_IDENTIFIER_t *oid;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	unsigned long arcs[10];
 	int alen;
 	int i;
@@ -66,7 +66,7 @@ check_OID(uint8_t *buf, size_t len, int *ck_buf, int ck_len) {
 static void
 check_ROID(uint8_t *buf, size_t len, int *ck_buf, int ck_len) {
 	RELATIVE_OID_t *oid;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	unsigned long arcs[10];
 	int alen;
 	int i;
diff --git a/skeletons/tests/check-UTCTime.c b/skeletons/tests/check-UTCTime.c
index 6762865f..4c76858b 100644
--- a/skeletons/tests/check-UTCTime.c
+++ b/skeletons/tests/check-UTCTime.c
@@ -79,7 +79,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *ptr, int tag_mode, ber_
 }
 
 asn_enc_rval_t
-OCTET_STRING_encode_xer_ascii(asn_TYPE_descriptor_t *td, void *ptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) {
+OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *ptr, int ilevel, enum xer_encoder_flags_e flags, asn_app_consume_bytes_f *cb, void *app_key) {
 	asn_enc_rval_t erval;
 
 	(void)td;
diff --git a/skeletons/tests/check-UTF8String.c b/skeletons/tests/check-UTF8String.c
index 14979219..ae368eab 100644
--- a/skeletons/tests/check-UTF8String.c
+++ b/skeletons/tests/check-UTF8String.c
@@ -4,6 +4,8 @@
 #include <ber_tlv_length.c>
 #include <ber_tlv_tag.c>
 #include <der_encoder.c>
+#include <xer_decoder.c>
+#include <xer_support.c>
 #include <constraints.c>
 #include <sys/time.h>
 
diff --git a/skeletons/tests/check-length.c b/skeletons/tests/check-length.c
index d76902de..80064d50 100644
--- a/skeletons/tests/check-length.c
+++ b/skeletons/tests/check-length.c
@@ -2,6 +2,8 @@
 #include <ber_tlv_length.c>
 #include <ber_tlv_tag.c>
 #include <der_encoder.c>
+#include <xer_decoder.c>
+#include <xer_support.c>
 #include <constraints.c>
 #undef	ADVANCE
 #undef	RETURN
@@ -37,7 +39,7 @@ check(int size) {
 	OCTET_STRING_t *os;
 	OCTET_STRING_t *nos = 0;
 	asn_enc_rval_t erval;
-	ber_dec_rval_t rval;
+	asn_dec_rval_t rval;
 	int i;
 
 	os = OCTET_STRING_new_fromBuf(&asn_DEF_OCTET_STRING, 0, size);
diff --git a/skeletons/xer_decoder.c b/skeletons/xer_decoder.c
new file mode 100644
index 00000000..39e830d0
--- /dev/null
+++ b/skeletons/xer_decoder.c
@@ -0,0 +1,288 @@
+
+#include <asn_application.h>
+#include <asn_internal.h>
+#include <xer_support.h>		/* XER/XML parsing support */
+#include <assert.h>
+
+
+/*
+ * Decode the XER encoding of a given type.
+ */
+asn_dec_rval_t
+xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+		void **struct_ptr, void *buffer, size_t size) {
+	asn_codec_ctx_t s_codec_ctx;
+
+	/*
+	 * Satisfy the requirement that the codec context
+	 * must be allocated on the stack.
+	 */
+	if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
+		s_codec_ctx = *opt_codec_ctx;
+		opt_codec_ctx = &s_codec_ctx;
+	}
+
+	/*
+	 * Invoke type-specific decoder.
+	 */
+	return td->xer_decoder(opt_codec_ctx, td, struct_ptr, 0, buffer, size);
+}
+
+
+
+struct xer__cb_arg {
+	pxml_chunk_type_e	chunk_type;
+	size_t			chunk_size;
+	void			*chunk_buf;
+	int callback_not_invoked;
+};
+
+static int
+xer__token_cb(pxml_chunk_type_e type, void *_chunk_data, size_t _chunk_size, void *key) {
+	struct xer__cb_arg *arg = (struct xer__cb_arg *)key;
+	arg->chunk_type = type;
+	arg->chunk_size = _chunk_size;
+	arg->chunk_buf = _chunk_data;
+	arg->callback_not_invoked = 0;
+	return -1;	/* Terminate the XML parsing */
+}
+
+/*
+ * Fetch the next token from the XER/XML stream.
+ */
+ssize_t
+xer_next_token(int *stateContext, void *buffer, size_t size,
+		pxer_chunk_type_e *ch_type) {
+	struct xer__cb_arg arg;
+	ssize_t ret;
+
+	arg.callback_not_invoked = 1;
+	ret = pxml_parse(stateContext, buffer, size, xer__token_cb, &arg);
+	if(ret < 0) return -1;
+	if(arg.callback_not_invoked) {
+		assert(ret == 0);	/* No data was consumed */
+		return 0;		/* Try again with more data */
+	} else {
+		assert(arg.chunk_size);
+		assert(arg.chunk_buf == buffer);
+	}
+
+	/*
+	 * Translate the XML chunk types into more convenient ones.
+	 */
+	switch(arg.chunk_type) {
+	case PXML_TEXT:
+		*ch_type = PXER_TEXT;
+		break;
+	case PXML_TAG: return 0;	/* Want more */
+	case PXML_TAG_END:
+		*ch_type = PXER_TAG;
+		break;
+	case PXML_COMMENT:
+	case PXML_COMMENT_END:
+		*ch_type = PXER_COMMENT;
+		break;
+	}
+
+	return arg.chunk_size;
+}
+
+#define	CSLASH	0x2f	/* '/' */
+#define	LANGLE	0x3c	/* '<' */
+#define	RANGLE	0x3e	/* '>' */
+
+xer_check_tag_e
+xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
+	const char *buf = (const char *)buf_ptr;
+	const char *end;
+	xer_check_tag_e ct = XCT_OPENING;
+
+	if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
+		return XCT_BROKEN;
+	}
+
+	/*
+	 * Determine the tag class.
+	 */
+	if(buf[1] == CSLASH) {
+		buf += 2;	/* advance past "</" */
+		size -= 3;	/* strip "</" and ">" */
+		ct = XCT_CLOSING;
+		if(size > 0 && buf[size-1] == CSLASH)
+			return XCT_BROKEN;	/* </abc/> */
+	} else {
+		buf++;		/* advance past "<" */
+		size -= 2;	/* strip "<" and ">" */
+		if(size > 0 && buf[size-1] == CSLASH) {
+			ct = XCT_BOTH;
+			size--;	/* One more, for "/" */
+		}
+	}
+
+	/*
+	 * Determine the tag name.
+	 */
+	for(end = buf + size; buf < end; buf++, need_tag++) {
+		int b = *buf, n = *need_tag;
+		if(b != n) {
+			if(n == 0) {
+				switch(b) {
+				case 0x09: case 0x0a: case 0x0c: case 0x0d:
+				case 0x20:
+					/* "<abc def/>": whitespace is normal */
+					return ct;
+				}
+			}
+			return XCT_UNEXPECTED;
+		}
+		if(b == 0)
+			return XCT_BROKEN;	/* Embedded 0 in buf?! */
+	}
+	if(*need_tag) return XCT_UNEXPECTED;
+
+	return ct;
+}
+
+
+#undef	ADVANCE
+#define	ADVANCE(num_bytes)	do {				\
+		size_t num = (num_bytes);			\
+		buf_ptr = ((char *)buf_ptr) + num;		\
+		size -= num;					\
+		consumed_myself += num;				\
+	} while(0)
+
+#undef	RETURN
+#define	RETURN(_code)	do {					\
+		rval.code = _code;				\
+		rval.consumed = consumed_myself;		\
+		return rval;					\
+	} while(0)
+
+#define	XER_GOT_BODY(chunk_buf, chunk_size)	do {		\
+		ssize_t converted_size = body_receiver		\
+			(struct_ptr, chunk_buf, chunk_size,	\
+				(size_t)chunk_size < size);	\
+		if(converted_size == -1) RETURN(RC_FAIL);	\
+		chunk_size = converted_size;			\
+	} while(0)
+#define	XER_GOT_EMPTY()	do {					\
+		ssize_t chunk_size = 0;				\
+		XER_GOT_BODY(0, chunk_size);			\
+	} while(0)
+
+/*
+ * Generalized function for decoding the primitive values.
+ */
+asn_dec_rval_t
+xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
+	asn_struct_ctx_t *ctx,	/* Type decoder context */
+	void *struct_ptr,	/* The structure must be already allocated */
+	const char *xml_tag,	/* Expected XML tag */
+	void *buf_ptr, size_t size,
+	int (*opt_unexpected_tag_decoder)
+		(void *struct_ptr, void *chunk_buf, size_t chunk_size),
+	ssize_t (*body_receiver)
+		(void *struct_ptr, void *chunk_buf, size_t chunk_size,
+			int have_more)
+	) {
+
+	asn_dec_rval_t rval;
+	ssize_t consumed_myself = 0;
+	pxer_chunk_type_e ch_type;	/* XER chunk type */
+	int xer_state;			/* XER low level parsing context */
+
+	(void)opt_codec_ctx;
+
+	/*
+	 * Phases of XER/XML processing:
+	 * Phase 0: Check that the opening tag matches our expectations.
+	 * Phase 1: Processing body and reacting on closing tag.
+	 */
+	if(ctx->phase > 1) RETURN(RC_FAIL);
+	for(xer_state = ctx->step;;) {
+		ssize_t ch_size;	/* Chunk size */
+		xer_check_tag_e tcv;	/* Tag check value */
+
+		/*
+		 * Get the next part of the XML stream.
+		 */
+		ch_size = xer_next_token(&xer_state, buf_ptr, size, &ch_type);
+		switch(ch_size) {
+		case -1: RETURN(RC_FAIL);
+		case 0:
+			ctx->step = xer_state;
+			RETURN(RC_WMORE);
+		default:
+			switch(ch_type) {
+			case PXER_COMMENT:		/* Got XML comment */
+				ADVANCE(ch_size);	/* Skip silently */
+				continue;
+			case PXER_TEXT:
+				if(ctx->phase == 0) {
+					/* Unexpected data */
+					/* TODO: ignore whitespace? */
+					RETURN(RC_FAIL);
+				}
+				XER_GOT_BODY(buf_ptr, ch_size);
+				ADVANCE(ch_size);
+				continue;
+			case PXER_TAG:
+				break;	/* Check the rest down there */
+			}
+		}
+
+		assert(ch_type == PXER_TAG && size);
+
+		tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
+		if(ctx->phase == 0) {
+			/*
+			 * Expecting the opening tag
+			 * for the type being processed.
+			 */
+			switch(tcv) {
+			case XCT_BOTH:
+				/* Finished decoding of an empty element */
+				XER_GOT_EMPTY();
+				ADVANCE(ch_size);
+				ctx->phase = 2;	/* Phase out */
+				RETURN(RC_OK);
+			case XCT_OPENING:
+				ADVANCE(ch_size);
+				ctx->phase = 1;	/* Processing body phase */
+				continue;
+			default:
+				break;		/* Unexpected tag */
+			}
+		} else {
+			/*
+			 * Waiting for the closing XML tag.
+			 */
+			switch(tcv) {
+			case XCT_CLOSING:
+				ADVANCE(ch_size);
+				ctx->phase = 2;	/* Phase out */
+				RETURN(RC_OK);
+			case XCT_UNEXPECTED:
+				/*
+				 * Certain tags in the body may be expected.
+				 */
+				if(opt_unexpected_tag_decoder
+				&& opt_unexpected_tag_decoder(struct_ptr,
+						buf_ptr, ch_size) == 0) {
+					/* Tag's processed fine */
+					ADVANCE(ch_size);
+					continue;
+				}
+				/* Fall through */
+			default:
+				break;
+			}
+			ASN_DEBUG("Unexpected XML tag");
+		}
+		break;	/* Dark and mysterious things have just happened */
+	}
+
+	RETURN(RC_FAIL);
+}
+
diff --git a/skeletons/xer_decoder.h b/skeletons/xer_decoder.h
new file mode 100644
index 00000000..e258b5b8
--- /dev/null
+++ b/skeletons/xer_decoder.h
@@ -0,0 +1,82 @@
+/*-
+ * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef	_XER_DECODER_H_
+#define	_XER_DECODER_H_
+
+#include <asn_application.h>
+
+struct asn_TYPE_descriptor_s;	/* Forward declaration */
+
+/*
+ * The XER decoder of any type. May be invoked by the application.
+ */
+asn_dec_rval_t xer_decode(struct asn_codec_ctx_s *opt_codec_ctx,
+	struct asn_TYPE_descriptor_s *type_descriptor,
+	void **struct_ptr,	/* Pointer to a target structure's pointer */
+	void *buffer,		/* Data to be decoded */
+	size_t size		/* Size of that buffer */
+	);
+
+/*
+ * Type of the type-specific XER decoder function.
+ */
+typedef asn_dec_rval_t (xer_type_decoder_f)(asn_codec_ctx_t *opt_codec_ctx,
+		struct asn_TYPE_descriptor_s *type_descriptor,
+		void **struct_ptr,
+		const char *opt_mname,	/* Member name */
+		void *buf_ptr, size_t size
+	);
+
+/*******************************
+ * INTERNALLY USEFUL FUNCTIONS *
+ *******************************/
+
+/*
+ * Generalized function for decoding the primitive values.
+ * Used by more specialized functions, such as OCTET_STRING_decode_xer_utf8
+ * and others. This function should not be used by applications, as its API
+ * is subject to changes.
+ */
+asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
+	asn_struct_ctx_t *ctx,	/* Type decoder context */
+	void *struct_ptr,	/* The structure must be already allocated */
+	const char *xml_tag,	/* Expected XML tag name */
+	void *buf_ptr, size_t size,
+	int (*opt_unexpected_tag_decoder)
+		(void *struct_ptr, void *chunk_buf, size_t chunk_size),
+	ssize_t (*body_receiver)
+		(void *struct_ptr, void *chunk_buf, size_t chunk_size,
+			int have_more)
+	);
+
+
+/*
+ * Fetch the next XER (XML) token from the stream.
+ * The function returns the number of bytes occupied by the chunk type,
+ * returned in the _ch_type. The _ch_type is only set (and valid) when
+ * the return value is greater than 0.
+ */
+  typedef enum pxer_chunk_type {
+	PXER_TAG,	/* Complete XER tag */
+	PXER_TEXT,	/* Plain text between XER tags */
+	PXER_COMMENT,	/* A comment, may be part of */
+  } pxer_chunk_type_e;
+ssize_t xer_next_token(int *stateContext, void *buffer, size_t size,
+	pxer_chunk_type_e *_ch_type);
+
+/*
+ * This function checks the buffer against the tag name is expected to occur.
+ */
+  typedef enum xer_check_tag {
+	XCT_BROKEN,	/* The tag is broken */
+	XCT_UNEXPECTED,	/* The tag is fine, but unexpected */
+	XCT_OPENING,	/* This is the opening <tag> */
+	XCT_CLOSING,	/* This is the closing </tag> */
+	XCT_BOTH,	/* This is the opening and closing tag <tag/> */
+  } xer_check_tag_e;
+xer_check_tag_e xer_check_tag(const void *buf_ptr, int size,
+		const char *need_tag);
+
+#endif	/* _XER_DECODER_H_ */
diff --git a/skeletons/xer_encoder.c b/skeletons/xer_encoder.c
index d3f04d66..5fb0de68 100644
--- a/skeletons/xer_encoder.c
+++ b/skeletons/xer_encoder.c
@@ -21,7 +21,7 @@ xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
 
 	if(!td || !sptr) goto cb_failed;
 
-	mname = td->name;
+	mname = td->xml_tag;
 	mlen = strlen(mname);
 
 	_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
diff --git a/skeletons/xer_support.c b/skeletons/xer_support.c
new file mode 100644
index 00000000..1fe59bc9
--- /dev/null
+++ b/skeletons/xer_support.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#include <xer_support.h>
+
+/* Parser states */
+typedef enum {
+	ST_TEXT,
+	ST_TAG_START,
+	ST_TAG_BODY,
+	ST_TAG_QUOTE_WAIT,
+	ST_TAG_QUOTED_STRING,
+	ST_TAG_UNQUOTED_STRING,
+	ST_COMMENT_WAIT_DASH1,	// "<!--"[1]
+	ST_COMMENT_WAIT_DASH2,	// "<!--"[2]
+	ST_COMMENT,
+	ST_COMMENT_CLO_DASH2,	// "-->"[0]
+	ST_COMMENT_CLO_RT	// "-->"[1]
+} pstate_e;
+
+static pxml_chunk_type_e final_chunk_type[] = {
+	PXML_TEXT,
+	PXML_TAG_END,
+	PXML_COMMENT_END,
+	PXML_TAG_END,
+	PXML_COMMENT_END,
+};
+
+
+static int
+_charclass[256] = {
+	0,0,0,0,0,0,0,0, 0,1,1,0,1,1,0,0,
+	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+	1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
+	2,2,2,2,2,2,2,2, 2,2,0,0,0,0,0,0,	/* 01234567 89       */
+	0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,	/*  ABCDEFG HIJKLMNO */
+	3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0,	/* PQRSTUVW XYZ      */
+	0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,	/*  abcdefg hijklmno */
+	3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0	/* pqrstuvw xyz      */
+};
+#define WHITESPACE(c)	(_charclass[(unsigned char)(c)] == 1)
+#define ALNUM(c)	(_charclass[(unsigned char)(c)] >= 2)
+#define ALPHA(c)	(_charclass[(unsigned char)(c)] == 3)
+
+/* Aliases for characters, ASCII/UTF-8 */
+#define	EXCLAM	0x21	/* '!' */
+#define	CQUOTE	0x22	/* '"' */
+#define	CDASH	0x2d	/* '-' */
+#define	CSLASH	0x2f	/* '/' */
+#define	LANGLE	0x3c	/* '<' */
+#define	CEQUAL	0x3d	/* '=' */
+#define	RANGLE	0x3e	/* '>' */
+
+/* Invoke token callback */
+#define	TOKEN_CB_CALL(type, _ns, _current_too, _final) do {	\
+		int _ret;					\
+		pstate_e ns  = _ns;				\
+		ssize_t _sz = (p - chunk_start) + _current_too;	\
+		if (!_sz) {					\
+			/* Shortcut */				\
+			state = _ns;				\
+			break;					\
+		}						\
+		_ret = cb(type, chunk_start, _sz, key);		\
+		if(_ret < _sz) {				\
+			if(_current_too && _ret == -1)		\
+				state = ns;			\
+			goto finish;				\
+		}						\
+		chunk_start = p + _current_too;			\
+		state = ns;					\
+	} while(0)
+
+#define TOKEN_CB(_type, _ns, _current_too)			\
+	TOKEN_CB_CALL(_type, _ns, _current_too, 0)
+
+#define TOKEN_CB_FINAL(_type, _ns, _current_too)		\
+	TOKEN_CB_CALL(final_chunk_type[_type], _ns, _current_too, 1)
+
+/*
+ * Parser itself
+ */
+int pxml_parse(int *stateContext, void *xmlbuf, size_t size, pxml_callback_f *cb, void *key) {
+	pstate_e state = (pstate_e)*stateContext;
+	char *chunk_start = (char *)xmlbuf;
+	char *p = chunk_start;
+	char *end = p + size;
+
+	for(; p < end; p++) {
+	  int C = *(unsigned char *)p;
+	  switch(state) {
+	  case ST_TEXT:
+		/*
+		 * Initial state: we're in the middle of some text,
+		 * or just have started.
+		 */
+		if (C == LANGLE) 
+			/* We're now in the tag, probably */
+			TOKEN_CB(PXML_TEXT, ST_TAG_START, 0);
+		break;
+	  case ST_TAG_START:
+		if (ALPHA(C) || (C == CSLASH))
+			state = ST_TAG_BODY;
+		else if (C == EXCLAM)
+			state = ST_COMMENT_WAIT_DASH1;
+		else 
+			/*
+			 * Not characters and not whitespace.
+			 * Must be something like "3 < 4".
+			 */
+			TOKEN_CB(PXML_TEXT, ST_TEXT, 1);/* Flush as data */
+		break;
+	  case ST_TAG_BODY:
+		switch(C) {
+		case RANGLE:
+			/* End of the tag */
+			TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
+			break;
+		case LANGLE:
+			/*
+			 * The previous tag wasn't completed, but still
+			 * recognized as valid. (Mozilla-compatible)
+			 */
+			TOKEN_CB_FINAL(PXML_TAG, ST_TAG_START, 0);	
+			break;
+		case CEQUAL:
+			state = ST_TAG_QUOTE_WAIT;
+			break;
+		}
+		break;
+	  case ST_TAG_QUOTE_WAIT:
+		/*
+		 * State after the equal sign ("=") in the tag.
+		 */
+		switch(C) {
+		case CQUOTE:
+			state = ST_TAG_QUOTED_STRING;
+			break;
+		case RANGLE:
+			/* End of the tag */
+			TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
+			break;
+		default:
+			if(!WHITESPACE(C))
+				/* Unquoted string value */
+				state = ST_TAG_UNQUOTED_STRING;
+		}
+		break;
+	  case ST_TAG_QUOTED_STRING:
+		/*
+		 * Tag attribute's string value in quotes.
+		 */
+		if(C == CQUOTE) {
+			/* Return back to the tag state */
+			state = ST_TAG_BODY;
+		}
+		break;
+	  case ST_TAG_UNQUOTED_STRING:
+		if(C == RANGLE) {
+			/* End of the tag */
+			TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
+		} else if(WHITESPACE(C)) {
+			/* Return back to the tag state */
+			state = ST_TAG_BODY;
+		}
+		break;
+	  case ST_COMMENT_WAIT_DASH1:
+		if(C == CDASH) {
+			state = ST_COMMENT_WAIT_DASH2;
+		} else {
+			/* Some ordinary tag. */
+			state = ST_TAG_BODY;
+		}
+		break;
+	  case ST_COMMENT_WAIT_DASH2:
+		if(C == CDASH) {
+			/* Seen "<--" */
+			state = ST_COMMENT;
+		} else {
+			/* Some ordinary tag */
+			state = ST_TAG_BODY;
+		}
+		break;
+	  case ST_COMMENT:
+		if(C == CDASH) {
+			state = ST_COMMENT_CLO_DASH2;
+		}
+		break;
+	  case ST_COMMENT_CLO_DASH2:
+		if(C == CDASH) {
+			state = ST_COMMENT_CLO_RT;
+		} else {
+			/* This is not an end of a comment */
+			state = ST_COMMENT;
+		}
+		break;
+	  case ST_COMMENT_CLO_RT:
+		if(C == RANGLE) {
+			TOKEN_CB_FINAL(PXML_COMMENT, ST_TEXT, 1);
+		} else {
+			state = ST_COMMENT;
+		}
+		break;
+	  } /* switch(*ptr) */
+	} /* for() */
+
+	/*
+	 * Flush the partially processed chunk, state permitting.
+	 */
+	if(p - chunk_start) {
+		switch (state) {
+		case ST_COMMENT:
+			TOKEN_CB(PXML_COMMENT, state, 0);
+			break;
+		case ST_TEXT:
+			TOKEN_CB(PXML_TEXT, state, 0);
+			break;
+		default: break;	/* a no-op */
+		}
+	}
+
+finish:
+	*stateContext = (int)state;
+	return chunk_start - (char *)xmlbuf;
+}
+
diff --git a/skeletons/xer_support.h b/skeletons/xer_support.h
new file mode 100644
index 00000000..a1a010c6
--- /dev/null
+++ b/skeletons/xer_support.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
+ * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef	_XER_SUPPORT_H_
+#define	_XER_SUPPORT_H_
+
+/*
+ * Types of data transferred to the application.
+ */
+typedef enum {
+	PXML_TEXT,	/* Plain text between XML tags. */
+	PXML_TAG,	/* A tag, starting with '<'. */
+	PXML_COMMENT,	/* An XML comment, including "<!--" and "-->". */
+	/* 
+	 * The following chunk types are reported if the chunk
+	 * terminates the specified XML element.
+	 */
+	PXML_TAG_END,		/* Tag ended */
+	PXML_COMMENT_END	/* Comment ended */
+} pxml_chunk_type_e;
+
+/*
+ * Callback function that is called by the parser when parsed data is
+ * available. The _opaque is the pointer to a field containing opaque user 
+ * data specified in pxml_create() call. The chunk type is _type and the text 
+ * data is the piece of buffer identified by _bufid (as supplied to
+ * pxml_feed() call) starting at offset _offset and of _size bytes size. 
+ * The chunk is NOT '\0'-terminated.
+ */
+typedef int (pxml_callback_f)(pxml_chunk_type_e _type,
+	void *_chunk_data, size_t _chunk_size, void *_key);
+
+/*
+ * Parse the given buffer as it were a chunk of XML data.
+ * Invoke the specified callback each time the meaninful data is found.
+ * This function returns number of bytes consumed from the bufer.
+ * It will always be lesser than or equal to the specified _size.
+ * The next invocation of this function must account the difference.
+ */
+ssize_t pxml_parse(int *_stateContext, void *_buf, size_t _size,
+	pxml_callback_f *cb, void *_key);
+
+#endif	/* _XER_SUPPORT_H_ */
diff --git a/tests/19-param-OK.asn1.-P b/tests/19-param-OK.asn1.-P
index 8c609e9d..0d07f8b2 100644
--- a/tests/19-param-OK.asn1.-P
+++ b/tests/19-param-OK.asn1.-P
@@ -107,6 +107,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_toBeSigned_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_toBeSigned = {
+	"toBeSigned",
 	"toBeSigned",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -167,6 +168,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_Certificate_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_Certificate = {
+	"Certificate",
 	"Certificate",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -228,6 +230,7 @@ static asn_SET_OF_specifics_t asn_DEF_Name_specs = {
 	0,	/* XER encoding is XMLDelimitedItemList */
 };
 asn_TYPE_descriptor_t asn_DEF_Name = {
+	"Name",
 	"Name",
 	SEQUENCE_OF_free,
 	SEQUENCE_OF_print,
@@ -344,6 +347,7 @@ static asn_SET_OF_specifics_t asn_DEF_RelativeDistinguishedName_specs = {
 	0,	/* XER encoding is XMLDelimitedItemList */
 };
 asn_TYPE_descriptor_t asn_DEF_RelativeDistinguishedName = {
+	"RelativeDistinguishedName",
 	"RelativeDistinguishedName",
 	SET_OF_free,
 	SET_OF_print,
diff --git a/tests/30-set-OK.asn1.-P b/tests/30-set-OK.asn1.-P
index 1ffd9b4b..f944af73 100644
--- a/tests/30-set-OK.asn1.-P
+++ b/tests/30-set-OK.asn1.-P
@@ -87,6 +87,7 @@ static asn_SET_specifics_t asn_DEF_T_specs = {
 	(unsigned int *)asn_DEF_T_mmap	/* Mandatory elements map */
 };
 asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
 	"T",
 	SET_free,
 	SET_print,
diff --git a/tests/31-set-of-OK.asn1.-P b/tests/31-set-of-OK.asn1.-P
index 143ab8c6..c245bf88 100644
--- a/tests/31-set-of-OK.asn1.-P
+++ b/tests/31-set-of-OK.asn1.-P
@@ -39,6 +39,7 @@ static asn_SET_OF_specifics_t asn_DEF_Forest_specs = {
 	0,	/* XER encoding is XMLDelimitedItemList */
 };
 asn_TYPE_descriptor_t asn_DEF_Forest = {
+	"Forest",
 	"Forest",
 	SET_OF_free,
 	SET_OF_print,
@@ -114,6 +115,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_Tree_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_Tree = {
+	"Tree",
 	"Tree",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -234,6 +236,7 @@ static asn_SET_OF_specifics_t asn_DEF_trees_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_trees = {
+	"trees",
 	"trees",
 	SET_OF_free,
 	SET_OF_print,
@@ -279,6 +282,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_anything_member_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_anything_member = {
+	"",
 	"",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -319,6 +323,7 @@ static asn_SET_OF_specifics_t asn_DEF_anything_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_anything = {
+	"anything",
 	"anything",
 	SET_OF_free,
 	SET_OF_print,
@@ -370,6 +375,7 @@ static asn_CHOICE_specifics_t asn_DEF_other_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_other = {
+	"other",
 	"other",
 	CHOICE_free,
 	CHOICE_print,
@@ -440,6 +446,7 @@ static asn_SET_specifics_t asn_DEF_Stuff_specs = {
 	(unsigned int *)asn_DEF_Stuff_mmap	/* Mandatory elements map */
 };
 asn_TYPE_descriptor_t asn_DEF_Stuff = {
+	"Stuff",
 	"Stuff",
 	SET_free,
 	SET_print,
diff --git a/tests/32-sequence-of-OK.asn1.-P b/tests/32-sequence-of-OK.asn1.-P
index 508eb051..5c2c9b29 100644
--- a/tests/32-sequence-of-OK.asn1.-P
+++ b/tests/32-sequence-of-OK.asn1.-P
@@ -39,6 +39,7 @@ static asn_SET_OF_specifics_t asn_DEF_Programming_specs = {
 	0,	/* XER encoding is XMLDelimitedItemList */
 };
 asn_TYPE_descriptor_t asn_DEF_Programming = {
+	"Programming",
 	"Programming",
 	SEQUENCE_OF_free,
 	SEQUENCE_OF_print,
@@ -100,6 +101,7 @@ static asn_SET_OF_specifics_t asn_DEF_Fault_specs = {
 	0,	/* XER encoding is XMLDelimitedItemList */
 };
 asn_TYPE_descriptor_t asn_DEF_Fault = {
+	"Fault",
 	"Fault",
 	SET_OF_free,
 	SET_OF_print,
@@ -158,6 +160,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_Error_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_Error = {
+	"Error",
 	"Error",
 	SEQUENCE_free,
 	SEQUENCE_print,
diff --git a/tests/39-sequence-of-OK.asn1.-P b/tests/39-sequence-of-OK.asn1.-P
index 6ef4a4f2..1fecb6f5 100644
--- a/tests/39-sequence-of-OK.asn1.-P
+++ b/tests/39-sequence-of-OK.asn1.-P
@@ -48,6 +48,7 @@ static asn_SET_OF_specifics_t asn_DEF_collection_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_collection = {
+	"collection",
 	"collection",
 	SEQUENCE_OF_free,
 	SEQUENCE_OF_print,
@@ -100,6 +101,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_T_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
 	"T",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -176,6 +178,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_T2_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_T2 = {
+	"T2",
 	"T2",
 	SEQUENCE_free,
 	SEQUENCE_print,
diff --git a/tests/42-real-life-OK.asn1.-PR b/tests/42-real-life-OK.asn1.-PR
index 1bfd634d..951e6693 100644
--- a/tests/42-real-life-OK.asn1.-PR
+++ b/tests/42-real-life-OK.asn1.-PR
@@ -84,6 +84,7 @@ static asn_SET_OF_specifics_t asn_DEF_varsets_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_varsets = {
+	"varsets",
 	"varsets",
 	SEQUENCE_OF_free,
 	SEQUENCE_OF_print,
@@ -136,6 +137,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_LogLine_specs = {
 	3	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_LogLine = {
+	"LogLine",
 	"LogLine",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -232,6 +234,7 @@ static asn_SET_OF_specifics_t asn_DEF_vparts_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_vparts = {
+	"vparts",
 	"vparts",
 	SEQUENCE_OF_free,
 	SEQUENCE_OF_print,
@@ -284,6 +287,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_VariablePartSet_specs = {
 	3	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_VariablePartSet = {
+	"VariablePartSet",
 	"VariablePartSet",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -409,6 +413,7 @@ static asn_SET_OF_specifics_t asn_DEF_vset_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_vset = {
+	"vset",
 	"vset",
 	SET_OF_free,
 	SET_OF_print,
@@ -462,6 +467,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_vrange_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_vrange = {
+	"vrange",
 	"vrange",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -512,6 +518,7 @@ static asn_CHOICE_specifics_t asn_DEF_VariablePart_specs = {
 	1	/* Whether extensible */
 };
 asn_TYPE_descriptor_t asn_DEF_VariablePart = {
+	"VariablePart",
 	"VariablePart",
 	CHOICE_free,
 	CHOICE_print,
@@ -603,6 +610,7 @@ static asn_SET_OF_specifics_t asn_DEF_email_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_email = {
+	"email",
 	"email",
 	SET_OF_free,
 	SET_OF_print,
@@ -656,6 +664,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_notify_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_notify = {
+	"notify",
 	"notify",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -708,6 +717,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_ActionItem_specs = {
 	3	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_ActionItem = {
+	"ActionItem",
 	"ActionItem",
 	SEQUENCE_free,
 	SEQUENCE_print,
diff --git a/tests/43-recursion-OK.asn1.-P b/tests/43-recursion-OK.asn1.-P
index 7f03aad7..004e0f05 100644
--- a/tests/43-recursion-OK.asn1.-P
+++ b/tests/43-recursion-OK.asn1.-P
@@ -59,6 +59,7 @@ static asn_SET_OF_specifics_t asn_DEF_t_member1_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_t_member1 = {
+	"t-member1",
 	"t-member1",
 	SET_OF_free,
 	SET_OF_print,
@@ -98,6 +99,7 @@ static asn_SET_OF_specifics_t asn_DEF_t_member2_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_t_member2 = {
+	"t-member2",
 	"t-member2",
 	SEQUENCE_OF_free,
 	SEQUENCE_OF_print,
@@ -166,6 +168,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_Test_structure_1_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_Test_structure_1 = {
+	"Test-structure-1",
 	"Test-structure-1",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -253,6 +256,7 @@ static asn_SET_OF_specifics_t asn_DEF_or_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_or = {
+	"or",
 	"or",
 	SET_OF_free,
 	SET_OF_print,
@@ -319,6 +323,7 @@ static asn_CHOICE_specifics_t asn_DEF_Choice_1_specs = {
 	0	/* Whether extensible */
 };
 asn_TYPE_descriptor_t asn_DEF_Choice_1 = {
+	"Choice-1",
 	"Choice-1",
 	CHOICE_free,
 	CHOICE_print,
@@ -402,6 +407,7 @@ static asn_SET_specifics_t asn_DEF_Test_structure_2_specs = {
 	(unsigned int *)asn_DEF_Test_structure_2_mmap	/* Mandatory elements map */
 };
 asn_TYPE_descriptor_t asn_DEF_Test_structure_2 = {
+	"Test-structure-2",
 	"Test-structure-2",
 	SET_free,
 	SET_print,
@@ -487,6 +493,7 @@ static asn_SET_specifics_t asn_DEF_Test_structure_3_specs = {
 	(unsigned int *)asn_DEF_Test_structure_3_mmap	/* Mandatory elements map */
 };
 asn_TYPE_descriptor_t asn_DEF_Test_structure_3 = {
+	"Test-structure-3",
 	"Test-structure-3",
 	SET_free,
 	SET_print,
diff --git a/tests/44-choice-in-sequence-OK.asn1.-P b/tests/44-choice-in-sequence-OK.asn1.-P
index 8b3106d8..bb51a570 100644
--- a/tests/44-choice-in-sequence-OK.asn1.-P
+++ b/tests/44-choice-in-sequence-OK.asn1.-P
@@ -99,6 +99,7 @@ static asn_CHOICE_specifics_t asn_DEF_e_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_e = {
+	"e",
 	"e",
 	CHOICE_free,
 	CHOICE_print,
@@ -148,6 +149,7 @@ static asn_CHOICE_specifics_t asn_DEF_h_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_h = {
+	"h",
 	"h",
 	CHOICE_free,
 	CHOICE_print,
@@ -214,6 +216,7 @@ static asn_CHOICE_specifics_t asn_DEF_b_specs = {
 };
 static /* Use -fall-defs-global to expose */
 asn_TYPE_descriptor_t asn_DEF_b = {
+	"b",
 	"b",
 	CHOICE_free,
 	CHOICE_print,
@@ -269,6 +272,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_T_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
 	"T",
 	SEQUENCE_free,
 	SEQUENCE_print,
diff --git a/tests/46-redefine-OK.asn1.-PR b/tests/46-redefine-OK.asn1.-PR
index 92a81cae..4650b513 100644
--- a/tests/46-redefine-OK.asn1.-PR
+++ b/tests/46-redefine-OK.asn1.-PR
@@ -63,6 +63,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_ConstructedType_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_ConstructedType = {
+	"ConstructedType",
 	"ConstructedType",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -144,7 +145,7 @@ T_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T_inherit_TYPE_descriptor(td);
@@ -175,6 +176,7 @@ static ber_tlv_tag_t asn_DEF_T_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
 	"T",
 	T_free,
 	T_print,
diff --git a/tests/47-set-ext-OK.asn1.-P b/tests/47-set-ext-OK.asn1.-P
index 5aa2ce2d..8c2bc270 100644
--- a/tests/47-set-ext-OK.asn1.-P
+++ b/tests/47-set-ext-OK.asn1.-P
@@ -65,6 +65,7 @@ static asn_SET_specifics_t asn_DEF_T1_specs = {
 	(unsigned int *)asn_DEF_T1_mmap	/* Mandatory elements map */
 };
 asn_TYPE_descriptor_t asn_DEF_T1 = {
+	"T1",
 	"T1",
 	SET_free,
 	SET_print,
@@ -152,6 +153,7 @@ static asn_SET_specifics_t asn_DEF_T2_specs = {
 	(unsigned int *)asn_DEF_T2_mmap	/* Mandatory elements map */
 };
 asn_TYPE_descriptor_t asn_DEF_T2 = {
+	"T2",
 	"T2",
 	SET_free,
 	SET_print,
@@ -228,6 +230,7 @@ static asn_CHOICE_specifics_t asn_DEF_T3_specs = {
 	1	/* Whether extensible */
 };
 asn_TYPE_descriptor_t asn_DEF_T3 = {
+	"T3",
 	"T3",
 	CHOICE_free,
 	CHOICE_print,
@@ -302,6 +305,7 @@ static asn_CHOICE_specifics_t asn_DEF_T4_specs = {
 	1	/* Whether extensible */
 };
 asn_TYPE_descriptor_t asn_DEF_T4 = {
+	"T4",
 	"T4",
 	CHOICE_free,
 	CHOICE_print,
diff --git a/tests/50-constraint-OK.asn1.-P b/tests/50-constraint-OK.asn1.-P
index 9eba4695..6f4dac10 100644
--- a/tests/50-constraint-OK.asn1.-P
+++ b/tests/50-constraint-OK.asn1.-P
@@ -97,7 +97,7 @@ Int2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Int2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int2_inherit_TYPE_descriptor(td);
@@ -127,6 +127,7 @@ static ber_tlv_tag_t asn_DEF_Int2_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Int2 = {
+	"Int2",
 	"Int2",
 	Int2_free,
 	Int2_print,
@@ -230,7 +231,7 @@ Int3_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Int3_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int3_inherit_TYPE_descriptor(td);
@@ -260,6 +261,7 @@ static ber_tlv_tag_t asn_DEF_Int3_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Int3 = {
+	"Int3",
 	"Int3",
 	Int3_free,
 	Int3_print,
@@ -363,7 +365,7 @@ Int4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Int4_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int4_inherit_TYPE_descriptor(td);
@@ -393,6 +395,7 @@ static ber_tlv_tag_t asn_DEF_Int4_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Int4 = {
+	"Int4",
 	"Int4",
 	Int4_free,
 	Int4_print,
@@ -496,7 +499,7 @@ Int5_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Int5_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int5_inherit_TYPE_descriptor(td);
@@ -526,6 +529,7 @@ static ber_tlv_tag_t asn_DEF_Int5_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Int5 = {
+	"Int5",
 	"Int5",
 	Int5_free,
 	Int5_print,
@@ -629,7 +633,7 @@ ExtensibleExtensions_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 ExtensibleExtensions_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	ExtensibleExtensions_inherit_TYPE_descriptor(td);
@@ -659,6 +663,7 @@ static ber_tlv_tag_t asn_DEF_ExtensibleExtensions_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_ExtensibleExtensions = {
+	"ExtensibleExtensions",
 	"ExtensibleExtensions",
 	ExtensibleExtensions_free,
 	ExtensibleExtensions_print,
@@ -793,7 +798,7 @@ Str2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Str2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Str2_inherit_TYPE_descriptor(td);
@@ -823,6 +828,7 @@ static ber_tlv_tag_t asn_DEF_Str2_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Str2 = {
+	"Str2",
 	"Str2",
 	Str2_free,
 	Str2_print,
@@ -949,7 +955,7 @@ Str3_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Str3_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Str3_inherit_TYPE_descriptor(td);
@@ -979,6 +985,7 @@ static ber_tlv_tag_t asn_DEF_Str3_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Str3 = {
+	"Str3",
 	"Str3",
 	Str3_free,
 	Str3_print,
@@ -1091,7 +1098,7 @@ Str4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Str4_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Str4_inherit_TYPE_descriptor(td);
@@ -1121,6 +1128,7 @@ static ber_tlv_tag_t asn_DEF_Str4_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Str4 = {
+	"Str4",
 	"Str4",
 	Str4_free,
 	Str4_print,
@@ -1233,7 +1241,7 @@ PER_Visible_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 PER_Visible_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	PER_Visible_inherit_TYPE_descriptor(td);
@@ -1263,6 +1271,7 @@ static ber_tlv_tag_t asn_DEF_PER_Visible_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_PER_Visible = {
+	"PER-Visible",
 	"PER-Visible",
 	PER_Visible_free,
 	PER_Visible_print,
@@ -1375,7 +1384,7 @@ PER_Visible_2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 PER_Visible_2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	PER_Visible_2_inherit_TYPE_descriptor(td);
@@ -1405,6 +1414,7 @@ static ber_tlv_tag_t asn_DEF_PER_Visible_2_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_PER_Visible_2 = {
+	"PER-Visible-2",
 	"PER-Visible-2",
 	PER_Visible_2_free,
 	PER_Visible_2_print,
@@ -1517,7 +1527,7 @@ Not_PER_Visible_1_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Not_PER_Visible_1_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Not_PER_Visible_1_inherit_TYPE_descriptor(td);
@@ -1547,6 +1557,7 @@ static ber_tlv_tag_t asn_DEF_Not_PER_Visible_1_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_1 = {
+	"Not-PER-Visible-1",
 	"Not-PER-Visible-1",
 	Not_PER_Visible_1_free,
 	Not_PER_Visible_1_print,
@@ -1659,7 +1670,7 @@ Not_PER_Visible_2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Not_PER_Visible_2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Not_PER_Visible_2_inherit_TYPE_descriptor(td);
@@ -1689,6 +1700,7 @@ static ber_tlv_tag_t asn_DEF_Not_PER_Visible_2_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_2 = {
+	"Not-PER-Visible-2",
 	"Not-PER-Visible-2",
 	Not_PER_Visible_2_free,
 	Not_PER_Visible_2_print,
@@ -1801,7 +1813,7 @@ Not_PER_Visible_3_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Not_PER_Visible_3_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Not_PER_Visible_3_inherit_TYPE_descriptor(td);
@@ -1831,6 +1843,7 @@ static ber_tlv_tag_t asn_DEF_Not_PER_Visible_3_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Not_PER_Visible_3 = {
+	"Not-PER-Visible-3",
 	"Not-PER-Visible-3",
 	Not_PER_Visible_3_free,
 	Not_PER_Visible_3_print,
@@ -1946,7 +1959,7 @@ SIZE_but_not_FROM_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 SIZE_but_not_FROM_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	SIZE_but_not_FROM_inherit_TYPE_descriptor(td);
@@ -1976,6 +1989,7 @@ static ber_tlv_tag_t asn_DEF_SIZE_but_not_FROM_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_SIZE_but_not_FROM = {
+	"SIZE-but-not-FROM",
 	"SIZE-but-not-FROM",
 	SIZE_but_not_FROM_free,
 	SIZE_but_not_FROM_print,
@@ -2091,7 +2105,7 @@ SIZE_and_FROM_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 SIZE_and_FROM_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	SIZE_and_FROM_inherit_TYPE_descriptor(td);
@@ -2121,6 +2135,7 @@ static ber_tlv_tag_t asn_DEF_SIZE_and_FROM_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_SIZE_and_FROM = {
+	"SIZE-and-FROM",
 	"SIZE-and-FROM",
 	SIZE_and_FROM_free,
 	SIZE_and_FROM_print,
@@ -2233,7 +2248,7 @@ Neither_SIZE_nor_FROM_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Neither_SIZE_nor_FROM_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Neither_SIZE_nor_FROM_inherit_TYPE_descriptor(td);
@@ -2263,6 +2278,7 @@ static ber_tlv_tag_t asn_DEF_Neither_SIZE_nor_FROM_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Neither_SIZE_nor_FROM = {
+	"Neither-SIZE-nor-FROM",
 	"Neither-SIZE-nor-FROM",
 	Neither_SIZE_nor_FROM_free,
 	Neither_SIZE_nor_FROM_print,
@@ -2369,7 +2385,7 @@ Utf8_4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Utf8_4_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Utf8_4_inherit_TYPE_descriptor(td);
@@ -2399,6 +2415,7 @@ static ber_tlv_tag_t asn_DEF_Utf8_4_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Utf8_4 = {
+	"Utf8-4",
 	"Utf8-4",
 	Utf8_4_free,
 	Utf8_4_print,
@@ -2533,7 +2550,7 @@ Utf8_3_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Utf8_3_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Utf8_3_inherit_TYPE_descriptor(td);
@@ -2563,6 +2580,7 @@ static ber_tlv_tag_t asn_DEF_Utf8_3_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Utf8_3 = {
+	"Utf8-3",
 	"Utf8-3",
 	Utf8_3_free,
 	Utf8_3_print,
@@ -2667,7 +2685,7 @@ Utf8_2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Utf8_2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Utf8_2_inherit_TYPE_descriptor(td);
@@ -2697,6 +2715,7 @@ static ber_tlv_tag_t asn_DEF_Utf8_2_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Utf8_2 = {
+	"Utf8-2",
 	"Utf8-2",
 	Utf8_2_free,
 	Utf8_2_print,
@@ -2862,7 +2881,7 @@ Identifier_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 Identifier_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Identifier_inherit_TYPE_descriptor(td);
@@ -2892,6 +2911,7 @@ static ber_tlv_tag_t asn_DEF_Identifier_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (26 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_Identifier = {
+	"Identifier",
 	"Identifier",
 	Identifier_free,
 	Identifier_print,
diff --git a/tests/60-any-OK.asn1.-P b/tests/60-any-OK.asn1.-P
index 59aa7b1d..f740e8a8 100644
--- a/tests/60-any-OK.asn1.-P
+++ b/tests/60-any-OK.asn1.-P
@@ -53,6 +53,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_T1_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_T1 = {
+	"T1",
 	"T1",
 	SEQUENCE_free,
 	SEQUENCE_print,
@@ -129,6 +130,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_T2_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_T2 = {
+	"T2",
 	"T2",
 	SEQUENCE_free,
 	SEQUENCE_print,
diff --git a/tests/65-multi-tag-OK.asn1.-P b/tests/65-multi-tag-OK.asn1.-P
index 995697ee..4ffc4b20 100644
--- a/tests/65-multi-tag-OK.asn1.-P
+++ b/tests/65-multi-tag-OK.asn1.-P
@@ -59,7 +59,7 @@ T1_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T1_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T1_inherit_TYPE_descriptor(td);
@@ -100,6 +100,7 @@ static ber_tlv_tag_t asn_DEF_T1_all_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T1 = {
+	"T1",
 	"T1",
 	T1_free,
 	T1_print,
@@ -180,7 +181,7 @@ T2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T2_inherit_TYPE_descriptor(td);
@@ -219,6 +220,7 @@ static ber_tlv_tag_t asn_DEF_T2_all_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T2 = {
+	"T2",
 	"T2",
 	T2_free,
 	T2_print,
@@ -299,7 +301,7 @@ T3_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T3_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T3_inherit_TYPE_descriptor(td);
@@ -336,6 +338,7 @@ static ber_tlv_tag_t asn_DEF_T3_all_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T3 = {
+	"T3",
 	"T3",
 	T3_free,
 	T3_print,
@@ -416,7 +419,7 @@ T4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T4_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T4_inherit_TYPE_descriptor(td);
@@ -448,6 +451,7 @@ static ber_tlv_tag_t asn_DEF_T4_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T4 = {
+	"T4",
 	"T4",
 	T4_free,
 	T4_print,
@@ -528,7 +532,7 @@ T5_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T5_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T5_inherit_TYPE_descriptor(td);
@@ -559,6 +563,7 @@ static ber_tlv_tag_t asn_DEF_T5_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T5 = {
+	"T5",
 	"T5",
 	T5_free,
 	T5_print,
@@ -658,7 +663,7 @@ T_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T_inherit_TYPE_descriptor(td);
@@ -690,6 +695,7 @@ static ber_tlv_tag_t asn_DEF_T_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
 	"T",
 	T_free,
 	T_print,
@@ -775,6 +781,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_Ts_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_Ts = {
+	"Ts",
 	"Ts",
 	SEQUENCE_free,
 	SEQUENCE_print,
diff --git a/tests/65-multi-tag-OK.asn1.-Pfnative-types b/tests/65-multi-tag-OK.asn1.-Pfnative-types
index faed7c66..796962ae 100644
--- a/tests/65-multi-tag-OK.asn1.-Pfnative-types
+++ b/tests/65-multi-tag-OK.asn1.-Pfnative-types
@@ -59,7 +59,7 @@ T1_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T1_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T1_inherit_TYPE_descriptor(td);
@@ -100,6 +100,7 @@ static ber_tlv_tag_t asn_DEF_T1_all_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T1 = {
+	"T1",
 	"T1",
 	T1_free,
 	T1_print,
@@ -180,7 +181,7 @@ T2_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T2_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T2_inherit_TYPE_descriptor(td);
@@ -219,6 +220,7 @@ static ber_tlv_tag_t asn_DEF_T2_all_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T2 = {
+	"T2",
 	"T2",
 	T2_free,
 	T2_print,
@@ -299,7 +301,7 @@ T3_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T3_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T3_inherit_TYPE_descriptor(td);
@@ -336,6 +338,7 @@ static ber_tlv_tag_t asn_DEF_T3_all_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T3 = {
+	"T3",
 	"T3",
 	T3_free,
 	T3_print,
@@ -416,7 +419,7 @@ T4_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T4_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T4_inherit_TYPE_descriptor(td);
@@ -448,6 +451,7 @@ static ber_tlv_tag_t asn_DEF_T4_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T4 = {
+	"T4",
 	"T4",
 	T4_free,
 	T4_print,
@@ -528,7 +532,7 @@ T5_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T5_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T5_inherit_TYPE_descriptor(td);
@@ -559,6 +563,7 @@ static ber_tlv_tag_t asn_DEF_T5_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (9 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T5 = {
+	"T5",
 	"T5",
 	T5_free,
 	T5_print,
@@ -658,7 +663,7 @@ T_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 T_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T_inherit_TYPE_descriptor(td);
@@ -690,6 +695,7 @@ static ber_tlv_tag_t asn_DEF_T_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
 	"T",
 	T_free,
 	T_print,
@@ -775,6 +781,7 @@ static asn_SEQUENCE_specifics_t asn_DEF_Ts_specs = {
 	-1	/* Stop extensions */
 };
 asn_TYPE_descriptor_t asn_DEF_Ts = {
+	"Ts",
 	"Ts",
 	SEQUENCE_free,
 	SEQUENCE_print,
diff --git a/tests/66-ref-simple-OK.asn1.-P b/tests/66-ref-simple-OK.asn1.-P
index 025f7e95..0131c919 100644
--- a/tests/66-ref-simple-OK.asn1.-P
+++ b/tests/66-ref-simple-OK.asn1.-P
@@ -39,6 +39,7 @@ static asn_SET_OF_specifics_t asn_DEF_T_specs = {
 	1,	/* XER encoding is XMLValueList */
 };
 asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
 	"T",
 	SET_OF_free,
 	SET_OF_print,
@@ -128,7 +129,7 @@ SimpleType_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,
 	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
 }
 
-ber_dec_rval_t
+asn_dec_rval_t
 SimpleType_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	SimpleType_inherit_TYPE_descriptor(td);
@@ -158,6 +159,7 @@ static ber_tlv_tag_t asn_DEF_SimpleType_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_SimpleType = {
+	"SimpleType",
 	"SimpleType",
 	SimpleType_free,
 	SimpleType_print,
-- 
GitLab