From: Maksym Mamontov <madf@madf.info>
Date: Sun, 17 Jan 2021 15:58:38 +0000 (+0200)
Subject: Update SMUX library.
X-Git-Url: https://git.stg.codes/stg.git/commitdiff_plain/4271ab433cd55bbd2612292bcf39e4dc3d7274f1?ds=sidebyside;hp=--cc

Update SMUX library.
---

4271ab433cd55bbd2612292bcf39e4dc3d7274f1
diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt
index bc632f03..d6e84941 100644
--- a/libs/CMakeLists.txt
+++ b/libs/CMakeLists.txt
@@ -54,6 +54,7 @@ if ( BUILD_LIB_SMUX )
     file ( GLOB SMUX_C_FILES smux/*.c )
     add_library ( smux STATIC ${SMUX_C_FILES} )
     target_include_directories ( smux PUBLIC smux/include smux/include/stg )
+    target_compile_options ( smux PRIVATE -Wno-cpp )
 endif ( BUILD_LIB_SMUX )
 
 if ( BUILD_LIB_SRVCONF )
diff --git a/libs/smux/ANY.c b/libs/smux/ANY.c
index 612238b6..77024bdc 100644
--- a/libs/smux/ANY.c
+++ b/libs/smux/ANY.c
@@ -9,7 +9,7 @@
 static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = {
 	sizeof(ANY_t),
 	offsetof(ANY_t, _asn_ctx),
-	2	/* Special indicator that this is an ANY type */
+	ASN_OSUBV_ANY
 };
 asn_TYPE_descriptor_t asn_DEF_ANY = {
 	"ANY",
@@ -39,7 +39,7 @@ ANY_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		/*
 		 * Canonical XER-encoding of ANY type is not supported.
 		 */
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	}
 
 	/* Dump as binary */
diff --git a/libs/smux/ApplicationSyntax.c b/libs/smux/ApplicationSyntax.c
index a4f97e2c..163bae33 100644
--- a/libs/smux/ApplicationSyntax.c
+++ b/libs/smux/ApplicationSyntax.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "ApplicationSyntax.h"
 
 static asn_TYPE_member_t asn_MBR_ApplicationSyntax_1[] = {
@@ -56,12 +54,12 @@ static asn_TYPE_member_t asn_MBR_ApplicationSyntax_1[] = {
 		"arbitrary"
 		},
 };
-static asn_TYPE_tag2member_t asn_MAP_ApplicationSyntax_tag2el_1[] = {
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* internet at 113 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
-    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* gauge at 94 */
-    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* ticks at 97 */
-    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 4, 0, 0 } /* arbitrary at 104 */
+static const asn_TYPE_tag2member_t asn_MAP_ApplicationSyntax_tag2el_1[] = {
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* internet */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter */
+    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* gauge */
+    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* ticks */
+    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 4, 0, 0 } /* arbitrary */
 };
 static asn_CHOICE_specifics_t asn_SPC_ApplicationSyntax_specs_1 = {
 	sizeof(struct ApplicationSyntax),
diff --git a/libs/smux/AtEntry.c b/libs/smux/AtEntry.c
index bf3b9ba9..035ea40a 100644
--- a/libs/smux/AtEntry.c
+++ b/libs/smux/AtEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "AtEntry.h"
 
 static asn_TYPE_member_t asn_MBR_AtEntry_1[] = {
@@ -38,13 +36,13 @@ static asn_TYPE_member_t asn_MBR_AtEntry_1[] = {
 		"atNetAddress"
 		},
 };
-static ber_tlv_tag_t asn_DEF_AtEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_AtEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_AtEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* atIfIndex at 154 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* atPhysAddress at 157 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* internet at 113 */
+static const asn_TYPE_tag2member_t asn_MAP_AtEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* atIfIndex */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* atPhysAddress */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* internet */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_AtEntry_specs_1 = {
 	sizeof(struct AtEntry),
diff --git a/libs/smux/BIT_STRING.c b/libs/smux/BIT_STRING.c
index 6469d4fd..997ff416 100644
--- a/libs/smux/BIT_STRING.c
+++ b/libs/smux/BIT_STRING.c
@@ -9,13 +9,13 @@
 /*
  * BIT STRING basic type description.
  */
-static ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
+static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
 };
 static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
 	sizeof(BIT_STRING_t),
 	offsetof(BIT_STRING_t, _asn_ctx),
-	1,	/* Special indicator that this is a BIT STRING type */
+	ASN_OSUBV_BIT
 };
 asn_TYPE_descriptor_t asn_DEF_BIT_STRING = {
 	"BIT STRING",
@@ -50,14 +50,15 @@ BIT_STRING_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
 
 	if(st && st->buf) {
-		if(st->size == 1 && st->bits_unused) {
-			_ASN_CTFAIL(app_key, td,
+		if((st->size == 0 && st->bits_unused)
+		|| st->bits_unused < 0 || st->bits_unused > 7) {
+			ASN__CTFAIL(app_key, td, sptr,
 				"%s: invalid padding byte (%s:%d)",
 				td->name, __FILE__, __LINE__);
 			return -1;
 		}
 	} else {
-		_ASN_CTFAIL(app_key, td,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -85,7 +86,7 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	uint8_t *end;
 
 	if(!st || !st->buf)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	er.encoded = 0;
 
@@ -100,9 +101,9 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		int nline = xcan?0:(((buf - st->buf) % 8) == 0);
 		if(p >= scend || nline) {
 			er.encoded += p - scratch;
-			_ASN_CALLBACK(scratch, p - scratch);
+			ASN__CALLBACK(scratch, p - scratch);
 			p = scratch;
-			if(nline) _i_ASN_TEXT_INDENT(1, ilevel);
+			if(nline) ASN__TEXT_INDENT(1, ilevel);
 		}
 		memcpy(p + 0, _bit_pattern[v >> 4], 4);
 		memcpy(p + 4, _bit_pattern[v & 0x0f], 4);
@@ -110,9 +111,9 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	}
 
 	if(!xcan && ((buf - st->buf) % 8) == 0)
-		_i_ASN_TEXT_INDENT(1, ilevel);
+		ASN__TEXT_INDENT(1, ilevel);
 	er.encoded += p - scratch;
-	_ASN_CALLBACK(scratch, p - scratch);
+	ASN__CALLBACK(scratch, p - scratch);
 	p = scratch;
 
 	if(buf == end) {
@@ -122,14 +123,14 @@ BIT_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		for(i = 7; i >= ubits; i--)
 			*p++ = (v & (1 << i)) ? 0x31 : 0x30;
 		er.encoded += p - scratch;
-		_ASN_CALLBACK(scratch, p - scratch);
+		ASN__CALLBACK(scratch, p - scratch);
 	}
 
-	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
 
@@ -139,7 +140,7 @@ cb_failed:
 int
 BIT_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 		asn_app_consume_bytes_f *cb, void *app_key) {
-	static const char *h2c = "0123456789ABCDEF";
+	const char * const h2c = "0123456789ABCDEF";
 	char scratch[64];
 	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
 	uint8_t *buf;
diff --git a/libs/smux/BOOLEAN.c b/libs/smux/BOOLEAN.c
index bb4697c2..6e55b3e6 100644
--- a/libs/smux/BOOLEAN.c
+++ b/libs/smux/BOOLEAN.c
@@ -9,7 +9,7 @@
 /*
  * BOOLEAN basic type description.
  */
-static ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
+static const ber_tlv_tag_t asn_DEF_BOOLEAN_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (1 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_BOOLEAN = {
@@ -129,7 +129,7 @@ BOOLEAN_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 
 	erval.encoded += 1;
 
-	_ASN_ENCODED_OK(erval);
+	ASN__ENCODED_OK(erval);
 }
 
 
@@ -161,10 +161,7 @@ BOOLEAN__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
 		}
 		return XPBD_BODY_CONSUMED;
 	} else {
-		if(xer_is_whitespace(chunk_buf, chunk_size))
-			return XPBD_NOT_BODY_IGNORE;
-		else
-			return XPBD_BROKEN_ENCODING;
+		return XPBD_BROKEN_ENCODING;
 	}
 }
 
@@ -189,19 +186,19 @@ BOOLEAN_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	(void)ilevel;
 	(void)flags;
 
-	if(!st) _ASN_ENCODE_FAILED;
+	if(!st) ASN__ENCODE_FAILED;
 
 	if(*st) {
-		_ASN_CALLBACK("<true/>", 7);
+		ASN__CALLBACK("<true/>", 7);
 		er.encoded = 7;
 	} else {
-		_ASN_CALLBACK("<false/>", 8);
+		ASN__CALLBACK("<false/>", 8);
 		er.encoded = 8;
 	}
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
 int
@@ -248,7 +245,7 @@ BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 	if(!st) {
 		st = (BOOLEAN_t *)(*sptr = MALLOC(sizeof(*st)));
-		if(!st) _ASN_DECODE_FAILED;
+		if(!st) ASN__DECODE_FAILED;
 	}
 
 	/*
@@ -257,7 +254,7 @@ BOOLEAN_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	switch(per_get_few_bits(pd, 1)) {
 	case 1: *st = 1; break;
 	case 0: *st = 0; break;
-	case -1: default: _ASN_DECODE_FAILED;
+	case -1: default: ASN__DECODE_STARVED;
 	}
 
 	ASN_DEBUG("%s decoded as %s", td->name, *st ? "TRUE" : "FALSE");
@@ -272,13 +269,14 @@ asn_enc_rval_t
 BOOLEAN_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
 	const BOOLEAN_t *st = (const BOOLEAN_t *)sptr;
-	asn_enc_rval_t er;
+	asn_enc_rval_t er = { 0, 0, 0 };
 
 	(void)constraints;
 
-	if(!st) _ASN_ENCODE_FAILED;
+	if(!st) ASN__ENCODE_FAILED;
 
-	per_put_few_bits(po, *st ? 1 : 0, 1);
+	if(per_put_few_bits(po, *st ? 1 : 0, 1))
+		ASN__ENCODE_FAILED;
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
diff --git a/libs/smux/ClosePDU.c b/libs/smux/ClosePDU.c
index a97e3b45..ce9745d7 100644
--- a/libs/smux/ClosePDU.c
+++ b/libs/smux/ClosePDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "ClosePDU.h"
 
 int
@@ -25,6 +23,7 @@ static void
 ClosePDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_INTEGER.free_struct;
 	td->print_struct   = asn_DEF_INTEGER.print_struct;
+	td->check_constraints = asn_DEF_INTEGER.check_constraints;
 	td->ber_decoder    = asn_DEF_INTEGER.ber_decoder;
 	td->der_encoder    = asn_DEF_INTEGER.der_encoder;
 	td->xer_decoder    = asn_DEF_INTEGER.xer_decoder;
@@ -82,7 +81,7 @@ ClosePDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_ClosePDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_ClosePDU_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (1 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
diff --git a/libs/smux/Counter.c b/libs/smux/Counter.c
index c2389fdb..a083ee8f 100644
--- a/libs/smux/Counter.c
+++ b/libs/smux/Counter.c
@@ -1,64 +1,48 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "Counter.h"
 
 int
 Counter_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
-	const INTEGER_t *st = (const INTEGER_t *)sptr;
-	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
 	}
 	
-	if(asn_INTEGER2long(st, &value)) {
-		_ASN_CTFAIL(app_key, td, sptr,
-			"%s: value too large (%s:%d)",
-			td->name, __FILE__, __LINE__);
-		return -1;
-	}
 	
-	if((value >= 0 && value <= 4294967295)) {
-		/* Constraint check succeeded */
-		return 0;
-	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
-			"%s: constraint failed (%s:%d)",
-			td->name, __FILE__, __LINE__);
-		return -1;
-	}
+	/* Constraint check succeeded */
+	return 0;
 }
 
 /*
- * This type is implemented using INTEGER,
+ * This type is implemented using NativeInteger,
  * so here we adjust the DEF accordingly.
  */
 static void
 Counter_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
-	td->free_struct    = asn_DEF_INTEGER.free_struct;
-	td->print_struct   = asn_DEF_INTEGER.print_struct;
-	td->ber_decoder    = asn_DEF_INTEGER.ber_decoder;
-	td->der_encoder    = asn_DEF_INTEGER.der_encoder;
-	td->xer_decoder    = asn_DEF_INTEGER.xer_decoder;
-	td->xer_encoder    = asn_DEF_INTEGER.xer_encoder;
-	td->uper_decoder   = asn_DEF_INTEGER.uper_decoder;
-	td->uper_encoder   = asn_DEF_INTEGER.uper_encoder;
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
 	if(!td->per_constraints)
-		td->per_constraints = asn_DEF_INTEGER.per_constraints;
-	td->elements       = asn_DEF_INTEGER.elements;
-	td->elements_count = asn_DEF_INTEGER.elements_count;
-	td->specifics      = asn_DEF_INTEGER.specifics;
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+     /* td->specifics      = asn_DEF_NativeInteger.specifics;	// Defined explicitly */
 }
 
 void
@@ -105,7 +89,12 @@ Counter_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_Counter_tags_1[] = {
+static const asn_INTEGER_specifics_t asn_SPC_Counter_specs_1 = {
+	0,	0,	0,	0,	0,
+	0,	/* Native long size */
+	1	/* Unsigned representation */
+};
+static const ber_tlv_tag_t asn_DEF_Counter_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (1 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
@@ -129,6 +118,6 @@ asn_TYPE_descriptor_t asn_DEF_Counter = {
 		/sizeof(asn_DEF_Counter_tags_1[0]), /* 2 */
 	0,	/* No PER visible constraints */
 	0, 0,	/* No members */
-	0	/* No specifics */
+	&asn_SPC_Counter_specs_1	/* Additional specs */
 };
 
diff --git a/libs/smux/DisplayString.c b/libs/smux/DisplayString.c
index f3c57405..a567799f 100644
--- a/libs/smux/DisplayString.c
+++ b/libs/smux/DisplayString.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "DisplayString.h"
 
 int
@@ -25,6 +23,7 @@ static void
 DisplayString_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_OCTET_STRING.free_struct;
 	td->print_struct   = asn_DEF_OCTET_STRING.print_struct;
+	td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
 	td->ber_decoder    = asn_DEF_OCTET_STRING.ber_decoder;
 	td->der_encoder    = asn_DEF_OCTET_STRING.der_encoder;
 	td->xer_decoder    = asn_DEF_OCTET_STRING.xer_decoder;
@@ -82,7 +81,7 @@ DisplayString_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_DisplayString_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_DisplayString_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_DisplayString = {
diff --git a/libs/smux/EgpNeighEntry.c b/libs/smux/EgpNeighEntry.c
index 07c28afa..b12c489f 100644
--- a/libs/smux/EgpNeighEntry.c
+++ b/libs/smux/EgpNeighEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "EgpNeighEntry.h"
 
 static asn_TYPE_member_t asn_MBR_EgpNeighEntry_1[] = {
@@ -146,25 +144,25 @@ static asn_TYPE_member_t asn_MBR_EgpNeighEntry_1[] = {
 		"egpNeighEventTrigger"
 		},
 };
-static ber_tlv_tag_t asn_DEF_EgpNeighEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_EgpNeighEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_EgpNeighEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 5 }, /* egpNeighState at 267 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 4 }, /* egpNeighAs at 271 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -2, 3 }, /* egpNeighIntervalHello at 290 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 12, -3, 2 }, /* egpNeighIntervalPoll at 292 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 13, -4, 1 }, /* egpNeighMode at 294 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 14, -5, 0 }, /* egpNeighEventTrigger at 297 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* egpNeighAddr at 269 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 3, 0, 7 }, /* egpNeighInMsgs at 273 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 4, -1, 6 }, /* egpNeighInErrs at 275 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 5, -2, 5 }, /* egpNeighOutMsgs at 277 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 6, -3, 4 }, /* egpNeighOutErrs at 279 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 7, -4, 3 }, /* egpNeighInErrMsgs at 282 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 8, -5, 2 }, /* egpNeighOutErrMsgs at 284 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, -6, 1 }, /* egpNeighStateUps at 286 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -7, 0 } /* egpNeighStateDowns at 288 */
+static const asn_TYPE_tag2member_t asn_MAP_EgpNeighEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 5 }, /* egpNeighState */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 4 }, /* egpNeighAs */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -2, 3 }, /* egpNeighIntervalHello */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 12, -3, 2 }, /* egpNeighIntervalPoll */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 13, -4, 1 }, /* egpNeighMode */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 14, -5, 0 }, /* egpNeighEventTrigger */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* egpNeighAddr */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 3, 0, 7 }, /* egpNeighInMsgs */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 4, -1, 6 }, /* egpNeighInErrs */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 5, -2, 5 }, /* egpNeighOutMsgs */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 6, -3, 4 }, /* egpNeighOutErrs */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 7, -4, 3 }, /* egpNeighInErrMsgs */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 8, -5, 2 }, /* egpNeighOutErrMsgs */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, -6, 1 }, /* egpNeighStateUps */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -7, 0 } /* egpNeighStateDowns */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_EgpNeighEntry_specs_1 = {
 	sizeof(struct EgpNeighEntry),
diff --git a/libs/smux/Gauge.c b/libs/smux/Gauge.c
index 190b91f4..2007be44 100644
--- a/libs/smux/Gauge.c
+++ b/libs/smux/Gauge.c
@@ -1,64 +1,48 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "Gauge.h"
 
 int
 Gauge_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
-	const INTEGER_t *st = (const INTEGER_t *)sptr;
-	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
 	}
 	
-	if(asn_INTEGER2long(st, &value)) {
-		_ASN_CTFAIL(app_key, td, sptr,
-			"%s: value too large (%s:%d)",
-			td->name, __FILE__, __LINE__);
-		return -1;
-	}
 	
-	if((value >= 0 && value <= 4294967295)) {
-		/* Constraint check succeeded */
-		return 0;
-	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
-			"%s: constraint failed (%s:%d)",
-			td->name, __FILE__, __LINE__);
-		return -1;
-	}
+	/* Constraint check succeeded */
+	return 0;
 }
 
 /*
- * This type is implemented using INTEGER,
+ * This type is implemented using NativeInteger,
  * so here we adjust the DEF accordingly.
  */
 static void
 Gauge_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
-	td->free_struct    = asn_DEF_INTEGER.free_struct;
-	td->print_struct   = asn_DEF_INTEGER.print_struct;
-	td->ber_decoder    = asn_DEF_INTEGER.ber_decoder;
-	td->der_encoder    = asn_DEF_INTEGER.der_encoder;
-	td->xer_decoder    = asn_DEF_INTEGER.xer_decoder;
-	td->xer_encoder    = asn_DEF_INTEGER.xer_encoder;
-	td->uper_decoder   = asn_DEF_INTEGER.uper_decoder;
-	td->uper_encoder   = asn_DEF_INTEGER.uper_encoder;
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
 	if(!td->per_constraints)
-		td->per_constraints = asn_DEF_INTEGER.per_constraints;
-	td->elements       = asn_DEF_INTEGER.elements;
-	td->elements_count = asn_DEF_INTEGER.elements_count;
-	td->specifics      = asn_DEF_INTEGER.specifics;
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+     /* td->specifics      = asn_DEF_NativeInteger.specifics;	// Defined explicitly */
 }
 
 void
@@ -105,7 +89,12 @@ Gauge_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_Gauge_tags_1[] = {
+static const asn_INTEGER_specifics_t asn_SPC_Gauge_specs_1 = {
+	0,	0,	0,	0,	0,
+	0,	/* Native long size */
+	1	/* Unsigned representation */
+};
+static const ber_tlv_tag_t asn_DEF_Gauge_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (2 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
@@ -129,6 +118,6 @@ asn_TYPE_descriptor_t asn_DEF_Gauge = {
 		/sizeof(asn_DEF_Gauge_tags_1[0]), /* 2 */
 	0,	/* No PER visible constraints */
 	0, 0,	/* No members */
-	0	/* No specifics */
+	&asn_SPC_Gauge_specs_1	/* Additional specs */
 };
 
diff --git a/libs/smux/GetNextRequest-PDU.c b/libs/smux/GetNextRequest-PDU.c
index 4ba345e5..ef88e805 100644
--- a/libs/smux/GetNextRequest-PDU.c
+++ b/libs/smux/GetNextRequest-PDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "GetNextRequest-PDU.h"
 
 int
@@ -25,6 +23,7 @@ static void
 GetNextRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_PDU.free_struct;
 	td->print_struct   = asn_DEF_PDU.print_struct;
+	td->check_constraints = asn_DEF_PDU.check_constraints;
 	td->ber_decoder    = asn_DEF_PDU.ber_decoder;
 	td->der_encoder    = asn_DEF_PDU.der_encoder;
 	td->xer_decoder    = asn_DEF_PDU.xer_decoder;
@@ -82,7 +81,7 @@ GetNextRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_GetNextRequest_PDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_GetNextRequest_PDU_tags_1[] = {
 	(ASN_TAG_CLASS_CONTEXT | (1 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
diff --git a/libs/smux/GetRequest-PDU.c b/libs/smux/GetRequest-PDU.c
index 41edc371..953999ce 100644
--- a/libs/smux/GetRequest-PDU.c
+++ b/libs/smux/GetRequest-PDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "GetRequest-PDU.h"
 
 int
@@ -25,6 +23,7 @@ static void
 GetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_PDU.free_struct;
 	td->print_struct   = asn_DEF_PDU.print_struct;
+	td->check_constraints = asn_DEF_PDU.check_constraints;
 	td->ber_decoder    = asn_DEF_PDU.ber_decoder;
 	td->der_encoder    = asn_DEF_PDU.der_encoder;
 	td->xer_decoder    = asn_DEF_PDU.xer_decoder;
@@ -82,7 +81,7 @@ GetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_GetRequest_PDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_GetRequest_PDU_tags_1[] = {
 	(ASN_TAG_CLASS_CONTEXT | (0 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
diff --git a/libs/smux/GetResponse-PDU.c b/libs/smux/GetResponse-PDU.c
index 6dcc845c..37019105 100644
--- a/libs/smux/GetResponse-PDU.c
+++ b/libs/smux/GetResponse-PDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "GetResponse-PDU.h"
 
 int
@@ -25,6 +23,7 @@ static void
 GetResponse_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_PDU.free_struct;
 	td->print_struct   = asn_DEF_PDU.print_struct;
+	td->check_constraints = asn_DEF_PDU.check_constraints;
 	td->ber_decoder    = asn_DEF_PDU.ber_decoder;
 	td->der_encoder    = asn_DEF_PDU.der_encoder;
 	td->xer_decoder    = asn_DEF_PDU.xer_decoder;
@@ -82,7 +81,7 @@ GetResponse_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_GetResponse_PDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_GetResponse_PDU_tags_1[] = {
 	(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
diff --git a/libs/smux/INTEGER.c b/libs/smux/INTEGER.c
index ba455f07..eed82176 100644
--- a/libs/smux/INTEGER.c
+++ b/libs/smux/INTEGER.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2003-2014 Lev Walkin <vlm@lionet.info>.
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
@@ -11,7 +11,7 @@
 /*
  * INTEGER basic type description.
  */
-static ber_tlv_tag_t asn_DEF_INTEGER_tags[] = {
+static const ber_tlv_tag_t asn_DEF_INTEGER_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_INTEGER = {
@@ -24,8 +24,13 @@ asn_TYPE_descriptor_t asn_DEF_INTEGER = {
 	INTEGER_encode_der,
 	INTEGER_decode_xer,
 	INTEGER_encode_xer,
+#ifdef	ASN_DISABLE_PER_SUPPORT
+	0,
+	0,
+#else
 	INTEGER_decode_uper,	/* Unaligned PER decoder */
 	INTEGER_encode_uper,	/* Unaligned PER encoder */
+#endif	/* ASN_DISABLE_PER_SUPPORT */
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_INTEGER_tags,
 	sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
@@ -101,52 +106,35 @@ static const asn_INTEGER_enum_map_t *INTEGER_map_enum2value(asn_INTEGER_specific
  * INTEGER specific human-readable output.
  */
 static ssize_t
-INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) {
+INTEGER__dump(const asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) {
 	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	char scratch[32];	/* Enough for 64-bit integer */
 	uint8_t *buf = st->buf;
 	uint8_t *buf_end = st->buf + st->size;
-	signed long accum;
+	signed long value;
 	ssize_t wrote = 0;
 	char *p;
+	int ret;
 
-	/*
-	 * Advance buf pointer until the start of the value's body.
-	 * This will make us able to process large integers using simple case,
-	 * when the actual value is small
-	 * (0x0000000000abcdef would yield a fine 0x00abcdef)
-	 */
-	/* Skip the insignificant leading bytes */
-	for(; buf < buf_end-1; buf++) {
-		switch(*buf) {
-		case 0x00: if((buf[1] & 0x80) == 0) continue; break;
-		case 0xff: if((buf[1] & 0x80) != 0) continue; break;
-		}
-		break;
-	}
+	if(specs && specs->field_unsigned)
+		ret = asn_INTEGER2ulong(st, (unsigned long *)&value);
+	else
+		ret = asn_INTEGER2long(st, &value);
 
 	/* Simple case: the integer size is small */
-	if((size_t)(buf_end - buf) <= sizeof(accum)) {
+	if(ret == 0) {
 		const asn_INTEGER_enum_map_t *el;
 		size_t scrsize;
-		int ret;
 		char *scr;
 
-		if(buf == buf_end) {
-			accum = 0;
-		} else {
-			accum = (*buf & 0x80) ? -1 : 0;
-			for(; buf < buf_end; buf++)
-				accum = (accum << 8) | *buf;
-		}
-
-		el = INTEGER_map_value2enum(specs, accum);
+		el = (value >= 0 || !specs || !specs->field_unsigned)
+			? INTEGER_map_value2enum(specs, value) : 0;
 		if(el) {
 			scrsize = el->enum_len + 32;
 			scr = (char *)alloca(scrsize);
 			if(plainOrXER == 0)
 				ret = snprintf(scr, scrsize,
-					"%ld (%s)", accum, el->enum_name);
+					"%ld (%s)", value, el->enum_name);
 			else
 				ret = snprintf(scr, scrsize,
 					"<%s/>", el->enum_name);
@@ -158,7 +146,9 @@ INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_by
 		} else {
 			scrsize = sizeof(scratch);
 			scr = scratch;
-			ret = snprintf(scr, scrsize, "%ld", accum);
+			ret = snprintf(scr, scrsize,
+				(specs && specs->field_unsigned)
+				?"%lu":"%ld", value);
 		}
 		assert(ret > 0 && (size_t)ret < scrsize);
 		return (cb(scr, ret, app_key) < 0) ? -1 : ret;
@@ -176,7 +166,7 @@ INTEGER__dump(asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_by
 	/* Output in the long xx:yy:zz... format */
 	/* TODO: replace with generic algorithm (Knuth TAOCP Vol 2, 4.3.1) */
 	for(p = scratch; buf < buf_end; buf++) {
-		static const char *h2c = "0123456789ABCDEF";
+		const char * const h2c = "0123456789ABCDEF";
 		if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
 			/* Flush buffer */
 			if(cb(scratch, p - scratch, app_key) < 0)
@@ -218,8 +208,8 @@ INTEGER_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 struct e2v_key {
 	const char *start;
 	const char *stop;
-	asn_INTEGER_enum_map_t *vemap;
-	unsigned int *evmap;
+	const asn_INTEGER_enum_map_t *vemap;
+	const unsigned int *evmap;
 };
 static int
 INTEGER__compar_enum2value(const void *kp, const void *am) {
@@ -242,7 +232,7 @@ INTEGER__compar_enum2value(const void *kp, const void *am) {
 
 static const asn_INTEGER_enum_map_t *
 INTEGER_map_enum2value(asn_INTEGER_specifics_t *specs, const char *lstart, const char *lstop) {
-	asn_INTEGER_enum_map_t *el_found;
+	const asn_INTEGER_enum_map_t *el_found;
 	int count = specs ? specs->map_count : 0;
 	struct e2v_key key;
 	const char *lp;
@@ -317,57 +307,71 @@ INTEGER_st_prealloc(INTEGER_t *st, int min_size) {
 static enum xer_pbd_rval
 INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
 	INTEGER_t *st = (INTEGER_t *)sptr;
-	long sign = 1;
-	long value;
+	long dec_value;
+	long hex_value = 0;
 	const char *lp;
 	const char *lstart = (const char *)chunk_buf;
 	const char *lstop = lstart + chunk_size;
 	enum {
-		ST_SKIPSPACE,
+		ST_LEADSPACE,
 		ST_SKIPSPHEX,
 		ST_WAITDIGITS,
 		ST_DIGITS,
+		ST_DIGITS_TRAILSPACE,
 		ST_HEXDIGIT1,
 		ST_HEXDIGIT2,
+		ST_HEXDIGITS_TRAILSPACE,
 		ST_HEXCOLON,
-		ST_EXTRASTUFF
-	} state = ST_SKIPSPACE;
+		ST_END_ENUM,
+		ST_UNEXPECTED
+	} state = ST_LEADSPACE;
+	const char *dec_value_start = 0; /* INVARIANT: always !0 in ST_DIGITS */
+	const char *dec_value_end = 0;
 
 	if(chunk_size)
-		ASN_DEBUG("INTEGER body %d 0x%2x..0x%2x",
-			chunk_size, *lstart, lstop[-1]);
+		ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x",
+			(long)chunk_size, *lstart, lstop[-1]);
+
+	if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
+		return XPBD_SYSTEM_FAILURE;
 
 	/*
 	 * We may have received a tag here. It will be processed inline.
 	 * Use strtoul()-like code and serialize the result.
 	 */
-	for(value = 0, lp = lstart; lp < lstop; lp++) {
+	for(lp = lstart; lp < lstop; lp++) {
 		int lv = *lp;
 		switch(lv) {
 		case 0x09: case 0x0a: case 0x0d: case 0x20:
 			switch(state) {
-			case ST_SKIPSPACE:
+			case ST_LEADSPACE:
+			case ST_DIGITS_TRAILSPACE:
+			case ST_HEXDIGITS_TRAILSPACE:
 			case ST_SKIPSPHEX:
 				continue;
+			case ST_DIGITS:
+				dec_value_end = lp;
+				state = ST_DIGITS_TRAILSPACE;
+				continue;
 			case ST_HEXCOLON:
-				if(xer_is_whitespace(lp, lstop - lp)) {
-					lp = lstop - 1;
-					continue;
-				}
-				break;
+				state = ST_HEXDIGITS_TRAILSPACE;
+				continue;
 			default:
 				break;
 			}
 			break;
 		case 0x2d:	/* '-' */
-			if(state == ST_SKIPSPACE) {
-				sign = -1;
+			if(state == ST_LEADSPACE) {
+				dec_value = 0;
+				dec_value_start = lp;
 				state = ST_WAITDIGITS;
 				continue;
 			}
 			break;
 		case 0x2b:	/* '+' */
-			if(state == ST_SKIPSPACE) {
+			if(state == ST_LEADSPACE) {
+				dec_value = 0;
+				dec_value_start = lp;
 				state = ST_WAITDIGITS;
 				continue;
 			}
@@ -375,48 +379,32 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
 		case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
 		case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
 			switch(state) {
-			case ST_DIGITS: break;
+			case ST_DIGITS: continue;
 			case ST_SKIPSPHEX:	/* Fall through */
 			case ST_HEXDIGIT1:
-				value = (lv - 0x30) << 4;
+				hex_value = (lv - 0x30) << 4;
 				state = ST_HEXDIGIT2;
 				continue;
 			case ST_HEXDIGIT2:
-				value += (lv - 0x30);
+				hex_value += (lv - 0x30);
 				state = ST_HEXCOLON;
-				st->buf[st->size++] = value;
+				st->buf[st->size++] = (uint8_t)hex_value;
 				continue;
 			case ST_HEXCOLON:
 				return XPBD_BROKEN_ENCODING;
-			default:
+			case ST_LEADSPACE:
+				dec_value = 0;
+				dec_value_start = lp;
+				/* FALL THROUGH */
+			case ST_WAITDIGITS:
 				state = ST_DIGITS;
+				continue;
+			default:
 				break;
 			}
-
-		    {
-			long new_value = value * 10;
-
-			if(new_value / 10 != value)
-				/* Overflow */
-				return XPBD_DECODER_LIMIT;
-
-			value = new_value + (lv - 0x30);
-			/* Check for two's complement overflow */
-			if(value < 0) {
-				/* Check whether it is a LONG_MIN */
-				if(sign == -1
-				&& (unsigned long)value
-						== ~((unsigned long)-1 >> 1)) {
-					sign = 1;
-				} else {
-					/* Overflow */
-					return XPBD_DECODER_LIMIT;
-				}
-			}
-		    }
-			continue;
-		case 0x3c:	/* '<' */
-			if(state == ST_SKIPSPACE) {
+			break;
+		case 0x3c:	/* '<', start of XML encoded enumeration */
+			if(state == ST_LEADSPACE) {
 				const asn_INTEGER_enum_map_t *el;
 				el = INTEGER_map_enum2value(
 					(asn_INTEGER_specifics_t *)
@@ -424,8 +412,8 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
 				if(el) {
 					ASN_DEBUG("Found \"%s\" => %ld",
 						el->enum_name, el->nat_value);
-					state = ST_DIGITS;
-					value = el->nat_value;
+					dec_value = el->nat_value;
+					state = ST_END_ENUM;
 					lp = lstop - 1;
 					continue;
 				}
@@ -443,13 +431,12 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
 				 * places as a decimal value.
 				 * Switch decoding mode. */
 				ASN_DEBUG("INTEGER re-evaluate as hex form");
-				if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
-					return XPBD_SYSTEM_FAILURE;
 				state = ST_SKIPSPHEX;
+				dec_value_start = 0;
 				lp = lstart - 1;
 				continue;
 			} else {
-				ASN_DEBUG("state %d at %d", state, lp - lstart);
+				ASN_DEBUG("state %d at %ld", state, (long)(lp - lstart));
 				break;
 			}
 		/* [A-Fa-f] */
@@ -457,24 +444,23 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
 		case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:
 			switch(state) {
 			case ST_SKIPSPHEX:
-			case ST_SKIPSPACE: /* Fall through */
+			case ST_LEADSPACE: /* Fall through */
 			case ST_HEXDIGIT1:
-				value = lv - ((lv < 0x61) ? 0x41 : 0x61);
-				value += 10;
-				value <<= 4;
+				hex_value = lv - ((lv < 0x61) ? 0x41 : 0x61);
+				hex_value += 10;
+				hex_value <<= 4;
 				state = ST_HEXDIGIT2;
 				continue;
 			case ST_HEXDIGIT2:
-				value += lv - ((lv < 0x61) ? 0x41 : 0x61);
-				value += 10;
-				st->buf[st->size++] = value;
+				hex_value += lv - ((lv < 0x61) ? 0x41 : 0x61);
+				hex_value += 10;
+				st->buf[st->size++] = (uint8_t)hex_value;
 				state = ST_HEXCOLON;
 				continue;
 			case ST_DIGITS:
 				ASN_DEBUG("INTEGER re-evaluate as hex form");
-				if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
-					return XPBD_SYSTEM_FAILURE;
 				state = ST_SKIPSPHEX;
+				dec_value_start = 0;
 				lp = lstart - 1;
 				continue;
 			default:
@@ -484,39 +470,54 @@ INTEGER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chun
 		}
 
 		/* Found extra non-numeric stuff */
-		ASN_DEBUG("Found non-numeric 0x%2x at %d",
-			lv, lp - lstart);
-		state = ST_EXTRASTUFF;
+		ASN_DEBUG("INTEGER :: Found non-numeric 0x%2x at %ld",
+			lv, (long)(lp - lstart));
+		state = ST_UNEXPECTED;
 		break;
 	}
 
 	switch(state) {
+	case ST_END_ENUM:
+		/* Got a complete and valid enumeration encoded as a tag. */
+		break;
 	case ST_DIGITS:
-		/* Everything is cool */
+		dec_value_end = lstop;
+		/* FALL THROUGH */
+	case ST_DIGITS_TRAILSPACE:
+		/* The last symbol encountered was a digit. */
+		switch(asn_strtol_lim(dec_value_start, &dec_value_end, &dec_value)) {
+		case ASN_STRTOL_OK:
+			break;
+		case ASN_STRTOL_ERROR_RANGE:
+			return XPBD_DECODER_LIMIT;
+		case ASN_STRTOL_ERROR_INVAL:
+		case ASN_STRTOL_EXPECT_MORE:
+		case ASN_STRTOL_EXTRA_DATA:
+			return XPBD_BROKEN_ENCODING;
+		}
 		break;
 	case ST_HEXCOLON:
+	case ST_HEXDIGITS_TRAILSPACE:
 		st->buf[st->size] = 0;	/* Just in case termination */
 		return XPBD_BODY_CONSUMED;
 	case ST_HEXDIGIT1:
 	case ST_HEXDIGIT2:
 	case ST_SKIPSPHEX:
 		return XPBD_BROKEN_ENCODING;
-	default:
-		if(xer_is_whitespace(lp, lstop - lp)) {
-			if(state != ST_EXTRASTUFF)
-				return XPBD_NOT_BODY_IGNORE;
-			break;
-		} else {
-			ASN_DEBUG("INTEGER: No useful digits (state %d)",
-				state);
-			return XPBD_BROKEN_ENCODING;	/* No digits */
-		}
-		break;
+	case ST_LEADSPACE:
+		/* Content not found */
+		return XPBD_NOT_BODY_IGNORE;
+	case ST_WAITDIGITS:
+	case ST_UNEXPECTED:
+		ASN_DEBUG("INTEGER: No useful digits (state %d)", state);
+		return XPBD_BROKEN_ENCODING;	/* No digits */
 	}
 
-	value *= sign;	/* Change sign, if needed */
-
-	if(asn_long2INTEGER(st, value))
+	/*
+	 * Convert the result of parsing of enumeration or a straight
+	 * decimal value into a BER representation.
+	 */
+	if(asn_long2INTEGER(st, dec_value))
 		return XPBD_SYSTEM_FAILURE;
 
 	return XPBD_BODY_CONSUMED;
@@ -543,17 +544,20 @@ INTEGER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	(void)flags;
 	
 	if(!st || !st->buf)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
-	if(er.encoded < 0) _ASN_ENCODE_FAILED;
+	if(er.encoded < 0) ASN__ENCODE_FAILED;
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
+#ifndef	ASN_DISABLE_PER_SUPPORT
+
 asn_dec_rval_t
 INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	asn_dec_rval_t rval = { RC_OK, 0 };
 	INTEGER_t *st = (INTEGER_t *)*sptr;
 	asn_per_constraint_t *ct;
@@ -563,7 +567,7 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 	if(!st) {
 		st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
-		if(!st) _ASN_DECODE_FAILED;
+		if(!st) ASN__DECODE_FAILED;
 	}
 
 	if(!constraints) constraints = td->per_constraints;
@@ -571,40 +575,55 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 	if(ct && ct->flags & APC_EXTENSIBLE) {
 		int inext = per_get_few_bits(pd, 1);
-		if(inext < 0) _ASN_DECODE_STARVED;
+		if(inext < 0) ASN__DECODE_STARVED;
 		if(inext) ct = 0;
 	}
 
 	FREEMEM(st->buf);
+	st->buf = 0;
+	st->size = 0;
 	if(ct) {
 		if(ct->flags & APC_SEMI_CONSTRAINED) {
 			st->buf = (uint8_t *)CALLOC(1, 2);
-			if(!st->buf) _ASN_DECODE_FAILED;
+			if(!st->buf) ASN__DECODE_FAILED;
 			st->size = 1;
 		} else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
 			size_t size = (ct->range_bits + 7) >> 3;
 			st->buf = (uint8_t *)MALLOC(1 + size + 1);
-			if(!st->buf) _ASN_DECODE_FAILED;
+			if(!st->buf) ASN__DECODE_FAILED;
 			st->size = size;
-		} else {
-			st->size = 0;
 		}
-	} else {
-		st->size = 0;
 	}
 
-	/* X.691, #12.2.2 */
+	/* X.691-2008/11, #13.2.2, constrained whole number */
 	if(ct && ct->flags != APC_UNCONSTRAINED) {
-		/* #10.5.6 */
+		/* #11.5.6 */
 		ASN_DEBUG("Integer with range %d bits", ct->range_bits);
 		if(ct->range_bits >= 0) {
-			long value = per_get_few_bits(pd, ct->range_bits);
-			if(value < 0) _ASN_DECODE_STARVED;
-			ASN_DEBUG("Got value %ld + low %ld",
-				value, ct->lower_bound);
-			value += ct->lower_bound;
-			if(asn_long2INTEGER(st, value))
-				_ASN_DECODE_FAILED;
+			if((size_t)ct->range_bits > 8 * sizeof(unsigned long))
+				ASN__DECODE_FAILED;
+
+			if(specs && specs->field_unsigned) {
+				unsigned long uvalue;
+				if(uper_get_constrained_whole_number(pd,
+					&uvalue, ct->range_bits))
+					ASN__DECODE_STARVED;
+				ASN_DEBUG("Got value %lu + low %ld",
+					uvalue, ct->lower_bound);
+				uvalue += ct->lower_bound;
+				if(asn_ulong2INTEGER(st, uvalue))
+					ASN__DECODE_FAILED;
+			} else {
+				unsigned long svalue;
+				if(uper_get_constrained_whole_number(pd,
+					&svalue, ct->range_bits))
+					ASN__DECODE_STARVED;
+				ASN_DEBUG("Got value %ld + low %ld",
+					svalue, ct->lower_bound);
+				svalue += ct->lower_bound;
+				if(asn_long2INTEGER(st, svalue))
+					ASN__DECODE_FAILED;
+			}
 			return rval;
 		}
 	} else {
@@ -619,14 +638,14 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 		/* Get the PER length */
 		len = uper_get_length(pd, -1, &repeat);
-		if(len < 0) _ASN_DECODE_STARVED;
+		if(len < 0) ASN__DECODE_STARVED;
 
 		p = REALLOC(st->buf, st->size + len + 1);
-		if(!p) _ASN_DECODE_FAILED;
+		if(!p) ASN__DECODE_FAILED;
 		st->buf = (uint8_t *)p;
 
 		ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
-		if(ret < 0) _ASN_DECODE_STARVED;
+		if(ret < 0) ASN__DECODE_STARVED;
 		st->size += len;
 	} while(repeat);
 	st->buf[st->size] = 0;	/* JIC */
@@ -638,9 +657,9 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		 */
 		long value;
 		if(asn_INTEGER2long(st, &value))
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 		if(asn_long2INTEGER(st, value + ct->lower_bound))
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 	}
 
 	return rval;
@@ -649,14 +668,16 @@ INTEGER_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 asn_enc_rval_t
 INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	asn_enc_rval_t er;
 	INTEGER_t *st = (INTEGER_t *)sptr;
 	const uint8_t *buf;
 	const uint8_t *end;
 	asn_per_constraint_t *ct;
 	long value = 0;
+	unsigned long v = 0;
 
-	if(!st || st->size == 0) _ASN_ENCODE_FAILED;
+	if(!st || st->size == 0) ASN__ENCODE_FAILED;
 
 	if(!constraints) constraints = td->per_constraints;
 	ct = constraints ? &constraints->value : 0;
@@ -665,60 +686,82 @@ INTEGER_encode_uper(asn_TYPE_descriptor_t *td,
 
 	if(ct) {
 		int inext = 0;
-		if(asn_INTEGER2long(st, &value))
-			_ASN_ENCODE_FAILED;
-		/* Check proper range */
-		if(ct->flags & APC_SEMI_CONSTRAINED) {
-			if(value < ct->lower_bound)
-				inext = 1;
-		} else if(ct->range_bits >= 0) {
-			if(value < ct->lower_bound
-			|| value > ct->upper_bound)
-				inext = 1;
+		if(specs && specs->field_unsigned) {
+			unsigned long uval;
+			if(asn_INTEGER2ulong(st, &uval))
+				ASN__ENCODE_FAILED;
+			/* Check proper range */
+			if(ct->flags & APC_SEMI_CONSTRAINED) {
+				if(uval < (unsigned long)ct->lower_bound)
+					inext = 1;
+			} else if(ct->range_bits >= 0) {
+				if(uval < (unsigned long)ct->lower_bound
+				|| uval > (unsigned long)ct->upper_bound)
+					inext = 1;
+			}
+			ASN_DEBUG("Value %lu (%02x/%d) lb %lu ub %lu %s",
+				uval, st->buf[0], st->size,
+				ct->lower_bound, ct->upper_bound,
+				inext ? "ext" : "fix");
+			value = uval;
+		} else {
+			if(asn_INTEGER2long(st, &value))
+				ASN__ENCODE_FAILED;
+			/* Check proper range */
+			if(ct->flags & APC_SEMI_CONSTRAINED) {
+				if(value < ct->lower_bound)
+					inext = 1;
+			} else if(ct->range_bits >= 0) {
+				if(value < ct->lower_bound
+				|| value > ct->upper_bound)
+					inext = 1;
+			}
+			ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s",
+				value, st->buf[0], st->size,
+				ct->lower_bound, ct->upper_bound,
+				inext ? "ext" : "fix");
 		}
-		ASN_DEBUG("Value %ld (%02x/%d) lb %ld ub %ld %s",
-			value, st->buf[0], st->size,
-			ct->lower_bound, ct->upper_bound,
-			inext ? "ext" : "fix");
 		if(ct->flags & APC_EXTENSIBLE) {
 			if(per_put_few_bits(po, inext, 1))
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 			if(inext) ct = 0;
 		} else if(inext) {
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 		}
 	}
 
 
-	/* X.691, #12.2.2 */
+	/* X.691-11/2008, #13.2.2, test if constrained whole number */
 	if(ct && ct->range_bits >= 0) {
-		/* #10.5.6 */
-		ASN_DEBUG("Encoding integer with range %d bits",
-			ct->range_bits);
-		if(per_put_few_bits(po, value - ct->lower_bound,
-				ct->range_bits))
-			_ASN_ENCODE_FAILED;
-		_ASN_ENCODED_OK(er);
+		/* #11.5.6 -> #11.3 */
+		ASN_DEBUG("Encoding integer %ld (%lu) with range %d bits",
+			value, value - ct->lower_bound, ct->range_bits);
+		v = value - ct->lower_bound;
+		if(uper_put_constrained_whole_number_u(po, v, ct->range_bits))
+			ASN__ENCODE_FAILED;
+		ASN__ENCODED_OK(er);
 	}
 
 	if(ct && ct->lower_bound) {
 		ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound);
 		/* TODO: adjust lower bound */
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	}
 
 	for(buf = st->buf, end = st->buf + st->size; buf < end;) {
 		ssize_t mayEncode = uper_put_length(po, end - buf);
 		if(mayEncode < 0)
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 		if(per_put_many_bits(po, buf, 8 * mayEncode))
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 		buf += mayEncode;
 	}
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
+#endif	/* ASN_DISABLE_PER_SUPPORT */
+
 int
 asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
 	uint8_t *b, *end;
@@ -779,6 +822,63 @@ asn_INTEGER2long(const INTEGER_t *iptr, long *lptr) {
 	return 0;
 }
 
+int
+asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *lptr) {
+	uint8_t *b, *end;
+	unsigned long l;
+	size_t size;
+
+	if(!iptr || !iptr->buf || !lptr) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	b = iptr->buf;
+	size = iptr->size;
+	end = b + size;
+
+	/* If all extra leading bytes are zeroes, ignore them */
+	for(; size > sizeof(unsigned long); b++, size--) {
+		if(*b) {
+			/* Value won't fit unsigned long */
+			errno = ERANGE;
+			return -1;
+		}
+	}
+
+	/* Conversion engine */
+	for(l = 0; b < end; b++)
+		l = (l << 8) | *b;
+
+	*lptr = l;
+	return 0;
+}
+
+int
+asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) {
+	uint8_t *buf;
+	uint8_t *end;
+	uint8_t *b;
+	int shr;
+
+	if(value <= LONG_MAX)
+		return asn_long2INTEGER(st, value);
+
+	buf = (uint8_t *)MALLOC(1 + sizeof(value));
+	if(!buf) return -1;
+
+	end = buf + (sizeof(value) + 1);
+	buf[0] = 0;
+	for(b = buf + 1, shr = (sizeof(long)-1)*8; b < end; shr -= 8, b++)
+		*b = (uint8_t)(value >> shr);
+
+	if(st->buf) FREEMEM(st->buf);
+	st->buf = buf;
+	st->size = 1 + sizeof(value);
+
+	return 0;
+}
+
 int
 asn_long2INTEGER(INTEGER_t *st, long value) {
 	uint8_t *buf, *bp;
@@ -833,3 +933,93 @@ asn_long2INTEGER(INTEGER_t *st, long value) {
 
 	return 0;
 }
+
+/*
+ * This function is going to be DEPRECATED soon.
+ */
+enum asn_strtol_result_e
+asn_strtol(const char *str, const char *end, long *lp) {
+    const char *endp = end;
+
+    switch(asn_strtol_lim(str, &endp, lp)) {
+    case ASN_STRTOL_ERROR_RANGE:
+        return ASN_STRTOL_ERROR_RANGE;
+    case ASN_STRTOL_ERROR_INVAL:
+        return ASN_STRTOL_ERROR_INVAL;
+    case ASN_STRTOL_EXPECT_MORE:
+        return ASN_STRTOL_ERROR_INVAL;  /* Retain old behavior */
+    case ASN_STRTOL_OK:
+        return ASN_STRTOL_OK;
+    case ASN_STRTOL_EXTRA_DATA:
+        return ASN_STRTOL_ERROR_INVAL;  /* Retain old behavior */
+    }
+
+    return ASN_STRTOL_ERROR_INVAL;  /* Retain old behavior */
+}
+
+/*
+ * Parse the number in the given string until the given *end position,
+ * returning the position after the last parsed character back using the
+ * same (*end) pointer.
+ * WARNING: This behavior is different from the standard strtol(3).
+ */
+enum asn_strtol_result_e
+asn_strtol_lim(const char *str, const char **end, long *lp) {
+	int sign = 1;
+	long l;
+
+	const long upper_boundary = LONG_MAX / 10;
+	long last_digit_max = LONG_MAX % 10;
+
+	if(str >= *end) return ASN_STRTOL_ERROR_INVAL;
+
+	switch(*str) {
+	case '-':
+		last_digit_max++;
+		sign = -1;
+		/* FALL THROUGH */
+	case '+':
+		str++;
+		if(str >= *end) {
+			*end = str;
+			return ASN_STRTOL_EXPECT_MORE;
+		}
+	}
+
+	for(l = 0; str < (*end); str++) {
+		switch(*str) {
+		case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
+		case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: {
+			int d = *str - '0';
+			if(l < upper_boundary) {
+				l = l * 10 + d;
+			} else if(l == upper_boundary) {
+				if(d <= last_digit_max) {
+					if(sign > 0) {
+						l = l * 10 + d;
+					} else {
+						sign = 1;
+						l = -l * 10 - d;
+					}
+				} else {
+					*end = str;
+					return ASN_STRTOL_ERROR_RANGE;
+				}
+			} else {
+				*end = str;
+				return ASN_STRTOL_ERROR_RANGE;
+			}
+		    }
+		    continue;
+		default:
+		    *end = str;
+		    *lp = sign * l;
+		    return ASN_STRTOL_EXTRA_DATA;
+		}
+	}
+
+	*end = str;
+	*lp = sign * l;
+	return ASN_STRTOL_OK;
+}
+
diff --git a/libs/smux/IfEntry.c b/libs/smux/IfEntry.c
index a97b2454..ad2e29d9 100644
--- a/libs/smux/IfEntry.c
+++ b/libs/smux/IfEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "IfEntry.h"
 
 static asn_TYPE_member_t asn_MBR_IfEntry_1[] = {
@@ -209,32 +207,32 @@ static asn_TYPE_member_t asn_MBR_IfEntry_1[] = {
 		"ifSpecific"
 		},
 };
-static ber_tlv_tag_t asn_DEF_IfEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_IfEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_IfEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 4 }, /* ifIndex at 78 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 3 }, /* ifType at 83 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 2 }, /* ifMtu at 85 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 6, -3, 1 }, /* ifAdminStatus at 91 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -4, 0 }, /* ifOperStatus at 93 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 1 }, /* ifDescr at 81 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 5, -1, 0 }, /* ifPhysAddress at 89 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 21, 0, 0 }, /* ifSpecific at 121 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, 0, 10 }, /* ifInOctets at 97 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -1, 9 }, /* ifInUcastPkts at 99 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 11, -2, 8 }, /* ifInNUcastPkts at 101 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 12, -3, 7 }, /* ifInDiscards at 103 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 13, -4, 6 }, /* ifInErrors at 105 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 14, -5, 5 }, /* ifInUnknownProtos at 107 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 15, -6, 4 }, /* ifOutOctets at 109 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 16, -7, 3 }, /* ifOutUcastPkts at 111 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 17, -8, 2 }, /* ifOutNUcastPkts at 113 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 18, -9, 1 }, /* ifOutDiscards at 115 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 19, -10, 0 }, /* ifOutErrors at 117 */
-    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 4, 0, 1 }, /* ifSpeed at 87 */
-    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 20, -1, 0 }, /* ifOutQLen at 119 */
-    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 8, 0, 0 } /* ifLastChange at 95 */
+static const asn_TYPE_tag2member_t asn_MAP_IfEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 4 }, /* ifIndex */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 3 }, /* ifType */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 2 }, /* ifMtu */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 6, -3, 1 }, /* ifAdminStatus */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -4, 0 }, /* ifOperStatus */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 1 }, /* ifDescr */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 5, -1, 0 }, /* ifPhysAddress */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 21, 0, 0 }, /* ifSpecific */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 9, 0, 10 }, /* ifInOctets */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 10, -1, 9 }, /* ifInUcastPkts */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 11, -2, 8 }, /* ifInNUcastPkts */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 12, -3, 7 }, /* ifInDiscards */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 13, -4, 6 }, /* ifInErrors */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 14, -5, 5 }, /* ifInUnknownProtos */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 15, -6, 4 }, /* ifOutOctets */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 16, -7, 3 }, /* ifOutUcastPkts */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 17, -8, 2 }, /* ifOutNUcastPkts */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 18, -9, 1 }, /* ifOutDiscards */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 19, -10, 0 }, /* ifOutErrors */
+    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 4, 0, 1 }, /* ifSpeed */
+    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 20, -1, 0 }, /* ifOutQLen */
+    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 8, 0, 0 } /* ifLastChange */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_IfEntry_specs_1 = {
 	sizeof(struct IfEntry),
diff --git a/libs/smux/IpAddrEntry.c b/libs/smux/IpAddrEntry.c
index 2cfdd1e0..bccd1550 100644
--- a/libs/smux/IpAddrEntry.c
+++ b/libs/smux/IpAddrEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "IpAddrEntry.h"
 
 static int
@@ -15,7 +13,7 @@ memb_ipAdEntReasmMaxSize_constraint_1(asn_TYPE_descriptor_t *td, const void *spt
 	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -27,7 +25,7 @@ memb_ipAdEntReasmMaxSize_constraint_1(asn_TYPE_descriptor_t *td, const void *spt
 		/* Constraint check succeeded */
 		return 0;
 	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: constraint failed (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -81,15 +79,15 @@ static asn_TYPE_member_t asn_MBR_IpAddrEntry_1[] = {
 		"ipAdEntReasmMaxSize"
 		},
 };
-static ber_tlv_tag_t asn_DEF_IpAddrEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_IpAddrEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_IpAddrEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 2 }, /* ipAdEntIfIndex at 177 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 1 }, /* ipAdEntBcastAddr at 181 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* ipAdEntReasmMaxSize at 183 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 1 }, /* ipAdEntAddr at 175 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, -1, 0 } /* ipAdEntNetMask at 179 */
+static const asn_TYPE_tag2member_t asn_MAP_IpAddrEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 2 }, /* ipAdEntIfIndex */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 1 }, /* ipAdEntBcastAddr */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* ipAdEntReasmMaxSize */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 1 }, /* ipAdEntAddr */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, -1, 0 } /* ipAdEntNetMask */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_IpAddrEntry_specs_1 = {
 	sizeof(struct IpAddrEntry),
diff --git a/libs/smux/IpAddress.c b/libs/smux/IpAddress.c
index 0b073d2d..2eaebf9b 100644
--- a/libs/smux/IpAddress.c
+++ b/libs/smux/IpAddress.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "IpAddress.h"
 
 int
@@ -16,7 +14,7 @@ IpAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 	size_t size;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -24,11 +22,11 @@ IpAddress_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 	
 	size = st->size;
 	
-	if(size == 4) {
+	if((size == 4)) {
 		/* Constraint check succeeded */
 		return 0;
 	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: constraint failed (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -43,6 +41,7 @@ static void
 IpAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_OCTET_STRING.free_struct;
 	td->print_struct   = asn_DEF_OCTET_STRING.print_struct;
+	td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
 	td->ber_decoder    = asn_DEF_OCTET_STRING.ber_decoder;
 	td->der_encoder    = asn_DEF_OCTET_STRING.der_encoder;
 	td->xer_decoder    = asn_DEF_OCTET_STRING.xer_decoder;
@@ -100,7 +99,7 @@ IpAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_IpAddress_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_IpAddress_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (0 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
 };
diff --git a/libs/smux/IpNetToMediaEntry.c b/libs/smux/IpNetToMediaEntry.c
index 92a723f4..ce6aa6d2 100644
--- a/libs/smux/IpNetToMediaEntry.c
+++ b/libs/smux/IpNetToMediaEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "IpNetToMediaEntry.h"
 
 static asn_TYPE_member_t asn_MBR_IpNetToMediaEntry_1[] = {
@@ -47,14 +45,14 @@ static asn_TYPE_member_t asn_MBR_IpNetToMediaEntry_1[] = {
 		"ipNetToMediaType"
 		},
 };
-static ber_tlv_tag_t asn_DEF_IpNetToMediaEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_IpNetToMediaEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_IpNetToMediaEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* ipNetToMediaIfIndex at 222 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* ipNetToMediaType at 229 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* ipNetToMediaPhysAddress at 224 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* ipNetToMediaNetAddress at 226 */
+static const asn_TYPE_tag2member_t asn_MAP_IpNetToMediaEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 1 }, /* ipNetToMediaIfIndex */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* ipNetToMediaType */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* ipNetToMediaPhysAddress */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 2, 0, 0 } /* ipNetToMediaNetAddress */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_IpNetToMediaEntry_specs_1 = {
 	sizeof(struct IpNetToMediaEntry),
diff --git a/libs/smux/IpRouteEntry.c b/libs/smux/IpRouteEntry.c
index 190f749e..5ee104ea 100644
--- a/libs/smux/IpRouteEntry.c
+++ b/libs/smux/IpRouteEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "IpRouteEntry.h"
 
 static asn_TYPE_member_t asn_MBR_IpRouteEntry_1[] = {
@@ -128,23 +126,23 @@ static asn_TYPE_member_t asn_MBR_IpRouteEntry_1[] = {
 		"ipRouteInfo"
 		},
 };
-static ber_tlv_tag_t asn_DEF_IpRouteEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_IpRouteEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_IpRouteEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 8 }, /* ipRouteIfIndex at 192 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 7 }, /* ipRouteMetric1 at 194 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 6 }, /* ipRouteMetric2 at 196 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -3, 5 }, /* ipRouteMetric3 at 198 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 5, -4, 4 }, /* ipRouteMetric4 at 200 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -5, 3 }, /* ipRouteType at 204 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 8, -6, 2 }, /* ipRouteProto at 206 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 9, -7, 1 }, /* ipRouteAge at 208 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -8, 0 }, /* ipRouteMetric5 at 212 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 12, 0, 0 }, /* ipRouteInfo at 215 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 2 }, /* ipRouteDest at 190 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 6, -1, 1 }, /* ipRouteNextHop at 202 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 10, -2, 0 } /* ipRouteMask at 210 */
+static const asn_TYPE_tag2member_t asn_MAP_IpRouteEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 8 }, /* ipRouteIfIndex */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 7 }, /* ipRouteMetric1 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -2, 6 }, /* ipRouteMetric2 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -3, 5 }, /* ipRouteMetric3 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 5, -4, 4 }, /* ipRouteMetric4 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 7, -5, 3 }, /* ipRouteType */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 8, -6, 2 }, /* ipRouteProto */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 9, -7, 1 }, /* ipRouteAge */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 11, -8, 0 }, /* ipRouteMetric5 */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 12, 0, 0 }, /* ipRouteInfo */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 2 }, /* ipRouteDest */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 6, -1, 1 }, /* ipRouteNextHop */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 10, -2, 0 } /* ipRouteMask */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_IpRouteEntry_specs_1 = {
 	sizeof(struct IpRouteEntry),
diff --git a/libs/smux/Message.c b/libs/smux/Message.c
index 545b426a..27ed3a2a 100644
--- a/libs/smux/Message.c
+++ b/libs/smux/Message.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "Message.h"
 
 static asn_TYPE_member_t asn_MBR_Message_1[] = {
@@ -38,12 +36,12 @@ static asn_TYPE_member_t asn_MBR_Message_1[] = {
 		"data"
 		},
 };
-static ber_tlv_tag_t asn_DEF_Message_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_Message_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_Message_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version at 18 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 } /* community at 22 */
+static const asn_TYPE_tag2member_t asn_MAP_Message_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 } /* community */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_Message_specs_1 = {
 	sizeof(struct Message),
diff --git a/libs/smux/NULL.c b/libs/smux/NULL.c
index 6d3316f1..62bc91e0 100644
--- a/libs/smux/NULL.c
+++ b/libs/smux/NULL.c
@@ -10,7 +10,7 @@
 /*
  * NULL basic type description.
  */
-static ber_tlv_tag_t asn_DEF_NULL_tags[] = {
+static const ber_tlv_tag_t asn_DEF_NULL_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_NULL = {
@@ -47,7 +47,7 @@ NULL_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
 		erval.structure_ptr = ptr;
 	}
 
-	_ASN_ENCODED_OK(erval);
+	ASN__ENCODED_OK(erval);
 }
 
 asn_enc_rval_t
@@ -65,7 +65,7 @@ NULL_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 
 	/* XMLNullValue is empty */
 	er.encoded = 0;
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
 
@@ -73,11 +73,15 @@ static enum xer_pbd_rval
 NULL__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const void *chunk_buf, size_t chunk_size) {
 	(void)td;
 	(void)sptr;
+	(void)chunk_buf;    /* Going to be empty according to the rules below. */
 
-	if(xer_is_whitespace(chunk_buf, chunk_size))
-		return XPBD_BODY_CONSUMED;
-	else
+	/*
+	 * There must be no content in self-terminating <NULL/> tag.
+	 */
+	if(chunk_size)
 		return XPBD_BROKEN_ENCODING;
+	else
+		return XPBD_BODY_CONSUMED;
 }
 
 asn_dec_rval_t
@@ -119,7 +123,7 @@ NULL_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		if(*sptr) {
 			*(NULL_t *)*sptr = 0;
 		} else {
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 		}
 	}
 
@@ -143,5 +147,5 @@ NULL_encode_uper(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
 	(void)po;
 
 	er.encoded = 0;
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
diff --git a/libs/smux/NativeEnumerated.c b/libs/smux/NativeEnumerated.c
index 3486cec1..78366af3 100644
--- a/libs/smux/NativeEnumerated.c
+++ b/libs/smux/NativeEnumerated.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2004, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 /*
@@ -15,7 +15,7 @@
 /*
  * NativeEnumerated basic type description.
  */
-static ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
+static const ber_tlv_tag_t asn_DEF_NativeEnumerated_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (10 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_NativeEnumerated = {
@@ -52,7 +52,7 @@ NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
         (void)ilevel;
         (void)flags;
 
-        if(!native) _ASN_ENCODE_FAILED;
+        if(!native) ASN__ENCODE_FAILED;
 
 	el = INTEGER_map_value2enum(specs, *native);
 	if(el) {
@@ -61,12 +61,12 @@ NativeEnumerated_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 
 		er.encoded = snprintf(src, srcsize, "<%s/>", el->enum_name);
 		assert(er.encoded > 0 && (size_t)er.encoded < srcsize);
-		if(cb(src, er.encoded, app_key) < 0) _ASN_ENCODE_FAILED;
-		_ASN_ENCODED_OK(er);
+		if(cb(src, er.encoded, app_key) < 0) ASN__ENCODE_FAILED;
+		ASN__ENCODED_OK(er);
 	} else {
 		ASN_DEBUG("ASN.1 forbids dealing with "
 			"unknown value of ENUMERATED type");
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	}
 }
 
@@ -84,39 +84,39 @@ NativeEnumerated_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 
 	if(constraints) ct = &constraints->value;
 	else if(td->per_constraints) ct = &td->per_constraints->value;
-	else _ASN_DECODE_FAILED;	/* Mandatory! */
-	if(!specs) _ASN_DECODE_FAILED;
+	else ASN__DECODE_FAILED;	/* Mandatory! */
+	if(!specs) ASN__DECODE_FAILED;
 
 	if(!native) {
 		native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
-		if(!native) _ASN_DECODE_FAILED;
+		if(!native) ASN__DECODE_FAILED;
 	}
 
 	ASN_DEBUG("Decoding %s as NativeEnumerated", td->name);
 
 	if(ct->flags & APC_EXTENSIBLE) {
 		int inext = per_get_few_bits(pd, 1);
-		if(inext < 0) _ASN_DECODE_STARVED;
+		if(inext < 0) ASN__DECODE_STARVED;
 		if(inext) ct = 0;
 	}
 
 	if(ct && ct->range_bits >= 0) {
 		value = per_get_few_bits(pd, ct->range_bits);
-		if(value < 0) _ASN_DECODE_STARVED;
+		if(value < 0) ASN__DECODE_STARVED;
 		if(value >= (specs->extension
 			? specs->extension - 1 : specs->map_count))
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 	} else {
 		if(!specs->extension)
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 		/*
 		 * X.691, #10.6: normally small non-negative whole number;
 		 */
 		value = uper_get_nsnnwn(pd);
-		if(value < 0) _ASN_DECODE_STARVED;
+		if(value < 0) ASN__DECODE_STARVED;
 		value += specs->extension - 1;
 		if(value >= specs->map_count)
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 	}
 
 	*native = specs->value2enum[value].nat_value;
@@ -142,63 +142,66 @@ NativeEnumerated_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_INTEGER_specifics_t *specs = (asn_INTEGER_specifics_t *)td->specifics;
 	asn_enc_rval_t er;
 	long native, value;
-	asn_per_constraint_t *ct = NULL;
+	asn_per_constraint_t *ct;
 	int inext = 0;
 	asn_INTEGER_enum_map_t key;
-	asn_INTEGER_enum_map_t *kf;
+	const asn_INTEGER_enum_map_t *kf;
 
-	if(!sptr) _ASN_ENCODE_FAILED;
-	if(!specs) _ASN_ENCODE_FAILED;
+	if(!sptr) ASN__ENCODE_FAILED;
+	if(!specs) ASN__ENCODE_FAILED;
 
 	if(constraints) ct = &constraints->value;
 	else if(td->per_constraints) ct = &td->per_constraints->value;
-	else _ASN_ENCODE_FAILED;	/* Mandatory! */
+	else ASN__ENCODE_FAILED;	/* Mandatory! */
 
 	ASN_DEBUG("Encoding %s as NativeEnumerated", td->name);
 
 	er.encoded = 0;
 
 	native = *(long *)sptr;
-	if(native < 0) _ASN_ENCODE_FAILED;
+	if(native < 0) ASN__ENCODE_FAILED;
 
 	key.nat_value = native;
 	kf = bsearch(&key, specs->value2enum, specs->map_count,
 		sizeof(key), NativeEnumerated__compar_value2enum);
 	if(!kf) {
 		ASN_DEBUG("No element corresponds to %ld", native);
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	}
 	value = kf - specs->value2enum;
 
-	if(ct && ct->range_bits >= 0) {
+	if(ct->range_bits >= 0) {
 		int cmpWith = specs->extension
 				? specs->extension - 1 : specs->map_count;
 		if(value >= cmpWith)
 			inext = 1;
 	}
-	if(ct && ct->flags & APC_EXTENSIBLE) {
-		if(per_put_few_bits(po, inext, 0))
-			_ASN_ENCODE_FAILED;
-		ct = 0;
+	if(ct->flags & APC_EXTENSIBLE) {
+		if(per_put_few_bits(po, inext, 1))
+			ASN__ENCODE_FAILED;
+		if(inext) ct = 0;
 	} else if(inext) {
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	}
 
 	if(ct && ct->range_bits >= 0) {
 		if(per_put_few_bits(po, value, ct->range_bits))
-			_ASN_ENCODE_FAILED;
-		_ASN_ENCODED_OK(er);
+			ASN__ENCODE_FAILED;
+		ASN__ENCODED_OK(er);
 	}
 
 	if(!specs->extension)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	/*
 	 * X.691, #10.6: normally small non-negative whole number;
 	 */
-	if(uper_put_nsnnwn(po, value - (specs->extension - 1)))
-		_ASN_ENCODE_FAILED;
+	ASN_DEBUG("value = %ld, ext = %d, inext = %d, res = %ld",
+		value, specs->extension, inext,
+		value - (inext ? (specs->extension - 1) : 0));
+	if(uper_put_nsnnwn(po, value - (inext ? (specs->extension - 1) : 0)))
+		ASN__ENCODE_FAILED;
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
diff --git a/libs/smux/NativeInteger.c b/libs/smux/NativeInteger.c
index db234c8b..e8ce6d2c 100644
--- a/libs/smux/NativeInteger.c
+++ b/libs/smux/NativeInteger.c
@@ -16,7 +16,7 @@
 /*
  * NativeInteger basic type description.
  */
-static ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
+static const ber_tlv_tag_t asn_DEF_NativeInteger_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_NativeInteger = {
@@ -48,6 +48,7 @@ asn_dec_rval_t
 NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td,
 	void **nint_ptr, const void *buf_ptr, size_t size, int tag_mode) {
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	long *native = (long *)*nint_ptr;
 	asn_dec_rval_t rval;
 	ber_tlv_len_t length;
@@ -105,7 +106,9 @@ NativeInteger_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 		tmp.buf = (uint8_t *)unconst_buf.nonconstbuf;
 		tmp.size = length;
 
-		if(asn_INTEGER2long(&tmp, &l)) {
+		if((specs&&specs->field_unsigned)
+			? asn_INTEGER2ulong(&tmp, (unsigned long *)&l) /* sic */
+			: asn_INTEGER2long(&tmp, &l)) {
 			rval.code = RC_FAIL;
 			rval.consumed = 0;
 			return rval;
@@ -145,7 +148,7 @@ NativeInteger_encode_der(asn_TYPE_descriptor_t *sd, void *ptr,
 
 	/* Prepare a fake INTEGER */
 	for(p = buf + sizeof(buf) - 1; p >= buf; p--, native >>= 8)
-		*p = native;
+		*p = (uint8_t)native;
 
 	tmp.buf = buf;
 	tmp.size = sizeof(buf);
@@ -167,6 +170,7 @@ asn_dec_rval_t
 NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td, void **sptr, const char *opt_mname,
 		const void *buf_ptr, size_t size) {
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	asn_dec_rval_t rval;
 	INTEGER_t st;
 	void *st_ptr = (void *)&st;
@@ -174,7 +178,7 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
 
 	if(!native) {
 		native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
-		if(!native) _ASN_DECODE_FAILED;
+		if(!native) ASN__DECODE_FAILED;
 	}
 
 	memset(&st, 0, sizeof(st));
@@ -182,7 +186,9 @@ NativeInteger_decode_xer(asn_codec_ctx_t *opt_codec_ctx,
 		opt_mname, buf_ptr, size);
 	if(rval.code == RC_OK) {
 		long l;
-		if(asn_INTEGER2long(&st, &l)) {
+		if((specs&&specs->field_unsigned)
+			? asn_INTEGER2ulong(&st, (unsigned long *)&l) /* sic */
+			: asn_INTEGER2long(&st, &l)) {
 			rval.code = RC_FAIL;
 			rval.consumed = 0;
 		} else {
@@ -205,6 +211,7 @@ asn_enc_rval_t
 NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	int ilevel, enum xer_encoder_flags_e flags,
 		asn_app_consume_bytes_f *cb, void *app_key) {
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	char scratch[32];	/* Enough for 64-bit int */
 	asn_enc_rval_t er;
 	const long *native = (const long *)sptr;
@@ -212,14 +219,16 @@ NativeInteger_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	(void)ilevel;
 	(void)flags;
 
-	if(!native) _ASN_ENCODE_FAILED;
+	if(!native) ASN__ENCODE_FAILED;
 
-	er.encoded = snprintf(scratch, sizeof(scratch), "%ld", *native);
+	er.encoded = snprintf(scratch, sizeof(scratch),
+			(specs && specs->field_unsigned)
+			? "%lu" : "%ld", *native);
 	if(er.encoded <= 0 || (size_t)er.encoded >= sizeof(scratch)
 		|| cb(scratch, er.encoded, app_key) < 0)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
 asn_dec_rval_t
@@ -227,6 +236,7 @@ NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td,
 	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
 
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	asn_dec_rval_t rval;
 	long *native = (long *)*sptr;
 	INTEGER_t tmpint;
@@ -237,14 +247,16 @@ NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 
 	if(!native) {
 		native = (long *)(*sptr = CALLOC(1, sizeof(*native)));
-		if(!native) _ASN_DECODE_FAILED;
+		if(!native) ASN__DECODE_FAILED;
 	}
 
 	memset(&tmpint, 0, sizeof tmpint);
 	rval = INTEGER_decode_uper(opt_codec_ctx, td, constraints,
 				   &tmpintptr, pd);
 	if(rval.code == RC_OK) {
-		if(asn_INTEGER2long(&tmpint, native))
+		if((specs&&specs->field_unsigned)
+			? asn_INTEGER2ulong(&tmpint, (unsigned long *)native)
+			: asn_INTEGER2long(&tmpint, native))
 			rval.code = RC_FAIL;
 		else
 			ASN_DEBUG("NativeInteger %s got value %ld",
@@ -258,19 +270,22 @@ NativeInteger_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 asn_enc_rval_t
 NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	asn_enc_rval_t er;
 	long native;
 	INTEGER_t tmpint;
 
-	if(!sptr) _ASN_ENCODE_FAILED;
+	if(!sptr) ASN__ENCODE_FAILED;
 
 	native = *(long *)sptr;
 
 	ASN_DEBUG("Encoding NativeInteger %s %ld (UPER)", td->name, native);
 
 	memset(&tmpint, 0, sizeof(tmpint));
-	if(asn_long2INTEGER(&tmpint, native))
-		_ASN_ENCODE_FAILED;
+	if((specs&&specs->field_unsigned)
+		? asn_ulong2INTEGER(&tmpint, native)
+		: asn_long2INTEGER(&tmpint, native))
+		ASN__ENCODE_FAILED;
 	er = INTEGER_encode_uper(td, constraints, &tmpint, po);
 	ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_INTEGER, &tmpint);
 	return er;
@@ -282,14 +297,18 @@ NativeInteger_encode_uper(asn_TYPE_descriptor_t *td,
 int
 NativeInteger_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 	asn_app_consume_bytes_f *cb, void *app_key) {
+	asn_INTEGER_specifics_t *specs=(asn_INTEGER_specifics_t *)td->specifics;
 	const long *native = (const long *)sptr;
+	char scratch[32];	/* Enough for 64-bit int */
+	int ret;
 
 	(void)td;	/* Unused argument */
 	(void)ilevel;	/* Unused argument */
 
 	if(native) {
-		char scratch[32];	/* Enough for 64-bit int */
-		int ret = snprintf(scratch, sizeof(scratch), "%ld", *native);
+		ret = snprintf(scratch, sizeof(scratch),
+			(specs && specs->field_unsigned)
+			? "%lu" : "%ld", *native);
 		assert(ret > 0 && (size_t)ret < sizeof(scratch));
 		return (cb(scratch, ret, app_key) < 0) ? -1 : 0;
 	} else {
diff --git a/libs/smux/NetworkAddress.c b/libs/smux/NetworkAddress.c
index 2d167746..3a65001d 100644
--- a/libs/smux/NetworkAddress.c
+++ b/libs/smux/NetworkAddress.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "NetworkAddress.h"
 
 static asn_TYPE_member_t asn_MBR_NetworkAddress_1[] = {
@@ -20,8 +18,8 @@ static asn_TYPE_member_t asn_MBR_NetworkAddress_1[] = {
 		"internet"
 		},
 };
-static asn_TYPE_tag2member_t asn_MAP_NetworkAddress_tag2el_1[] = {
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* internet at 113 */
+static const asn_TYPE_tag2member_t asn_MAP_NetworkAddress_tag2el_1[] = {
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* internet */
 };
 static asn_CHOICE_specifics_t asn_SPC_NetworkAddress_specs_1 = {
 	sizeof(struct NetworkAddress),
diff --git a/libs/smux/OBJECT_IDENTIFIER.c b/libs/smux/OBJECT_IDENTIFIER.c
index d0367f0f..d0f8b311 100644
--- a/libs/smux/OBJECT_IDENTIFIER.c
+++ b/libs/smux/OBJECT_IDENTIFIER.c
@@ -3,14 +3,16 @@
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #include <asn_internal.h>
+#include <INTEGER.h>
 #include <OBJECT_IDENTIFIER.h>
+#include <OCTET_STRING.h>
 #include <limits.h>	/* for CHAR_BIT */
 #include <errno.h>
 
 /*
  * OBJECT IDENTIFIER basic type description.
  */
-static ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
+static const ber_tlv_tag_t asn_DEF_OBJECT_IDENTIFIER_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
@@ -23,7 +25,8 @@ asn_TYPE_descriptor_t asn_DEF_OBJECT_IDENTIFIER = {
 	der_encode_primitive,
 	OBJECT_IDENTIFIER_decode_xer,
 	OBJECT_IDENTIFIER_encode_xer,
-	0, 0,
+	OCTET_STRING_decode_uper,
+	OCTET_STRING_encode_uper,
 	0, /* Use generic outmost tag fetcher */
 	asn_DEF_OBJECT_IDENTIFIER_tags,
 	sizeof(asn_DEF_OBJECT_IDENTIFIER_tags)
@@ -44,14 +47,14 @@ OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 
 	if(st && st->buf) {
 		if(st->size < 1) {
-			_ASN_CTFAIL(app_key, td,
+			ASN__CTFAIL(app_key, td, sptr,
 				"%s: at least one numerical value "
 				"expected (%s:%d)",
 				td->name, __FILE__, __LINE__);
 			return -1;
 		}
 	} else {
-		_ASN_CTFAIL(app_key, td,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -62,9 +65,9 @@ OBJECT_IDENTIFIER_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 
 
 int
-OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) {
-	unsigned LE __attribute__ ((unused)) = 1; /* Little endian (x86) */
-	uint8_t *arcend = arcbuf + arclen;	/* End of arc */
+OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbufp, unsigned int rvsize) {
+	unsigned LE GCC_NOTUSED = 1; /* Little endian (x86) */
+	const uint8_t *arcend = arcbuf + arclen;	/* End of arc */
 	unsigned int cache = 0;	/* No more than 14 significant bits */
 	unsigned char *rvbuf = (unsigned char *)rvbufp;
 	unsigned char *rvstart = rvbuf;	/* Original start of the value buffer */
@@ -117,7 +120,7 @@ OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed in
 			errno = ERANGE;	/* Overflow */
 			return -1;
 		}
-		*(unsigned long *)rvbuf = accum + add;	/* alignment OK! */
+		*(unsigned long *)(void *)rvbuf = accum + add;	/* alignment OK! */
 		return 0;
 	}
 
@@ -159,7 +162,7 @@ OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed in
 	if(add) {
 		for(rvbuf -= inc; rvbuf != rvstart; rvbuf -= inc) {
 			int v = add + *rvbuf;
-			if(v & (-1 << CHAR_BIT)) {
+			if(v & ((unsigned)~0 << CHAR_BIT)) {
 				*rvbuf = (unsigned char)(v + (1 << CHAR_BIT));
 				add = -1;
 			} else {
@@ -178,10 +181,11 @@ OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed in
 }
 
 ssize_t
-OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
+OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
 		asn_app_consume_bytes_f *cb, void *app_key) {
 	char scratch[64];	/* Conservative estimate */
 	unsigned long accum;	/* Bits accumulator */
+	char *p;		/* Position in the scratch buffer */
 
 	if(OBJECT_IDENTIFIER_get_single_arc(arcbuf, arclen, add,
 			&accum, sizeof(accum)))
@@ -189,8 +193,9 @@ OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
 
 	if(accum) {
 		ssize_t len;
-		char *p = scratch + sizeof(scratch);		/* Position in the scratch buffer */
 
+		/* Fill the scratch buffer in reverse. */
+		p = scratch + sizeof(scratch);
 		for(; accum; accum /= 10)
 			*(--p) = (char)(accum % 10) + 0x30; /* Put a digit */
 
@@ -207,7 +212,7 @@ OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
 }
 
 int
-OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen, int add,
+OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen, int add,
 		asn_app_consume_bytes_f *cb, void *app_key) {
 
 	if(OBJECT_IDENTIFIER__dump_arc(arcbuf, arclen, add, cb, app_key) < 0)
@@ -277,15 +282,13 @@ OBJECT_IDENTIFIER__xer_body_decode(asn_TYPE_descriptor_t *td, void *sptr, const
 	arcs_count = OBJECT_IDENTIFIER_parse_arcs(
 		(const char *)chunk_buf, chunk_size, arcs,
 			sizeof(s_arcs)/sizeof(s_arcs[0]), &endptr);
-	if(arcs_count <= 0) {
+	if(arcs_count < 0) {
 		/* Expecting more than zero arcs */
 		return XPBD_BROKEN_ENCODING;
+	} else if(arcs_count == 0) {
+		return XPBD_NOT_BODY_IGNORE;
 	}
-	if(endptr < chunk_end) {
-		/* We have a tail of unrecognized data. Check its safety. */
-		if(!xer_is_whitespace(endptr, chunk_end - endptr))
-			return XPBD_BROKEN_ENCODING;
-	}
+	assert(endptr == chunk_end);
 
 	if((size_t)arcs_count > sizeof(s_arcs)/sizeof(s_arcs[0])) {
 		arcs = (long *)MALLOC(arcs_count * sizeof(long));
@@ -327,12 +330,12 @@ OBJECT_IDENTIFIER_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	(void)flags;
 
 	if(!st || !st->buf)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	er.encoded = OBJECT_IDENTIFIER__dump_body(st, cb, app_key);
-	if(er.encoded < 0) _ASN_ENCODE_FAILED;
+	if(er.encoded < 0) ASN__ENCODE_FAILED;
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
 int
@@ -357,7 +360,7 @@ OBJECT_IDENTIFIER_print(asn_TYPE_descriptor_t *td, const void *sptr,
 }
 
 int
-OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *oid, void *arcs,
+OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *oid, void *arcs,
 		unsigned int arc_type_size, unsigned int arc_slots) {
 	void *arcs_end = (char *)arcs + (arc_type_size * arc_slots);
 	int num_arcs = 0;
@@ -645,12 +648,12 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
 	long *arcs, unsigned int arcs_slots, const char **opt_oid_text_end) {
 	unsigned int arcs_count = 0;
 	const char *oid_end;
-	long value = 0;
 	enum {
-		ST_SKIPSPACE,
-		ST_WAITDIGITS,	/* Next character is expected to be a digit */
-		ST_DIGITS
-	} state = ST_SKIPSPACE;
+		ST_LEADSPACE,
+		ST_TAILSPACE,
+		ST_AFTERVALUE,	/* Next character ought to be '.' or a space */
+		ST_WAITDIGITS 	/* Next character is expected to be a digit */
+	} state = ST_LEADSPACE;
 
 	if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) {
 		if(opt_oid_text_end) *opt_oid_text_end = oid_text;
@@ -661,41 +664,76 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
 	if(oid_txt_length == -1)
 		oid_txt_length = strlen(oid_text);
 
+#define	_OID_CAPTURE_ARC(oid_text, oid_end)		do {	\
+	const char *endp = oid_end;				\
+	long value;						\
+	switch(asn_strtol_lim(oid_text, &endp, &value)) {	\
+	case ASN_STRTOL_EXTRA_DATA:				\
+	case ASN_STRTOL_OK:					\
+		if(arcs_count < arcs_slots)			\
+			arcs[arcs_count] = value;		\
+		arcs_count++;					\
+		oid_text = endp - 1;				\
+		break;						\
+	case ASN_STRTOL_ERROR_RANGE:				\
+		if(opt_oid_text_end)				\
+			*opt_oid_text_end = oid_text;		\
+		errno = ERANGE;					\
+		return -1;					\
+	case ASN_STRTOL_ERROR_INVAL:				\
+	case ASN_STRTOL_EXPECT_MORE:				\
+		if(opt_oid_text_end)				\
+			*opt_oid_text_end = oid_text;		\
+		errno = EINVAL;					\
+		return -1;					\
+	}							\
+  } while(0)
+
 	for(oid_end = oid_text + oid_txt_length; oid_text<oid_end; oid_text++) {
 	    switch(*oid_text) {
 	    case 0x09: case 0x0a: case 0x0d: case 0x20:	/* whitespace */
-		if(state == ST_SKIPSPACE) {
+		switch(state) {
+		case ST_LEADSPACE:
+		case ST_TAILSPACE:
 			continue;
-		} else {
-			break;	/* Finish */
+		case ST_AFTERVALUE:
+			state = ST_TAILSPACE;
+			continue;
+		case ST_WAITDIGITS:
+			break;	/* Digits expected after ".", got whitespace */
 		}
+		break;
 	    case 0x2e:	/* '.' */
-		if(state != ST_DIGITS
-		|| (oid_text + 1) == oid_end) {
-			state = ST_WAITDIGITS;
+		switch(state) {
+		case ST_LEADSPACE:
+		case ST_TAILSPACE:
+		case ST_WAITDIGITS:
+			if(opt_oid_text_end)
+				*opt_oid_text_end = oid_text;
+			errno = EINVAL;	/* Broken OID */
+			return -1;
 			break;
+		case ST_AFTERVALUE:
+			state = ST_WAITDIGITS;
+			continue;
 		}
-		if(arcs_count < arcs_slots)
-			arcs[arcs_count] = value;
-		arcs_count++;
-		state = ST_WAITDIGITS;
-		continue;
+		break;
 	    case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
 	    case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
-		if(state != ST_DIGITS) {
-			state = ST_DIGITS;
-			value = 0;
-		}
-		if(1) {
-			long new_value = value * 10;
-			if(new_value / 10 != value
-			|| (value = new_value + (*oid_text - 0x30)) < 0) {
-				/* Overflow */
-				state = ST_WAITDIGITS;
-				break;
-			}
+		switch(state) {
+		case ST_TAILSPACE:
+		case ST_AFTERVALUE:
+			if(opt_oid_text_end)
+				*opt_oid_text_end = oid_text;
+			errno = EINVAL;	/* "1. 1" => broken OID */
+			return -1;
+		case ST_LEADSPACE:
+		case ST_WAITDIGITS:
+			_OID_CAPTURE_ARC(oid_text, oid_end);
+			state = ST_AFTERVALUE;
 			continue;
 		}
+		break;
 	    default:
 		/* Unexpected symbols */
 		state = ST_WAITDIGITS;
@@ -709,17 +747,18 @@ OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
 
 	/* Finalize last arc */
 	switch(state) {
+	case ST_LEADSPACE:
+		return 0; /* No OID found in input data */
 	case ST_WAITDIGITS:
-		errno = EINVAL;
+		errno = EINVAL;	/* Broken OID */
 		return -1;
-	case ST_DIGITS:
-		if(arcs_count < arcs_slots)
-			arcs[arcs_count] = value;
-		arcs_count++;
-		/* Fall through */
-	default:
+	case ST_AFTERVALUE:
+	case ST_TAILSPACE:
 		return arcs_count;
 	}
+
+	errno = EINVAL;	/* Broken OID */
+	return -1;
 }
 
 
diff --git a/libs/smux/OCTET_STRING.c b/libs/smux/OCTET_STRING.c
index 9e9694b5..5420dede 100644
--- a/libs/smux/OCTET_STRING.c
+++ b/libs/smux/OCTET_STRING.c
@@ -11,16 +11,18 @@
 /*
  * OCTET STRING basic type description.
  */
-static ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
+static const ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
 };
-static asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
+static const asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
 	sizeof(OCTET_STRING_t),
 	offsetof(OCTET_STRING_t, _asn_ctx),
-	0
+	ASN_OSUBV_STR
 };
-static asn_per_constraint_t asn_DEF_OCTET_STRING_constraint = {
-	APC_SEMI_CONSTRAINED, -1, -1, 0, 0
+static const asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
+	{ APC_CONSTRAINED, 8, 8, 0, 255 },
+	{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
+	0, 0
 };
 asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
 	"OCTET STRING",		/* Canonical name */
@@ -102,15 +104,6 @@ asn_TYPE_descriptor_t asn_DEF_OCTET_STRING = {
 		st->size = _es;						\
 	} while(0)
 
-/*
- * Internal variant of the OCTET STRING.
- */
-typedef enum OS_type {
-	_TT_GENERIC	= 0,	/* Just a random OCTET STRING */
-	_TT_BIT_STRING	= 1,	/* BIT STRING type, a special case */
-	_TT_ANY		= 2	/* ANY type, a special case too */
-} OS_type_e;
-
 /*
  * The main reason why ASN.1 is still alive is that too much time and effort
  * is necessary for learning it more or less adequately, thus creating a gut
@@ -185,11 +178,11 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 	struct _stack *stck;		/* Expectations stack structure */
 	struct _stack_el *sel = 0;	/* Stack element */
 	int tlv_constr;
-	OS_type_e type_variant = (OS_type_e)specs->subvariant;
+	enum asn_OS_Subvariant type_variant = specs->subvariant;
 
 	ASN_DEBUG("Decoding %s as %s (frame %ld)",
 		td->name,
-		(type_variant == _TT_GENERIC) ?
+		(type_variant == ASN_OSUBV_STR) ?
 			"OCTET STRING" : "OS-SpecialCase",
 		(long)size);
 
@@ -230,7 +223,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 			 * Jump into stackless primitive decoding.
 			 */
 			_CH_PHASE(ctx, 3);
-			if(type_variant == _TT_ANY && tag_mode != 1)
+			if(type_variant == ASN_OSUBV_ANY && tag_mode != 1)
 				APPEND(buf_ptr, rval.consumed);
 			ADVANCE(rval.consumed);
 			goto phase3;
@@ -309,7 +302,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 
 			ASN_DEBUG("Eat EOC; wn=%d--", sel->want_nulls);
 
-			if(type_variant == _TT_ANY
+			if(type_variant == ASN_OSUBV_ANY
 			&& (tag_mode != 1 || sel->cont_level))
 				APPEND("\0\0", 2);
 
@@ -334,10 +327,10 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 		 * depending on ASN.1 type being decoded.
 		 */
 		switch(type_variant) {
-		case _TT_BIT_STRING:
+		case ASN_OSUBV_BIT:
 			/* X.690: 8.6.4.1, NOTE 2 */
 			/* Fall through */
-		case _TT_GENERIC:
+		case ASN_OSUBV_STR:
 		default:
 			if(sel) {
 				int level = sel->cont_level;
@@ -352,7 +345,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 				/* else, Fall through */
 			}
 			/* Fall through */
-		case _TT_ANY:
+		case ASN_OSUBV_ANY:
 			expected_tag = tlv_tag;
 			break;
 		}
@@ -397,7 +390,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 		} else {
 			sel->left = tlv_len;
 		}
-		if(type_variant == _TT_ANY
+		if(type_variant == ASN_OSUBV_ANY
 		&& (tag_mode != 1 || sel->cont_level))
 			APPEND(buf_ptr, tlvl);
 		sel->got += tlvl;
@@ -431,7 +424,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 		len = ((ber_tlv_len_t)size < sel->left)
 				? (ber_tlv_len_t)size : sel->left;
 		if(len > 0) {
-			if(type_variant == _TT_BIT_STRING
+			if(type_variant == ASN_OSUBV_BIT
 			&& sel->bits_chopped == 0) {
 				/* Put the unused-bits-octet away */
 				st->bits_unused = *(const uint8_t *)buf_ptr;
@@ -464,7 +457,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 
 		if(size < (size_t)ctx->left) {
 			if(!size) RETURN(RC_WMORE);
-			if(type_variant == _TT_BIT_STRING && !ctx->context) {
+			if(type_variant == ASN_OSUBV_BIT && !ctx->context) {
 				st->bits_unused = *(const uint8_t *)buf_ptr;
 				ctx->left--;
 				ADVANCE(1);
@@ -475,7 +468,7 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 			ADVANCE(size);
 			RETURN(RC_WMORE);
 		} else {
-			if(type_variant == _TT_BIT_STRING
+			if(type_variant == ASN_OSUBV_BIT
 			&& !ctx->context && ctx->left) {
 				st->bits_unused = *(const uint8_t *)buf_ptr;
 				ctx->left--;
@@ -502,14 +495,14 @@ OCTET_STRING_decode_ber(asn_codec_ctx_t *opt_codec_ctx,
 	/*
 	 * BIT STRING-specific processing.
 	 */
-	if(type_variant == _TT_BIT_STRING && st->size) {
+	if(type_variant == ASN_OSUBV_BIT && st->size) {
 		/* Finalize BIT STRING: zero out unused bits. */
 		st->buf[st->size-1] &= 0xff << st->bits_unused;
 	}
 
 	ASN_DEBUG("Took %ld bytes to encode %s: [%s]:%ld",
 		(long)consumed_myself, td->name,
-		(type_variant == _TT_GENERIC) ? (char *)st->buf : "<data>",
+		(type_variant == ASN_OSUBV_STR) ? (char *)st->buf : "<data>",
 		(long)st->size);
 
 
@@ -528,7 +521,7 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 				? (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;
+	enum asn_OS_Subvariant type_variant = specs->subvariant;
 	int fix_last_byte = 0;
 
 	ASN_DEBUG("%s %s as OCTET STRING",
@@ -537,10 +530,11 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 	/*
 	 * Write tags.
 	 */
-	if(type_variant != _TT_ANY || tag_mode == 1) {
+	if(type_variant != ASN_OSUBV_ANY || tag_mode == 1) {
 		er.encoded = der_write_tags(td,
-				(type_variant == _TT_BIT_STRING) + st->size,
-			tag_mode, type_variant == _TT_ANY, tag, cb, app_key);
+				(type_variant == ASN_OSUBV_BIT) + st->size,
+			tag_mode, type_variant == ASN_OSUBV_ANY, tag,
+			cb, app_key);
 		if(er.encoded == -1) {
 			er.failed_type = td;
 			er.structure_ptr = sptr;
@@ -548,54 +542,55 @@ OCTET_STRING_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 		}
 	} else {
 		/* Disallow: [<tag>] IMPLICIT ANY */
-		assert(type_variant != _TT_ANY || tag_mode != -1);
+		assert(type_variant != ASN_OSUBV_ANY || tag_mode != -1);
 		er.encoded = 0;
 	}
 
 	if(!cb) {
-		er.encoded += (type_variant == _TT_BIT_STRING) + st->size;
-		_ASN_ENCODED_OK(er);
+		er.encoded += (type_variant == ASN_OSUBV_BIT) + st->size;
+		ASN__ENCODED_OK(er);
 	}
 
 	/*
 	 * Prepare to deal with the last octet of BIT STRING.
 	 */
-	if(type_variant == _TT_BIT_STRING) {
+	if(type_variant == ASN_OSUBV_BIT) {
 		uint8_t b = st->bits_unused & 0x07;
 		if(b && st->size) fix_last_byte = 1;
-		_ASN_CALLBACK(&b, 1);
+		ASN__CALLBACK(&b, 1);
 		er.encoded++;
 	}
 
 	/* Invoke callback for the main part of the buffer */
-	_ASN_CALLBACK(st->buf, st->size - fix_last_byte);
+	ASN__CALLBACK(st->buf, st->size - fix_last_byte);
 
 	/* The last octet should be stripped off the unused bits */
 	if(fix_last_byte) {
 		uint8_t b = st->buf[st->size-1] & (0xff << st->bits_unused);
-		_ASN_CALLBACK(&b, 1);
+		ASN__CALLBACK(&b, 1);
 	}
 
 	er.encoded += st->size;
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
 asn_enc_rval_t
 OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	int ilevel, enum xer_encoder_flags_e flags,
 		asn_app_consume_bytes_f *cb, void *app_key) {
-	static const char *h2c = "0123456789ABCDEF";
+	const char * const h2c = "0123456789ABCDEF";
 	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
 	asn_enc_rval_t er;
 	char scratch[16 * 3 + 4];
 	char *p = scratch;
 	uint8_t *buf;
 	uint8_t *end;
+	size_t i;
 
-	if(!st || !st->buf)
-		_ASN_ENCODE_FAILED;
+	if(!st || (!st->buf && st->size))
+		ASN__ENCODE_FAILED;
 
 	er.encoded = 0;
 
@@ -608,7 +603,7 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		char *scend = scratch + (sizeof(scratch) - 2);
 		for(; buf < end; buf++) {
 			if(p >= scend) {
-				_ASN_CALLBACK(scratch, p - scratch);
+				ASN__CALLBACK(scratch, p - scratch);
 				er.encoded += p - scratch;
 				p = scratch;
 			}
@@ -616,16 +611,15 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 			*p++ = h2c[*buf & 0x0F];
 		}
 
-		_ASN_CALLBACK(scratch, p-scratch);	/* Dump the rest */
+		ASN__CALLBACK(scratch, p-scratch);	/* Dump the rest */
 		er.encoded += p - scratch;
 	} else {
-		size_t i;
 		for(i = 0; buf < end; buf++, i++) {
 			if(!(i % 16) && (i || st->size > 16)) {
-				_ASN_CALLBACK(scratch, p-scratch);
+				ASN__CALLBACK(scratch, p-scratch);
 				er.encoded += (p-scratch);
 				p = scratch;
-				_i_ASN_TEXT_INDENT(1, ilevel);
+				ASN__TEXT_INDENT(1, ilevel);
 			}
 			*p++ = h2c[(*buf >> 4) & 0x0F];
 			*p++ = h2c[*buf & 0x0F];
@@ -633,20 +627,20 @@ OCTET_STRING_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		}
 		if(p - scratch) {
 			p--;	/* Remove the tail space */
-			_ASN_CALLBACK(scratch, p-scratch); /* Dump the rest */
+			ASN__CALLBACK(scratch, p-scratch); /* Dump the rest */
 			er.encoded += p - scratch;
 			if(st->size > 16)
-				_i_ASN_TEXT_INDENT(1, ilevel-1);
+				ASN__TEXT_INDENT(1, ilevel-1);
 		}
 	}
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
-static struct OCTET_STRING__xer_escape_table_s {
-	char *string;
+static const struct OCTET_STRING__xer_escape_table_s {
+	const char *string;
 	int size;
 } OCTET_STRING__xer_escape_table[] = {
 #define	OSXET(s)	{ s, sizeof(s) - 1 }
@@ -708,7 +702,7 @@ OS__check_escaped_control_char(const void *buf, int size) {
 	 * 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;
+		const 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;
@@ -751,8 +745,8 @@ OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
 	(void)ilevel;	/* Unused argument */
 	(void)flags;	/* Unused argument */
 
-	if(!st || !st->buf)
-		_ASN_ENCODE_FAILED;
+	if(!st || (!st->buf && st->size))
+		ASN__ENCODE_FAILED;
 
 	buf = st->buf;
 	end = buf + st->size;
@@ -769,7 +763,7 @@ OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
 			if(((buf - ss) && cb(ss, buf - ss, app_key) < 0)
 			|| cb(OCTET_STRING__xer_escape_table[ch].string, s_len,
 					app_key) < 0)
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 			encoded_len += (buf - ss) + s_len;
 			ss = buf + 1;
 		}
@@ -777,10 +771,10 @@ OCTET_STRING_encode_xer_utf8(asn_TYPE_descriptor_t *td, void *sptr,
 
 	encoded_len += (buf - ss);
 	if((buf - ss) && cb(ss, buf - ss, app_key) < 0)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	er.encoded = encoded_len;
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
 /*
@@ -1197,6 +1191,135 @@ OCTET_STRING_decode_xer_utf8(asn_codec_ctx_t *opt_codec_ctx,
 		OCTET_STRING__convert_entrefs);
 }
 
+static int
+OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf,
+		size_t units, unsigned int bpc, unsigned int unit_bits,
+		long lb, long ub, asn_per_constraints_t *pc) {
+	uint8_t *end = buf + units * bpc;
+
+	ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
+		(int)units, lb, ub, unit_bits);
+
+	/* X.691: 27.5.4 */
+	if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
+		/* Decode without translation */
+		lb = 0;
+	} else if(pc && pc->code2value) {
+		if(unit_bits > 16)
+			return 1;	/* FATAL: can't have constrained
+					 * UniversalString with more than
+					 * 16 million code points */
+		for(; buf < end; buf += bpc) {
+			int value;
+			int code = per_get_few_bits(po, unit_bits);
+			if(code < 0) return -1;	/* WMORE */
+			value = pc->code2value(code);
+			if(value < 0) {
+				ASN_DEBUG("Code %d (0x%02x) is"
+					" not in map (%ld..%ld)",
+					code, code, lb, ub);
+				return 1;	/* FATAL */
+			}
+			switch(bpc) {
+			case 1: *buf = value; break;
+			case 2: buf[0] = value >> 8; buf[1] = value; break;
+			case 4: buf[0] = value >> 24; buf[1] = value >> 16;
+				buf[2] = value >> 8; buf[3] = value; break;
+			}
+		}
+		return 0;
+	}
+
+	/* Shortcut the no-op copying to the aligned structure */
+	if(lb == 0 && (unit_bits == 8 * bpc)) {
+		return per_get_many_bits(po, buf, 0, unit_bits * units);
+	}
+
+	for(; buf < end; buf += bpc) {
+		int code = per_get_few_bits(po, unit_bits);
+		int ch = code + lb;
+		if(code < 0) return -1;	/* WMORE */
+		if(ch > ub) {
+			ASN_DEBUG("Code %d is out of range (%ld..%ld)",
+				ch, lb, ub);
+			return 1;	/* FATAL */
+		}
+		switch(bpc) {
+		case 1: *buf = ch; break;
+		case 2: buf[0] = ch >> 8; buf[1] = ch; break;
+		case 4: buf[0] = ch >> 24; buf[1] = ch >> 16;
+			buf[2] = ch >> 8; buf[3] = ch; break;
+		}
+	}
+
+	return 0;
+}
+
+static int
+OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf,
+		size_t units, unsigned int bpc, unsigned int unit_bits,
+		long lb, long ub, asn_per_constraints_t *pc) {
+	const uint8_t *end = buf + units * bpc;
+
+	ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)",
+		(int)units, lb, ub, unit_bits, bpc);
+
+	/* X.691: 27.5.4 */
+	if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
+		/* Encode as is */
+		lb = 0;
+	} else if(pc && pc->value2code) {
+		for(; buf < end; buf += bpc) {
+			int code;
+			uint32_t value;
+			switch(bpc) {
+			case 1: value = *(const uint8_t *)buf; break;
+			case 2: value = (buf[0] << 8) | buf[1]; break;
+			case 4: value = (buf[0] << 24) | (buf[1] << 16)
+					| (buf[2] << 8) | buf[3]; break;
+			default: return -1;
+			}
+			code = pc->value2code(value);
+			if(code < 0) {
+				ASN_DEBUG("Character %d (0x%02x) is"
+					" not in map (%ld..%ld)",
+					*buf, *buf, lb, ub);
+				return -1;
+			}
+			if(per_put_few_bits(po, code, unit_bits))
+				return -1;
+		}
+	}
+
+	/* Shortcut the no-op copying to the aligned structure */
+	if(lb == 0 && (unit_bits == 8 * bpc)) {
+		return per_put_many_bits(po, buf, unit_bits * units);
+	}
+
+	for(ub -= lb; buf < end; buf += bpc) {
+		int ch;
+		uint32_t value;
+		switch(bpc) {
+		case 1: value = *(const uint8_t *)buf; break;
+		case 2: value = (buf[0] << 8) | buf[1]; break;
+		case 4: value = (buf[0] << 24) | (buf[1] << 16)
+				| (buf[2] << 8) | buf[3]; break;
+		default: return -1;
+		}
+		ch = value - lb;
+		if(ch < 0 || ch > ub) {
+			ASN_DEBUG("Character %d (0x%02x)"
+			" is out of range (%ld..%ld)",
+				*buf, *buf, lb, ub + lb);
+			return -1;
+		}
+		if(per_put_few_bits(po, ch, unit_bits))
+			return -1;
+	}
+
+	return 0;
+}
+
 asn_dec_rval_t
 OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 	asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints,
@@ -1205,18 +1328,62 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 		? (asn_OCTET_STRING_specifics_t *)td->specifics
 		: &asn_DEF_OCTET_STRING_specs;
-	asn_per_constraint_t *ct = constraints ? &constraints->size
-				: (td->per_constraints
-					? &td->per_constraints->size
-					: &asn_DEF_OCTET_STRING_constraint);
+	asn_per_constraints_t *pc = constraints ? constraints
+				: td->per_constraints;
+	asn_per_constraint_t *cval;
+	asn_per_constraint_t *csiz;
 	asn_dec_rval_t rval = { RC_OK, 0 };
 	BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
 	ssize_t consumed_myself = 0;
 	int repeat;
-	int unit_bits = (specs->subvariant != 1) * 7 + 1;
+	enum {
+		OS__BPC_BIT	= 0,
+		OS__BPC_CHAR	= 1,
+		OS__BPC_U16	= 2,
+		OS__BPC_U32	= 4
+	} bpc;	/* Bytes per character */
+	unsigned int unit_bits;
+	unsigned int canonical_unit_bits;
 
 	(void)opt_codec_ctx;
 
+	if(pc) {
+		cval = &pc->value;
+		csiz = &pc->size;
+	} else {
+		cval = &asn_DEF_OCTET_STRING_constraints.value;
+		csiz = &asn_DEF_OCTET_STRING_constraints.size;
+	}
+
+	switch(specs->subvariant) {
+	default:
+	case ASN_OSUBV_ANY:
+		ASN_DEBUG("Unrecognized subvariant %d", specs->subvariant);
+		RETURN(RC_FAIL);
+	case ASN_OSUBV_BIT:
+		canonical_unit_bits = unit_bits = 1;
+		bpc = OS__BPC_BIT;
+		break;
+	case ASN_OSUBV_STR:
+		canonical_unit_bits = unit_bits = 8;
+		if(cval->flags & APC_CONSTRAINED)
+			unit_bits = cval->range_bits;
+		bpc = OS__BPC_CHAR;
+		break;
+	case ASN_OSUBV_U16:
+		canonical_unit_bits = unit_bits = 16;
+		if(cval->flags & APC_CONSTRAINED)
+			unit_bits = cval->range_bits;
+		bpc = OS__BPC_U16;
+		break;
+	case ASN_OSUBV_U32:
+		canonical_unit_bits = unit_bits = 32;
+		if(cval->flags & APC_CONSTRAINED)
+			unit_bits = cval->range_bits;
+		bpc = OS__BPC_U32;
+		break;
+	}
+
 	/*
 	 * Allocate the string.
 	 */
@@ -1225,24 +1392,26 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 		if(!st) RETURN(RC_FAIL);
 	}
 
-	ASN_DEBUG("PER Decoding %s %ld .. %ld bits %d",
-		ct->flags & APC_EXTENSIBLE ? "extensible" : "fixed",
-		ct->lower_bound, ct->upper_bound, ct->effective_bits);
+	ASN_DEBUG("PER Decoding %s size %ld .. %ld bits %d",
+		csiz->flags & APC_EXTENSIBLE ? "extensible" : "non-extensible",
+		csiz->lower_bound, csiz->upper_bound, csiz->effective_bits);
 
-	if(ct->flags & APC_EXTENSIBLE) {
+	if(csiz->flags & APC_EXTENSIBLE) {
 		int inext = per_get_few_bits(pd, 1);
 		if(inext < 0) RETURN(RC_WMORE);
-		if(inext) ct = &asn_DEF_OCTET_STRING_constraint;
-		consumed_myself = 0;
+		if(inext) {
+			csiz = &asn_DEF_OCTET_STRING_constraints.size;
+			cval = &asn_DEF_OCTET_STRING_constraints.value;
+			unit_bits = canonical_unit_bits;
+		}
 	}
 
-	if(ct->effective_bits >= 0
-	&& (!st->buf || st->size < ct->upper_bound)) {
+	if(csiz->effective_bits >= 0) {
 		FREEMEM(st->buf);
-		if(unit_bits == 1) {
-			st->size = (ct->upper_bound + 7) >> 3;
+		if(bpc) {
+			st->size = csiz->upper_bound * bpc;
 		} else {
-			st->size = ct->upper_bound;
+			st->size = (csiz->upper_bound + 7) >> 3;
 		}
 		st->buf = (uint8_t *)MALLOC(st->size + 1);
 		if(!st->buf) { st->size = 0; RETURN(RC_FAIL); }
@@ -1251,46 +1420,70 @@ OCTET_STRING_decode_uper(asn_codec_ctx_t *opt_codec_ctx,
 	/* X.691, #16.5: zero-length encoding */
 	/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
 	/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
-	if(ct->effective_bits == 0) {
-		int ret = per_get_many_bits(pd, st->buf, 0,
-					    unit_bits * ct->upper_bound);
+	if(csiz->effective_bits == 0) {
+		int ret;
+		if(bpc) {
+			ASN_DEBUG("Encoding OCTET STRING size %ld",
+				csiz->upper_bound);
+			ret = OCTET_STRING_per_get_characters(pd, st->buf,
+				csiz->upper_bound, bpc, unit_bits,
+				cval->lower_bound, cval->upper_bound, pc);
+			if(ret > 0) RETURN(RC_FAIL);
+		} else {
+			ASN_DEBUG("Encoding BIT STRING size %ld",
+				csiz->upper_bound);
+			ret = per_get_many_bits(pd, st->buf, 0,
+					    unit_bits * csiz->upper_bound);
+		}
 		if(ret < 0) RETURN(RC_WMORE);
-		consumed_myself += unit_bits * ct->upper_bound;
+		consumed_myself += unit_bits * csiz->upper_bound;
 		st->buf[st->size] = 0;
-		if(unit_bits == 1 && (ct->upper_bound & 0x7))
-			st->bits_unused = 8 - (ct->upper_bound & 0x7);
+		if(bpc == 0) {
+			int ubs = (csiz->upper_bound & 0x7);
+			st->bits_unused = ubs ? 8 - ubs : 0;
+		}
 		RETURN(RC_OK);
 	}
 
 	st->size = 0;
 	do {
+		ssize_t raw_len;
 		ssize_t len_bytes;
 		ssize_t len_bits;
 		void *p;
 		int ret;
 
 		/* Get the PER length */
-		len_bits = uper_get_length(pd, ct->effective_bits, &repeat);
-		if(len_bits < 0) RETURN(RC_WMORE);
-		len_bits += ct->lower_bound;
+		raw_len = uper_get_length(pd, csiz->effective_bits, &repeat);
+		if(raw_len < 0) RETURN(RC_WMORE);
+		raw_len += csiz->lower_bound;
 
 		ASN_DEBUG("Got PER length eb %ld, len %ld, %s (%s)",
-			(long)ct->effective_bits, (long)len_bits,
+			(long)csiz->effective_bits, (long)raw_len,
 			repeat ? "repeat" : "once", td->name);
-		if(unit_bits == 1) {
+		if(bpc) {
+			len_bytes = raw_len * bpc;
+			len_bits = len_bytes * unit_bits;
+		} else {
+			len_bits = raw_len;
 			len_bytes = (len_bits + 7) >> 3;
 			if(len_bits & 0x7)
 				st->bits_unused = 8 - (len_bits & 0x7);
 			/* len_bits be multiple of 16K if repeat is set */
-		} else {
-			len_bytes = len_bits;
-			len_bits = len_bytes << 3;
 		}
 		p = REALLOC(st->buf, st->size + len_bytes + 1);
 		if(!p) RETURN(RC_FAIL);
 		st->buf = (uint8_t *)p;
 
-		ret = per_get_many_bits(pd, &st->buf[st->size], 0, len_bits);
+		if(bpc) {
+			ret = OCTET_STRING_per_get_characters(pd,
+				&st->buf[st->size], raw_len, bpc, unit_bits,
+				cval->lower_bound, cval->upper_bound, pc);
+			if(ret > 0) RETURN(RC_FAIL);
+		} else {
+			ret = per_get_many_bits(pd, &st->buf[st->size],
+				0, len_bits);
+		}
 		if(ret < 0) RETURN(RC_WMORE);
 		st->size += len_bytes;
 	} while(repeat);
@@ -1306,45 +1499,90 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 		? (asn_OCTET_STRING_specifics_t *)td->specifics
 		: &asn_DEF_OCTET_STRING_specs;
-	asn_per_constraint_t *ct = constraints ? &constraints->size
-				: (td->per_constraints
-					? &td->per_constraints->size
-					: &asn_DEF_OCTET_STRING_constraint);
+	asn_per_constraints_t *pc = constraints ? constraints
+				: td->per_constraints;
+	asn_per_constraint_t *cval;
+	asn_per_constraint_t *csiz;
 	const BIT_STRING_t *st = (const BIT_STRING_t *)sptr;
-	int unit_bits = (specs->subvariant != 1) * 7 + 1;
-	asn_enc_rval_t er;
-	int ct_extensible = ct->flags & APC_EXTENSIBLE;
+	asn_enc_rval_t er = { 0, 0, 0 };
 	int inext = 0;		/* Lies not within extension root */
-	int sizeinunits = 0;
+	unsigned int unit_bits;
+	unsigned int canonical_unit_bits;
+	unsigned int sizeinunits;
 	const uint8_t *buf;
 	int ret;
-
-	if(!st || !st->buf)
-		_ASN_ENCODE_FAILED;
-	sizeinunits = st->size;
-
-	if(unit_bits == 1) {
+	enum {
+		OS__BPC_BIT	= 0,
+		OS__BPC_CHAR	= 1,
+		OS__BPC_U16	= 2,
+		OS__BPC_U32	= 4
+	} bpc;	/* Bytes per character */
+	int ct_extensible;
+
+	if(!st || (!st->buf && st->size))
+		ASN__ENCODE_FAILED;
+
+	if(pc) {
+		cval = &pc->value;
+		csiz = &pc->size;
+	} else {
+		cval = &asn_DEF_OCTET_STRING_constraints.value;
+		csiz = &asn_DEF_OCTET_STRING_constraints.size;
+	}
+	ct_extensible = csiz->flags & APC_EXTENSIBLE;
+
+	switch(specs->subvariant) {
+	default:
+	case ASN_OSUBV_ANY:
+		ASN__ENCODE_FAILED;
+	case ASN_OSUBV_BIT:
+		canonical_unit_bits = unit_bits = 1;
+		bpc = OS__BPC_BIT;
+		sizeinunits = st->size * 8 - (st->bits_unused & 0x07);
 		ASN_DEBUG("BIT STRING of %d bytes, %d bits unused",
 				sizeinunits, st->bits_unused);
-		sizeinunits = sizeinunits * 8 - (st->bits_unused & 0x07);
+		break;
+	case ASN_OSUBV_STR:
+		canonical_unit_bits = unit_bits = 8;
+		if(cval->flags & APC_CONSTRAINED)
+			unit_bits = cval->range_bits;
+		bpc = OS__BPC_CHAR;
+		sizeinunits = st->size;
+		break;
+	case ASN_OSUBV_U16:
+		canonical_unit_bits = unit_bits = 16;
+		if(cval->flags & APC_CONSTRAINED)
+			unit_bits = cval->range_bits;
+		bpc = OS__BPC_U16;
+		sizeinunits = st->size / 2;
+		break;
+	case ASN_OSUBV_U32:
+		canonical_unit_bits = unit_bits = 32;
+		if(cval->flags & APC_CONSTRAINED)
+			unit_bits = cval->range_bits;
+		bpc = OS__BPC_U32;
+		sizeinunits = st->size / 4;
+		break;
 	}
 
 	ASN_DEBUG("Encoding %s into %d units of %d bits"
-		" (%d..%d, effective %d)%s",
+		" (%ld..%ld, effective %d)%s",
 		td->name, sizeinunits, unit_bits,
-		ct->lower_bound, ct->upper_bound,
-		ct->effective_bits, ct_extensible ? " EXT" : "");
+		csiz->lower_bound, csiz->upper_bound,
+		csiz->effective_bits, ct_extensible ? " EXT" : "");
 
-	/* Figure out wheter size lies within PER visible consrtaint */
+	/* Figure out whether size lies within PER visible constraint */
 
-	if(ct->effective_bits >= 0) {
-		if(sizeinunits < ct->lower_bound
-		|| sizeinunits > ct->upper_bound) {
+	if(csiz->effective_bits >= 0) {
+		if((int)sizeinunits < csiz->lower_bound
+		|| (int)sizeinunits > csiz->upper_bound) {
 			if(ct_extensible) {
-				ct = &asn_DEF_OCTET_STRING_constraint;
+				cval = &asn_DEF_OCTET_STRING_constraints.value;
+				csiz = &asn_DEF_OCTET_STRING_constraints.size;
+				unit_bits = canonical_unit_bits;
 				inext = 1;
 			} else
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 		}
 	} else {
 		inext = 0;
@@ -1353,57 +1591,71 @@ OCTET_STRING_encode_uper(asn_TYPE_descriptor_t *td,
 	if(ct_extensible) {
 		/* Declare whether length is [not] within extension root */
 		if(per_put_few_bits(po, inext, 1))
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 	}
 
 	/* X.691, #16.5: zero-length encoding */
 	/* X.691, #16.6: short fixed length encoding (up to 2 octets) */
 	/* X.691, #16.7: long fixed length encoding (up to 64K octets) */
-	if(ct->effective_bits >= 0) {
+	if(csiz->effective_bits >= 0) {
 		ASN_DEBUG("Encoding %d bytes (%ld), length in %d bits",
-				st->size, sizeinunits - ct->lower_bound,
-				ct->effective_bits);
-		ret = per_put_few_bits(po, sizeinunits - ct->lower_bound,
-				ct->effective_bits);
-		if(ret) _ASN_ENCODE_FAILED;
-		ret = per_put_many_bits(po, st->buf, sizeinunits * unit_bits);
-		if(ret) _ASN_ENCODE_FAILED;
-		_ASN_ENCODED_OK(er);
+				st->size, sizeinunits - csiz->lower_bound,
+				csiz->effective_bits);
+		ret = per_put_few_bits(po, sizeinunits - csiz->lower_bound,
+				csiz->effective_bits);
+		if(ret) ASN__ENCODE_FAILED;
+		if(bpc) {
+			ret = OCTET_STRING_per_put_characters(po, st->buf,
+				sizeinunits, bpc, unit_bits,
+				cval->lower_bound, cval->upper_bound, pc);
+		} else {
+			ret = per_put_many_bits(po, st->buf,
+				sizeinunits * unit_bits);
+		}
+		if(ret) ASN__ENCODE_FAILED;
+		ASN__ENCODED_OK(er);
 	}
 
 	ASN_DEBUG("Encoding %d bytes", st->size);
 
 	if(sizeinunits == 0) {
 		if(uper_put_length(po, 0))
-			_ASN_ENCODE_FAILED;
-		_ASN_ENCODED_OK(er);
+			ASN__ENCODE_FAILED;
+		ASN__ENCODED_OK(er);
 	}
 
 	buf = st->buf;
 	while(sizeinunits) {
 		ssize_t maySave = uper_put_length(po, sizeinunits);
-		if(maySave < 0) _ASN_ENCODE_FAILED;
+		if(maySave < 0) ASN__ENCODE_FAILED;
 
-		ASN_DEBUG("Encoding %d of %d", maySave, sizeinunits);
+		ASN_DEBUG("Encoding %ld of %ld",
+			(long)maySave, (long)sizeinunits);
 
-		ret = per_put_many_bits(po, buf, maySave * unit_bits);
-		if(ret) _ASN_ENCODE_FAILED;
+		if(bpc) {
+			ret = OCTET_STRING_per_put_characters(po, buf,
+				maySave, bpc, unit_bits,
+				cval->lower_bound, cval->upper_bound, pc);
+		} else {
+			ret = per_put_many_bits(po, buf, maySave * unit_bits);
+		}
+		if(ret) ASN__ENCODE_FAILED;
 
-		if(unit_bits == 1)
-			buf += maySave >> 3;
+		if(bpc)
+			buf += maySave * bpc;
 		else
-			buf += maySave;
+			buf += maySave >> 3;
 		sizeinunits -= maySave;
 		assert(!(maySave & 0x07) || !sizeinunits);
 	}
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
 int
 OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 	asn_app_consume_bytes_f *cb, void *app_key) {
-	static const char *h2c = "0123456789ABCDEF";
+	const char * const h2c = "0123456789ABCDEF";
 	const OCTET_STRING_t *st = (const OCTET_STRING_t *)sptr;
 	char scratch[16 * 3 + 4];
 	char *p = scratch;
@@ -1413,7 +1665,8 @@ OCTET_STRING_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 
 	(void)td;	/* Unused argument */
 
-	if(!st || !st->buf) return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
+	if(!st || (!st->buf && st->size))
+		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
 
 	/*
 	 * Dump the contents of the buffer in hexadecimal.
@@ -1449,7 +1702,7 @@ OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr,
 	(void)td;	/* Unused argument */
 	(void)ilevel;	/* Unused argument */
 
-	if(st && st->buf) {
+	if(st && (st->buf || !st->size)) {
 		return (cb(st->buf, st->size, app_key) < 0) ? -1 : 0;
 	} else {
 		return (cb("<absent>", 8, app_key) < 0) ? -1 : 0;
@@ -1459,20 +1712,23 @@ OCTET_STRING_print_utf8(asn_TYPE_descriptor_t *td, const void *sptr,
 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 && td->specifics
-				? (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);
+	asn_OCTET_STRING_specifics_t *specs;
+	asn_struct_ctx_t *ctx;
 	struct _stack *stck;
 
 	if(!td || !st)
 		return;
 
+	specs = td->specifics
+		    ? (asn_OCTET_STRING_specifics_t *)td->specifics
+		    : &asn_DEF_OCTET_STRING_specs;
+	ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
+
 	ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
 
 	if(st->buf) {
 		FREEMEM(st->buf);
+		st->buf = 0;
 	}
 
 	/*
diff --git a/libs/smux/ObjectName.c b/libs/smux/ObjectName.c
index d10f7193..5b059007 100644
--- a/libs/smux/ObjectName.c
+++ b/libs/smux/ObjectName.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "ObjectName.h"
 
 int
@@ -25,6 +23,7 @@ static void
 ObjectName_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_OBJECT_IDENTIFIER.free_struct;
 	td->print_struct   = asn_DEF_OBJECT_IDENTIFIER.print_struct;
+	td->check_constraints = asn_DEF_OBJECT_IDENTIFIER.check_constraints;
 	td->ber_decoder    = asn_DEF_OBJECT_IDENTIFIER.ber_decoder;
 	td->der_encoder    = asn_DEF_OBJECT_IDENTIFIER.der_encoder;
 	td->xer_decoder    = asn_DEF_OBJECT_IDENTIFIER.xer_decoder;
@@ -82,7 +81,7 @@ ObjectName_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_ObjectName_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_ObjectName_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (6 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_ObjectName = {
diff --git a/libs/smux/ObjectSyntax.c b/libs/smux/ObjectSyntax.c
index b0542d90..1e5c6350 100644
--- a/libs/smux/ObjectSyntax.c
+++ b/libs/smux/ObjectSyntax.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "ObjectSyntax.h"
 
 static asn_TYPE_member_t asn_MBR_ObjectSyntax_1[] = {
@@ -29,16 +27,16 @@ static asn_TYPE_member_t asn_MBR_ObjectSyntax_1[] = {
 		"application-wide"
 		},
 };
-static asn_TYPE_tag2member_t asn_MAP_ObjectSyntax_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number at 73 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, 0, 0 }, /* string at 76 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 0, 0, 0 }, /* empty at 82 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* object at 79 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
-    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge at 94 */
-    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks at 97 */
-    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary at 104 */
+static const asn_TYPE_tag2member_t asn_MAP_ObjectSyntax_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 0, 0, 0 }, /* string */
+    { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 0, 0, 0 }, /* empty */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* object */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter */
+    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge */
+    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks */
+    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary */
 };
 static asn_CHOICE_specifics_t asn_SPC_ObjectSyntax_specs_1 = {
 	sizeof(struct ObjectSyntax),
diff --git a/libs/smux/Opaque.c b/libs/smux/Opaque.c
index bccff85d..f9e6823c 100644
--- a/libs/smux/Opaque.c
+++ b/libs/smux/Opaque.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "Opaque.h"
 
 int
@@ -25,6 +23,7 @@ static void
 Opaque_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_OCTET_STRING.free_struct;
 	td->print_struct   = asn_DEF_OCTET_STRING.print_struct;
+	td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
 	td->ber_decoder    = asn_DEF_OCTET_STRING.ber_decoder;
 	td->der_encoder    = asn_DEF_OCTET_STRING.der_encoder;
 	td->xer_decoder    = asn_DEF_OCTET_STRING.xer_decoder;
@@ -82,7 +81,7 @@ Opaque_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_Opaque_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_Opaque_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (4 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
 };
diff --git a/libs/smux/OpenPDU.c b/libs/smux/OpenPDU.c
index a841714e..337275e4 100644
--- a/libs/smux/OpenPDU.c
+++ b/libs/smux/OpenPDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "OpenPDU.h"
 
 static asn_TYPE_member_t asn_MBR_OpenPDU_1[] = {
@@ -20,8 +18,8 @@ static asn_TYPE_member_t asn_MBR_OpenPDU_1[] = {
 		"simple"
 		},
 };
-static asn_TYPE_tag2member_t asn_MAP_OpenPDU_tag2el_1[] = {
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* simple at 52 */
+static const asn_TYPE_tag2member_t asn_MAP_OpenPDU_tag2el_1[] = {
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* simple */
 };
 static asn_CHOICE_specifics_t asn_SPC_OpenPDU_specs_1 = {
 	sizeof(struct OpenPDU),
diff --git a/libs/smux/PDU.c b/libs/smux/PDU.c
index 0087d19f..af8528d5 100644
--- a/libs/smux/PDU.c
+++ b/libs/smux/PDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "PDU.h"
 
 static asn_TYPE_member_t asn_MBR_PDU_1[] = {
@@ -47,14 +45,14 @@ static asn_TYPE_member_t asn_MBR_PDU_1[] = {
 		"variable-bindings"
 		},
 };
-static ber_tlv_tag_t asn_DEF_PDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_PDU_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_PDU_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* request-id at 73 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 1 }, /* error-status at 77 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -2, 0 }, /* error-index at 86 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 3, 0, 0 } /* variable-bindings at 90 */
+static const asn_TYPE_tag2member_t asn_MAP_PDU_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* request-id */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, -1, 1 }, /* error-status */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -2, 0 }, /* error-index */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 3, 0, 0 } /* variable-bindings */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_PDU_specs_1 = {
 	sizeof(struct PDU),
diff --git a/libs/smux/PDUs.c b/libs/smux/PDUs.c
index 162530c0..177d23d9 100644
--- a/libs/smux/PDUs.c
+++ b/libs/smux/PDUs.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "PDUs.h"
 
 static asn_TYPE_member_t asn_MBR_PDUs_1[] = {
@@ -56,12 +54,12 @@ static asn_TYPE_member_t asn_MBR_PDUs_1[] = {
 		"trap"
 		},
 };
-static asn_TYPE_tag2member_t asn_MAP_PDUs_tag2el_1[] = {
-    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* get-request at 34 */
-    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* get-next-request at 37 */
-    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* get-response at 40 */
-    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* set-request at 43 */
-    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap at 47 */
+static const asn_TYPE_tag2member_t asn_MAP_PDUs_tag2el_1[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 0, 0, 0 }, /* get-request */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 }, /* get-next-request */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 2, 0, 0 }, /* get-response */
+    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 3, 0, 0 }, /* set-request */
+    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap */
 };
 static asn_CHOICE_specifics_t asn_SPC_PDUs_specs_1 = {
 	sizeof(struct PDUs),
diff --git a/libs/smux/PhysAddress.c b/libs/smux/PhysAddress.c
index eed47386..2ffd2c3d 100644
--- a/libs/smux/PhysAddress.c
+++ b/libs/smux/PhysAddress.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "PhysAddress.h"
 
 int
@@ -25,6 +23,7 @@ static void
 PhysAddress_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_OCTET_STRING.free_struct;
 	td->print_struct   = asn_DEF_OCTET_STRING.print_struct;
+	td->check_constraints = asn_DEF_OCTET_STRING.check_constraints;
 	td->ber_decoder    = asn_DEF_OCTET_STRING.ber_decoder;
 	td->der_encoder    = asn_DEF_OCTET_STRING.der_encoder;
 	td->xer_decoder    = asn_DEF_OCTET_STRING.xer_decoder;
@@ -82,7 +81,7 @@ PhysAddress_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_PhysAddress_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_PhysAddress_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
 };
 asn_TYPE_descriptor_t asn_DEF_PhysAddress = {
diff --git a/libs/smux/RReqPDU.c b/libs/smux/RReqPDU.c
index b19c3548..ee4040dc 100644
--- a/libs/smux/RReqPDU.c
+++ b/libs/smux/RReqPDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "RReqPDU.h"
 
 static int
@@ -15,7 +13,7 @@ memb_priority_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -27,7 +25,7 @@ memb_priority_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 		/* Constraint check succeeded */
 		return 0;
 	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: constraint failed (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -63,14 +61,14 @@ static asn_TYPE_member_t asn_MBR_RReqPDU_1[] = {
 		"operation"
 		},
 };
-static ber_tlv_tag_t asn_DEF_RReqPDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_RReqPDU_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (2 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_RReqPDU_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 1 }, /* priority at 96 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 0 }, /* operation at 101 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 } /* subtree at 93 */
+static const asn_TYPE_tag2member_t asn_MAP_RReqPDU_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 1 }, /* priority */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 0 }, /* operation */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 } /* subtree */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_RReqPDU_specs_1 = {
 	sizeof(struct RReqPDU),
diff --git a/libs/smux/RRspPDU.c b/libs/smux/RRspPDU.c
index b80080b1..b4d026f3 100644
--- a/libs/smux/RRspPDU.c
+++ b/libs/smux/RRspPDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "RRspPDU.h"
 
 int
@@ -25,6 +23,7 @@ static void
 RRspPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_INTEGER.free_struct;
 	td->print_struct   = asn_DEF_INTEGER.print_struct;
+	td->check_constraints = asn_DEF_INTEGER.check_constraints;
 	td->ber_decoder    = asn_DEF_INTEGER.ber_decoder;
 	td->der_encoder    = asn_DEF_INTEGER.der_encoder;
 	td->xer_decoder    = asn_DEF_INTEGER.xer_decoder;
@@ -82,7 +81,7 @@ RRspPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_RRspPDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_RRspPDU_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (3 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
diff --git a/libs/smux/SMUX-PDUs.c b/libs/smux/SMUX-PDUs.c
index 9942f998..adfdccde 100644
--- a/libs/smux/SMUX-PDUs.c
+++ b/libs/smux/SMUX-PDUs.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "SMUX-PDUs.h"
 
 static asn_TYPE_member_t asn_MBR_SMUX_PDUs_1[] = {
@@ -65,17 +63,17 @@ static asn_TYPE_member_t asn_MBR_SMUX_PDUs_1[] = {
 		"commitOrRollback"
 		},
 };
-static asn_TYPE_tag2member_t asn_MAP_SMUX_PDUs_tag2el_1[] = {
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* simple at 52 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* close at 27 */
-    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* registerRequest at 30 */
-    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* registerResponse at 33 */
-    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 5, 0, 0 }, /* commitOrRollback at 41 */
-    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 4, 0, 0 }, /* get-request at 34 */
-    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 4, 0, 0 }, /* get-next-request at 37 */
-    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 4, 0, 0 }, /* get-response at 40 */
-    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 4, 0, 0 }, /* set-request at 43 */
-    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap at 47 */
+static const asn_TYPE_tag2member_t asn_MAP_SMUX_PDUs_tag2el_1[] = {
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 }, /* simple */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* close */
+    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 2, 0, 0 }, /* registerRequest */
+    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 3, 0, 0 }, /* registerResponse */
+    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 5, 0, 0 }, /* commitOrRollback */
+    { (ASN_TAG_CLASS_CONTEXT | (0 << 2)), 4, 0, 0 }, /* get-request */
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 4, 0, 0 }, /* get-next-request */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 4, 0, 0 }, /* get-response */
+    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 4, 0, 0 }, /* set-request */
+    { (ASN_TAG_CLASS_CONTEXT | (4 << 2)), 4, 0, 0 } /* trap */
 };
 static asn_CHOICE_specifics_t asn_SPC_SMUX_PDUs_specs_1 = {
 	sizeof(struct SMUX_PDUs),
diff --git a/libs/smux/SOutPDU.c b/libs/smux/SOutPDU.c
index 6d3521bf..29d47786 100644
--- a/libs/smux/SOutPDU.c
+++ b/libs/smux/SOutPDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "SOutPDU.h"
 
 int
@@ -25,6 +23,7 @@ static void
 SOutPDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_INTEGER.free_struct;
 	td->print_struct   = asn_DEF_INTEGER.print_struct;
+	td->check_constraints = asn_DEF_INTEGER.check_constraints;
 	td->ber_decoder    = asn_DEF_INTEGER.ber_decoder;
 	td->der_encoder    = asn_DEF_INTEGER.der_encoder;
 	td->xer_decoder    = asn_DEF_INTEGER.xer_decoder;
@@ -82,7 +81,7 @@ SOutPDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_SOutPDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_SOutPDU_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (4 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
diff --git a/libs/smux/SetRequest-PDU.c b/libs/smux/SetRequest-PDU.c
index 08d30387..1bc9495d 100644
--- a/libs/smux/SetRequest-PDU.c
+++ b/libs/smux/SetRequest-PDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "SetRequest-PDU.h"
 
 int
@@ -25,6 +23,7 @@ static void
 SetRequest_PDU_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
 	td->free_struct    = asn_DEF_PDU.free_struct;
 	td->print_struct   = asn_DEF_PDU.print_struct;
+	td->check_constraints = asn_DEF_PDU.check_constraints;
 	td->ber_decoder    = asn_DEF_PDU.ber_decoder;
 	td->der_encoder    = asn_DEF_PDU.der_encoder;
 	td->xer_decoder    = asn_DEF_PDU.xer_decoder;
@@ -82,7 +81,7 @@ SetRequest_PDU_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_SetRequest_PDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_SetRequest_PDU_tags_1[] = {
 	(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
diff --git a/libs/smux/SimpleOpen.c b/libs/smux/SimpleOpen.c
index ec267687..479430bf 100644
--- a/libs/smux/SimpleOpen.c
+++ b/libs/smux/SimpleOpen.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "SimpleOpen.h"
 
 static asn_TYPE_member_t asn_MBR_SimpleOpen_1[] = {
@@ -47,15 +45,15 @@ static asn_TYPE_member_t asn_MBR_SimpleOpen_1[] = {
 		"password"
 		},
 };
-static ber_tlv_tag_t asn_DEF_SimpleOpen_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_SimpleOpen_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (0 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_SimpleOpen_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version at 59 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 2, 0, 1 }, /* description at 66 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 3, -1, 0 }, /* password at 69 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, 0, 0 } /* identity at 63 */
+static const asn_TYPE_tag2member_t asn_MAP_SimpleOpen_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* version */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 2, 0, 1 }, /* description */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 3, -1, 0 }, /* password */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, 0, 0 } /* identity */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_SimpleOpen_specs_1 = {
 	sizeof(struct SimpleOpen),
diff --git a/libs/smux/SimpleSyntax.c b/libs/smux/SimpleSyntax.c
index 72a11c0a..b2a385b4 100644
--- a/libs/smux/SimpleSyntax.c
+++ b/libs/smux/SimpleSyntax.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "SimpleSyntax.h"
 
 static asn_TYPE_member_t asn_MBR_SimpleSyntax_1[] = {
@@ -47,11 +45,11 @@ static asn_TYPE_member_t asn_MBR_SimpleSyntax_1[] = {
 		"empty"
 		},
 };
-static asn_TYPE_tag2member_t asn_MAP_SimpleSyntax_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number at 73 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string at 76 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 3, 0, 0 }, /* empty at 82 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 2, 0, 0 } /* object at 79 */
+static const asn_TYPE_tag2member_t asn_MAP_SimpleSyntax_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 0 }, /* number */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string */
+    { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 3, 0, 0 }, /* empty */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 2, 0, 0 } /* object */
 };
 static asn_CHOICE_specifics_t asn_SPC_SimpleSyntax_specs_1 = {
 	sizeof(struct SimpleSyntax),
diff --git a/libs/smux/TcpConnEntry.c b/libs/smux/TcpConnEntry.c
index 1a1c903b..994baa29 100644
--- a/libs/smux/TcpConnEntry.c
+++ b/libs/smux/TcpConnEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "TcpConnEntry.h"
 
 static int
@@ -15,7 +13,7 @@ memb_tcpConnLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -27,7 +25,7 @@ memb_tcpConnLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 		/* Constraint check succeeded */
 		return 0;
 	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: constraint failed (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -40,7 +38,7 @@ memb_tcpConnRemPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -52,7 +50,7 @@ memb_tcpConnRemPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 		/* Constraint check succeeded */
 		return 0;
 	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: constraint failed (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -106,15 +104,15 @@ static asn_TYPE_member_t asn_MBR_TcpConnEntry_1[] = {
 		"tcpConnRemPort"
 		},
 };
-static ber_tlv_tag_t asn_DEF_TcpConnEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_TcpConnEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_TcpConnEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* tcpConnState at 236 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 1 }, /* tcpConnLocalPort at 240 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* tcpConnRemPort at 244 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 1 }, /* tcpConnLocalAddress at 238 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 3, -1, 0 } /* tcpConnRemAddress at 242 */
+static const asn_TYPE_tag2member_t asn_MAP_TcpConnEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 0, 0, 2 }, /* tcpConnState */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, -1, 1 }, /* tcpConnLocalPort */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 4, -2, 0 }, /* tcpConnRemPort */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 1 }, /* tcpConnLocalAddress */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 3, -1, 0 } /* tcpConnRemAddress */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_TcpConnEntry_specs_1 = {
 	sizeof(struct TcpConnEntry),
diff --git a/libs/smux/TimeTicks.c b/libs/smux/TimeTicks.c
index fad39691..b1aa1130 100644
--- a/libs/smux/TimeTicks.c
+++ b/libs/smux/TimeTicks.c
@@ -1,64 +1,48 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "TimeTicks.h"
 
 int
 TimeTicks_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 			asn_app_constraint_failed_f *ctfailcb, void *app_key) {
-	const INTEGER_t *st = (const INTEGER_t *)sptr;
-	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
 	}
 	
-	if(asn_INTEGER2long(st, &value)) {
-		_ASN_CTFAIL(app_key, td, sptr,
-			"%s: value too large (%s:%d)",
-			td->name, __FILE__, __LINE__);
-		return -1;
-	}
 	
-	if((value >= 0 && value <= 4294967295)) {
-		/* Constraint check succeeded */
-		return 0;
-	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
-			"%s: constraint failed (%s:%d)",
-			td->name, __FILE__, __LINE__);
-		return -1;
-	}
+	/* Constraint check succeeded */
+	return 0;
 }
 
 /*
- * This type is implemented using INTEGER,
+ * This type is implemented using NativeInteger,
  * so here we adjust the DEF accordingly.
  */
 static void
 TimeTicks_1_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {
-	td->free_struct    = asn_DEF_INTEGER.free_struct;
-	td->print_struct   = asn_DEF_INTEGER.print_struct;
-	td->ber_decoder    = asn_DEF_INTEGER.ber_decoder;
-	td->der_encoder    = asn_DEF_INTEGER.der_encoder;
-	td->xer_decoder    = asn_DEF_INTEGER.xer_decoder;
-	td->xer_encoder    = asn_DEF_INTEGER.xer_encoder;
-	td->uper_decoder   = asn_DEF_INTEGER.uper_decoder;
-	td->uper_encoder   = asn_DEF_INTEGER.uper_encoder;
+	td->free_struct    = asn_DEF_NativeInteger.free_struct;
+	td->print_struct   = asn_DEF_NativeInteger.print_struct;
+	td->check_constraints = asn_DEF_NativeInteger.check_constraints;
+	td->ber_decoder    = asn_DEF_NativeInteger.ber_decoder;
+	td->der_encoder    = asn_DEF_NativeInteger.der_encoder;
+	td->xer_decoder    = asn_DEF_NativeInteger.xer_decoder;
+	td->xer_encoder    = asn_DEF_NativeInteger.xer_encoder;
+	td->uper_decoder   = asn_DEF_NativeInteger.uper_decoder;
+	td->uper_encoder   = asn_DEF_NativeInteger.uper_encoder;
 	if(!td->per_constraints)
-		td->per_constraints = asn_DEF_INTEGER.per_constraints;
-	td->elements       = asn_DEF_INTEGER.elements;
-	td->elements_count = asn_DEF_INTEGER.elements_count;
-	td->specifics      = asn_DEF_INTEGER.specifics;
+		td->per_constraints = asn_DEF_NativeInteger.per_constraints;
+	td->elements       = asn_DEF_NativeInteger.elements;
+	td->elements_count = asn_DEF_NativeInteger.elements_count;
+     /* td->specifics      = asn_DEF_NativeInteger.specifics;	// Defined explicitly */
 }
 
 void
@@ -105,7 +89,12 @@ TimeTicks_encode_xer(asn_TYPE_descriptor_t *td, void *structure,
 	return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);
 }
 
-static ber_tlv_tag_t asn_DEF_TimeTicks_tags_1[] = {
+static const asn_INTEGER_specifics_t asn_SPC_TimeTicks_specs_1 = {
+	0,	0,	0,	0,	0,
+	0,	/* Native long size */
+	1	/* Unsigned representation */
+};
+static const ber_tlv_tag_t asn_DEF_TimeTicks_tags_1[] = {
 	(ASN_TAG_CLASS_APPLICATION | (3 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
@@ -129,6 +118,6 @@ asn_TYPE_descriptor_t asn_DEF_TimeTicks = {
 		/sizeof(asn_DEF_TimeTicks_tags_1[0]), /* 2 */
 	0,	/* No PER visible constraints */
 	0, 0,	/* No members */
-	0	/* No specifics */
+	&asn_SPC_TimeTicks_specs_1	/* Additional specs */
 };
 
diff --git a/libs/smux/Trap-PDU.c b/libs/smux/Trap-PDU.c
index 5e82ddf7..4c1b44dc 100644
--- a/libs/smux/Trap-PDU.c
+++ b/libs/smux/Trap-PDU.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "Trap-PDU.h"
 
 static asn_TYPE_member_t asn_MBR_Trap_PDU_1[] = {
@@ -65,17 +63,17 @@ static asn_TYPE_member_t asn_MBR_Trap_PDU_1[] = {
 		"variable-bindings"
 		},
 };
-static ber_tlv_tag_t asn_DEF_Trap_PDU_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_Trap_PDU_tags_1[] = {
 	(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_Trap_PDU_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, 0, 1 }, /* generic-trap at 106 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* specific-trap at 116 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* enterprise at 99 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 5, 0, 0 }, /* variable-bindings at 125 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
-    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 4, 0, 0 } /* time-stamp at 120 */
+static const asn_TYPE_tag2member_t asn_MAP_Trap_PDU_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 2, 0, 1 }, /* generic-trap */
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 3, -1, 0 }, /* specific-trap */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 0 }, /* enterprise */
+    { (ASN_TAG_CLASS_UNIVERSAL | (16 << 2)), 5, 0, 0 }, /* variable-bindings */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet */
+    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 4, 0, 0 } /* time-stamp */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_Trap_PDU_specs_1 = {
 	sizeof(struct Trap_PDU),
diff --git a/libs/smux/UdpEntry.c b/libs/smux/UdpEntry.c
index 711bbadc..d4c85a38 100644
--- a/libs/smux/UdpEntry.c
+++ b/libs/smux/UdpEntry.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "UdpEntry.h"
 
 static int
@@ -15,7 +13,7 @@ memb_udpLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 	long value;
 	
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -27,7 +25,7 @@ memb_udpLocalPort_constraint_1(asn_TYPE_descriptor_t *td, const void *sptr,
 		/* Constraint check succeeded */
 		return 0;
 	} else {
-		_ASN_CTFAIL(app_key, td, sptr,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: constraint failed (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -54,12 +52,12 @@ static asn_TYPE_member_t asn_MBR_UdpEntry_1[] = {
 		"udpLocalPort"
 		},
 };
-static ber_tlv_tag_t asn_DEF_UdpEntry_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_UdpEntry_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_UdpEntry_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* udpLocalPort at 253 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* udpLocalAddress at 251 */
+static const asn_TYPE_tag2member_t asn_MAP_UdpEntry_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* udpLocalPort */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 0, 0, 0 } /* udpLocalAddress */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_UdpEntry_specs_1 = {
 	sizeof(struct UdpEntry),
diff --git a/libs/smux/VarBind.c b/libs/smux/VarBind.c
index 85a6f97f..047337f3 100644
--- a/libs/smux/VarBind.c
+++ b/libs/smux/VarBind.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "VarBind.h"
 
 static asn_TYPE_member_t asn_MBR_VarBind_1[] = {
@@ -29,20 +27,20 @@ static asn_TYPE_member_t asn_MBR_VarBind_1[] = {
 		"value"
 		},
 };
-static ber_tlv_tag_t asn_DEF_VarBind_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_VarBind_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
-static asn_TYPE_tag2member_t asn_MAP_VarBind_tag2el_1[] = {
-    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* number at 73 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string at 76 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 1, 0, 0 }, /* empty at 82 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 1 }, /* name at 133 */
-    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, -1, 0 }, /* object at 79 */
-    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet at 113 */
-    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter at 91 */
-    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge at 94 */
-    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks at 97 */
-    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary at 104 */
+static const asn_TYPE_tag2member_t asn_MAP_VarBind_tag2el_1[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)), 1, 0, 0 }, /* number */
+    { (ASN_TAG_CLASS_UNIVERSAL | (4 << 2)), 1, 0, 0 }, /* string */
+    { (ASN_TAG_CLASS_UNIVERSAL | (5 << 2)), 1, 0, 0 }, /* empty */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 0, 0, 1 }, /* name */
+    { (ASN_TAG_CLASS_UNIVERSAL | (6 << 2)), 1, -1, 0 }, /* object */
+    { (ASN_TAG_CLASS_APPLICATION | (0 << 2)), 1, 0, 0 }, /* internet */
+    { (ASN_TAG_CLASS_APPLICATION | (1 << 2)), 1, 0, 0 }, /* counter */
+    { (ASN_TAG_CLASS_APPLICATION | (2 << 2)), 1, 0, 0 }, /* gauge */
+    { (ASN_TAG_CLASS_APPLICATION | (3 << 2)), 1, 0, 0 }, /* ticks */
+    { (ASN_TAG_CLASS_APPLICATION | (4 << 2)), 1, 0, 0 } /* arbitrary */
 };
 static asn_SEQUENCE_specifics_t asn_SPC_VarBind_specs_1 = {
 	sizeof(struct VarBind),
diff --git a/libs/smux/VarBindList.c b/libs/smux/VarBindList.c
index 15018ded..d84026e1 100644
--- a/libs/smux/VarBindList.c
+++ b/libs/smux/VarBindList.c
@@ -1,12 +1,10 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
-#include <asn_internal.h>
-
 #include "VarBindList.h"
 
 static asn_TYPE_member_t asn_MBR_VarBindList_1[] = {
@@ -20,7 +18,7 @@ static asn_TYPE_member_t asn_MBR_VarBindList_1[] = {
 		""
 		},
 };
-static ber_tlv_tag_t asn_DEF_VarBindList_tags_1[] = {
+static const ber_tlv_tag_t asn_DEF_VarBindList_tags_1[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (16 << 2))
 };
 static asn_SET_OF_specifics_t asn_SPC_VarBindList_specs_1 = {
diff --git a/libs/smux/asn_codecs_prim.c b/libs/smux/asn_codecs_prim.c
index 4e5c6393..426339c9 100644
--- a/libs/smux/asn_codecs_prim.c
+++ b/libs/smux/asn_codecs_prim.c
@@ -15,14 +15,14 @@ ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
 	void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
 	ASN__PRIMITIVE_TYPE_t *st = (ASN__PRIMITIVE_TYPE_t *)*sptr;
 	asn_dec_rval_t rval;
-	ber_tlv_len_t length;
+	ber_tlv_len_t length = 0; /* =0 to avoid [incorrect] warning. */
 
 	/*
 	 * If the structure is not there, allocate it.
 	 */
 	if(st == NULL) {
 		st = (ASN__PRIMITIVE_TYPE_t *)CALLOC(1, sizeof(*st));
-		if(st == NULL) _ASN_DECODE_FAILED;
+		if(st == NULL) ASN__DECODE_FAILED;
 		*sptr = (void *)st;
 	}
 
@@ -55,13 +55,13 @@ ber_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
 	if(sizeof(st->size) != sizeof(length)
 			&& (ber_tlv_len_t)st->size != length) {
 		st->size = 0;
-		_ASN_DECODE_FAILED;
+		ASN__DECODE_FAILED;
 	}
 
 	st->buf = (uint8_t *)MALLOC(length + 1);
 	if(!st->buf) {
 		st->size = 0;
-		_ASN_DECODE_FAILED;
+		ASN__DECODE_FAILED;
 	}
 
 	memcpy(st->buf, buf_ptr, length);
@@ -111,7 +111,7 @@ der_encode_primitive(asn_TYPE_descriptor_t *td, void *sptr,
 	}
 
 	erval.encoded += st->size;
-	_ASN_ENCODED_OK(erval);
+	ASN__ENCODED_OK(erval);
 }
 
 void
@@ -143,20 +143,26 @@ struct xdp_arg_s {
 	int want_more;
 };
 
-
+/*
+ * Since some kinds of primitive values can be encoded using value-specific
+ * tags (<MINUS-INFINITY>, <enum-element>, etc), the primitive decoder must
+ * be supplied with such tags to parse them as needed.
+ */
 static int
 xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size) {
 	struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
 	enum xer_pbd_rval bret;
 
-	if(arg->decoded_something) {
-		if(xer_is_whitespace(chunk_buf, chunk_size))
-			return 0;	/* Skip it. */
-		/*
-		 * Decoding was done once already. Prohibit doing it again.
-		 */
+	/*
+	 * The chunk_buf is guaranteed to start at '<'.
+	 */
+	assert(chunk_size && ((const char *)chunk_buf)[0] == 0x3c);
+
+	/*
+	 * Decoding was performed once already. Prohibit doing it again.
+	 */
+	if(arg->decoded_something)
 		return -1;
-	}
 
 	bret = arg->prim_body_decoder(arg->type_descriptor,
 		arg->struct_key, chunk_buf, chunk_size);
@@ -177,13 +183,20 @@ xer_decode__unexpected_tag(void *key, const void *chunk_buf, size_t chunk_size)
 }
 
 static ssize_t
-xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
+xer_decode__primitive_body(void *key, const void *chunk_buf, size_t chunk_size, int have_more) {
 	struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
 	enum xer_pbd_rval bret;
+	size_t lead_wsp_size;
 
 	if(arg->decoded_something) {
-		if(xer_is_whitespace(chunk_buf, chunk_size))
+		if(xer_whitespace_span(chunk_buf, chunk_size) == chunk_size) {
+			/*
+			 * Example:
+			 * "<INTEGER>123<!--/--> </INTEGER>"
+			 *                      ^- chunk_buf position.
+			 */
 			return chunk_size;
+		}
 		/*
 		 * Decoding was done once already. Prohibit doing it again.
 		 */
@@ -203,6 +216,10 @@ xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_m
 		return -1;
 	}
 
+	lead_wsp_size = xer_whitespace_span(chunk_buf, chunk_size);
+	chunk_buf = (const char *)chunk_buf + lead_wsp_size;
+	chunk_size -= lead_wsp_size;
+
 	bret = arg->prim_body_decoder(arg->type_descriptor,
 		arg->struct_key, chunk_buf, chunk_size);
 	switch(bret) {
@@ -215,7 +232,7 @@ xer_decode__body(void *key, const void *chunk_buf, size_t chunk_size, int have_m
 		arg->decoded_something = 1;
 		/* Fall through */
 	case XPBD_NOT_BODY_IGNORE:	/* Safe to proceed further */
-		return chunk_size;
+		return lead_wsp_size + chunk_size;
 	}
 
 	return -1;
@@ -241,7 +258,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
 	 */
 	if(!*sptr) {
 		*sptr = CALLOC(1, struct_size);
-		if(!*sptr) _ASN_DECODE_FAILED;
+		if(!*sptr) ASN__DECODE_FAILED;
 	}
 
 	memset(&s_ctx, 0, sizeof(s_ctx));
@@ -253,7 +270,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
 
 	rc = xer_decode_general(opt_codec_ctx, &s_ctx, &s_arg,
 		xml_tag, buf_ptr, size,
-		xer_decode__unexpected_tag, xer_decode__body);
+		xer_decode__unexpected_tag, xer_decode__primitive_body);
 	switch(rc.code) {
 	case RC_OK:
 		if(!s_arg.decoded_something) {
@@ -271,7 +288,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
 				/*
 				 * This decoder does not like empty stuff.
 				 */
-				_ASN_DECODE_FAILED;
+				ASN__DECODE_FAILED;
 			}
 		}
 		break;
@@ -287,7 +304,7 @@ xer_decode_primitive(asn_codec_ctx_t *opt_codec_ctx,
 		if(s_arg.want_more)
 			rc.code = RC_WMORE;
 		else
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 		break;
 	}
 	return rc;
diff --git a/libs/smux/ber_decoder.c b/libs/smux/ber_decoder.c
index 601f66c0..b3a6329e 100644
--- a/libs/smux/ber_decoder.c
+++ b/libs/smux/ber_decoder.c
@@ -44,7 +44,7 @@ ber_decode(asn_codec_ctx_t *opt_codec_ctx,
 	} else {
 		/* If context is not given, be security-conscious anyway */
 		memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
-		s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
+		s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
 		opt_codec_ctx = &s_codec_ctx;
 	}
 
@@ -80,7 +80,7 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx,
 	/*
 	 * Make sure we didn't exceed the maximum stack size.
 	 */
-	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+	if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
 		RETURN(RC_FAIL);
 
 	/*
@@ -206,7 +206,7 @@ ber_check_tags(asn_codec_ctx_t *opt_codec_ctx,
 		 */
 		len_len = ber_fetch_length(tlv_constr,
 			(const char *)ptr + tag_len, size - tag_len, &tlv_len);
-		ASN_DEBUG("Fetchinig len = %ld", (long)len_len);
+		ASN_DEBUG("Fetching len = %ld", (long)len_len);
 		switch(len_len) {
 		case -1: RETURN(RC_FAIL);
 		case 0: RETURN(RC_WMORE);
diff --git a/libs/smux/ber_tlv_length.c b/libs/smux/ber_tlv_length.c
index 32aa5e54..4c2f1e5f 100644
--- a/libs/smux/ber_tlv_length.c
+++ b/libs/smux/ber_tlv_length.c
@@ -78,13 +78,14 @@ ssize_t
 ber_skip_length(asn_codec_ctx_t *opt_codec_ctx,
 		int _is_constructed, const void *ptr, size_t size) {
 	ber_tlv_len_t vlen;	/* Length of V in TLV */
+	ssize_t tl;		/* Length of L in TLV */
 	ssize_t ll;		/* Length of L in TLV */
 	size_t skip;
 
 	/*
 	 * Make sure we didn't exceed the maximum stack size.
 	 */
-	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
+	if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
 		return -1;
 
 	/*
@@ -111,7 +112,7 @@ ber_skip_length(asn_codec_ctx_t *opt_codec_ctx,
 		ber_tlv_tag_t tag;
 
 		/* Fetch the tag */
-		ssize_t tl = ber_fetch_tag(ptr, size, &tag);
+		tl = ber_fetch_tag(ptr, size, &tag);
 		if(tl <= 0) return tl;
 
 		ll = ber_skip_length(opt_codec_ctx,
diff --git a/libs/smux/constr_CHOICE.c b/libs/smux/constr_CHOICE.c
index a20a0505..6116e6a6 100644
--- a/libs/smux/constr_CHOICE.c
+++ b/libs/smux/constr_CHOICE.c
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin <vlm@lionet.info>.
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #include <asn_internal.h>
 #include <constr_CHOICE.h>
+#include <per_opentype.h>
 
 /*
  * Number of bytes left for this structure.
@@ -182,11 +183,11 @@ CHOICE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		}
 
 		do {
-			asn_TYPE_tag2member_t *t2m;
+			const asn_TYPE_tag2member_t *t2m;
 			asn_TYPE_tag2member_t key;
 
 			key.el_tag = tlv_tag;
-			t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
+			t2m = (const asn_TYPE_tag2member_t *)bsearch(&key,
 					specs->tag2el, specs->tag2el_count,
 					sizeof(specs->tag2el[0]), _search4tag);
 			if(t2m) {
@@ -363,7 +364,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 	size_t computed_size = 0;
 	int present;
 
-	if(!sptr) _ASN_ENCODE_FAILED;
+	if(!sptr) ASN__ENCODE_FAILED;
 
 	ASN_DEBUG("%s %s as CHOICE",
 		cb?"Encoding":"Estimating", td->name);
@@ -379,9 +380,9 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 		if(present == 0 && td->elements_count == 0) {
 			/* The CHOICE is empty?! */
 			erval.encoded = 0;
-			_ASN_ENCODED_OK(erval);
+			ASN__ENCODED_OK(erval);
 		}
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	}
 
 	/*
@@ -393,10 +394,10 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 		if(memb_ptr == 0) {
 			if(elm->optional) {
 				erval.encoded = 0;
-				_ASN_ENCODED_OK(erval);
+				ASN__ENCODED_OK(erval);
 			}
 			/* Mandatory element absent */
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 		}
 	} else {
 		memb_ptr = (void *)((char *)sptr + elm->memb_offset);
@@ -423,7 +424,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 		ret = der_write_tags(td, erval.encoded, tag_mode, 1, tag,
 			cb, app_key);
 		if(ret == -1)
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 		computed_size += ret;
 	}
 
@@ -444,7 +445,7 @@ CHOICE_encode_der(asn_TYPE_descriptor_t *td, void *sptr,
 }
 
 ber_tlv_tag_t
-CHOICE_outmost_tag(asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag) {
+CHOICE_outmost_tag(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber_tlv_tag_t tag) {
 	asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
 	int present;
 
@@ -457,7 +458,7 @@ CHOICE_outmost_tag(asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode, ber
 	present = _fetch_present_idx(ptr, specs->pres_offset, specs->pres_size);
 
 	if(present > 0 || present <= td->elements_count) {
-		asn_TYPE_member_t *elm = &td->elements[present-1];
+		const asn_TYPE_member_t *elm = &td->elements[present-1];
 		const void *memb_ptr;
 
 		if(elm->flags & ATF_POINTER) {
@@ -482,7 +483,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 	int present;
 
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -501,7 +502,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 			if(!memb_ptr) {
 				if(elm->optional)
 					return 0;
-				_ASN_CTFAIL(app_key, td,
+				ASN__CTFAIL(app_key, td, sptr,
 					"%s: mandatory CHOICE element %s absent (%s:%d)",
 					td->name, elm->name, __FILE__, __LINE__);
 				return -1;
@@ -524,7 +525,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 			return ret;
 		}
 	} else {
-		_ASN_CTFAIL(app_key, td,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: no CHOICE element given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -534,7 +535,7 @@ CHOICE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 #undef	XER_ADVANCE
 #define	XER_ADVANCE(num_bytes)	do {			\
 		size_t num = num_bytes;			\
-		buf_ptr = ((const char *)buf_ptr) + num;\
+		buf_ptr = (const void *)(((const char *)buf_ptr) + num); \
 		size -= num;				\
 		consumed_myself += num;			\
 	} while(0)
@@ -639,11 +640,12 @@ CHOICE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		 * Get the next part of the XML stream.
 		 */
 		ch_size = xer_next_token(&ctx->context, buf_ptr, size, &ch_type);
-		switch(ch_size) {
-		case -1: RETURN(RC_FAIL);
-		case 0:  RETURN(RC_WMORE);
-		default:
+		if(ch_size == -1) {
+            RETURN(RC_FAIL);
+        } else {
 			switch(ch_type) {
+			case PXER_WMORE:
+                RETURN(RC_WMORE);
 			case PXER_COMMENT:	/* Got XML comment */
 			case PXER_TEXT:		/* Ignore free-standing text */
 				XER_ADVANCE(ch_size);	/* Skip silently */
@@ -779,7 +781,7 @@ CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	int present;
 
 	if(!sptr)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	/*
 	 * Figure out which CHOICE element is encoded.
@@ -787,7 +789,7 @@ CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	present = _fetch_present_idx(sptr, specs->pres_offset,specs->pres_size);
 
 	if(present <= 0 || present > td->elements_count) {
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	}  else {
 		asn_enc_rval_t tmper;
 		asn_TYPE_member_t *elm = &td->elements[present-1];
@@ -797,30 +799,30 @@ CHOICE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 
 		if(elm->flags & ATF_POINTER) {
 			memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
-			if(!memb_ptr) _ASN_ENCODE_FAILED;
+			if(!memb_ptr) ASN__ENCODE_FAILED;
 		} else {
 			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
 		}
 
 		er.encoded = 0;
 
-                if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel);
-		_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+                if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel);
+		ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 
 		tmper = elm->type->xer_encoder(elm->type, memb_ptr,
 				ilevel + 1, flags, cb, app_key);
 		if(tmper.encoded == -1) return tmper;
 
-		_ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+		ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
 
 		er.encoded += 5 + (2 * mlen) + tmper.encoded;
 	}
 
-	if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+	if(!(flags & XER_F_CANONICAL)) ASN__TEXT_INDENT(1, ilevel - 1);
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
 asn_dec_rval_t
@@ -835,15 +837,15 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	void *st = *sptr;
 	int value;
 
-	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
-		_ASN_DECODE_FAILED;
+	if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
+		ASN__DECODE_FAILED;
 
 	/*
 	 * Create the target structure if it is not present already.
 	 */
 	if(!st) {
 		st = *sptr = CALLOC(1, specs->struct_size);
-		if(!st) _ASN_DECODE_FAILED;
+		if(!st) ASN__DECODE_FAILED;
 	}
 
 	if(constraints) ct = &constraints->value;
@@ -852,27 +854,25 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 	if(ct && ct->flags & APC_EXTENSIBLE) {
 		value = per_get_few_bits(pd, 1);
-		if(value < 0) _ASN_DECODE_STARVED;
+		if(value < 0) ASN__DECODE_STARVED;
 		if(value) ct = 0;	/* Not restricted */
 	}
 
 	if(ct && ct->range_bits >= 0) {
 		value = per_get_few_bits(pd, ct->range_bits);
-		if(value < 0) _ASN_DECODE_STARVED;
+		if(value < 0) ASN__DECODE_STARVED;
 		ASN_DEBUG("CHOICE %s got index %d in range %d",
 			td->name, value, ct->range_bits);
 		if(value > ct->upper_bound)
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 	} else {
 		if(specs->ext_start == -1)
-			_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 		value = uper_get_nsnnwn(pd);
-		if(value < 0) _ASN_DECODE_STARVED;
+		if(value < 0) ASN__DECODE_STARVED;
 		value += specs->ext_start;
 		if(value >= td->elements_count)
-			_ASN_DECODE_FAILED;
-		ASN_DEBUG("NOT IMPLEMENTED YET");
-		_ASN_DECODE_FAILED;
+			ASN__DECODE_FAILED;
 	}
 
 	/* Adjust if canonical order is different from natural order */
@@ -892,11 +892,17 @@ CHOICE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	}
 	ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);
 
-	rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+	if(ct && ct->range_bits >= 0) {
+		rv = elm->type->uper_decoder(opt_codec_ctx, elm->type,
+			elm->per_constraints, memb_ptr2, pd);
+	} else {
+		rv = uper_open_type_get(opt_codec_ctx, elm->type,
 			elm->per_constraints, memb_ptr2, pd);
+	}
+
 	if(rv.code != RC_OK)
-		ASN_DEBUG("Failed to decode %s in %s (CHOICE)",
-			elm->name, td->name);
+		ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d",
+			elm->name, td->name, rv.code);
 	return rv;
 }
    
@@ -908,8 +914,9 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_per_constraint_t *ct;
 	void *memb_ptr;
 	int present;
+	int present_enc;
 
-	if(!sptr) _ASN_ENCODE_FAILED;
+	if(!sptr) ASN__ENCODE_FAILED;
 
 	ASN_DEBUG("Encoding %s as CHOICE", td->name);
 
@@ -925,55 +932,61 @@ CHOICE_encode_uper(asn_TYPE_descriptor_t *td,
 	 * can't deduce what to encode in the choice type.
 	 */
 	if(present <= 0 || present > td->elements_count)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	else
 		present--;
 
+	ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
+
 	/* Adjust if canonical order is different from natural order */
 	if(specs->canonical_order)
-		present = specs->canonical_order[present];
-
-	ASN_DEBUG("Encoding %s CHOICE element %d", td->name, present);
+		present_enc = specs->canonical_order[present];
+	else
+		present_enc = present;
 
 	if(ct && ct->range_bits >= 0) {
-		if(present < ct->lower_bound
-		|| present > ct->upper_bound) {
+		if(present_enc < ct->lower_bound
+		|| present_enc > ct->upper_bound) {
 			if(ct->flags & APC_EXTENSIBLE) {
 				if(per_put_few_bits(po, 1, 1))
-					_ASN_ENCODE_FAILED;
+					ASN__ENCODE_FAILED;
 			} else {
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 			}
 			ct = 0;
 		}
 	}
 	if(ct && ct->flags & APC_EXTENSIBLE)
 		if(per_put_few_bits(po, 0, 1))
-			_ASN_ENCODE_FAILED;
-
-	if(ct && ct->range_bits >= 0) {
-		if(per_put_few_bits(po, present, ct->range_bits))
-			_ASN_ENCODE_FAILED;
-	} else {
-		if(specs->ext_start == -1)
-			_ASN_ENCODE_FAILED;
-		if(uper_put_nsnnwn(po, present - specs->ext_start))
-			_ASN_ENCODE_FAILED;
-		ASN_DEBUG("NOT IMPLEMENTED YET");
-		_ASN_ENCODE_FAILED;
-	}
+			ASN__ENCODE_FAILED;
 
 	elm = &td->elements[present];
 	if(elm->flags & ATF_POINTER) {
 		/* Member is a pointer to another structure */
 		memb_ptr = *(void **)((char *)sptr + elm->memb_offset);
-		if(!memb_ptr) _ASN_ENCODE_FAILED;
+		if(!memb_ptr) ASN__ENCODE_FAILED;
 	} else {
 		memb_ptr = (char *)sptr + elm->memb_offset;
 	}
 
-	return elm->type->uper_encoder(elm->type, elm->per_constraints,
+	if(ct && ct->range_bits >= 0) {
+		if(per_put_few_bits(po, present_enc, ct->range_bits))
+			ASN__ENCODE_FAILED;
+
+		return elm->type->uper_encoder(elm->type, elm->per_constraints,
 			memb_ptr, po);
+	} else {
+		asn_enc_rval_t rval;
+		if(specs->ext_start == -1)
+			ASN__ENCODE_FAILED;
+		if(uper_put_nsnnwn(po, present_enc - specs->ext_start))
+			ASN__ENCODE_FAILED;
+		if(uper_open_type_put(elm->type, elm->per_constraints,
+			memb_ptr, po))
+			ASN__ENCODE_FAILED;
+		rval.encoded = 0;
+		ASN__ENCODED_OK(rval);
+	}
 }
    
 
@@ -1020,7 +1033,7 @@ CHOICE_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 
 void
 CHOICE_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
-	asn_CHOICE_specifics_t *specs = td ? (asn_CHOICE_specifics_t *)td->specifics : NULL;
+	asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
 	int present;
 
 	if(!td || !ptr)
diff --git a/libs/smux/constr_SEQUENCE.c b/libs/smux/constr_SEQUENCE.c
index bc14ca5e..5923023d 100644
--- a/libs/smux/constr_SEQUENCE.c
+++ b/libs/smux/constr_SEQUENCE.c
@@ -1,10 +1,11 @@
 /*-
- * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2003, 2004, 2005, 2006, 2007 Lev Walkin <vlm@lionet.info>.
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #include <asn_internal.h>
 #include <constr_SEQUENCE.h>
+#include <per_opentype.h>
 
 /*
  * Number of bytes left for this structure.
@@ -33,7 +34,7 @@
 #undef	ADVANCE
 #define	ADVANCE(num_bytes)	do {		\
 		size_t num = num_bytes;		\
-		ptr = ((const char *)ptr) + num;\
+		ptr = ((const char *)ptr) + num; \
 		size -= num;			\
 		if(ctx->left >= 0)		\
 			ctx->left -= num;	\
@@ -309,16 +310,16 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 			 * Resort to a binary search over
 			 * sorted array of tags.
 			 */
-			asn_TYPE_tag2member_t *t2m;
+			const asn_TYPE_tag2member_t *t2m;
 			asn_TYPE_tag2member_t key;
 			key.el_tag = tlv_tag;
 			key.el_no = edx;
-			t2m = (asn_TYPE_tag2member_t *)bsearch(&key,
+			t2m = (const asn_TYPE_tag2member_t *)bsearch(&key,
 				specs->tag2el, specs->tag2el_count,
 				sizeof(specs->tag2el[0]), _t2e_cmp);
 			if(t2m) {
-				asn_TYPE_tag2member_t *best = 0;
-				asn_TYPE_tag2member_t *t2m_f, *t2m_l;
+				const asn_TYPE_tag2member_t *best = 0;
+				const asn_TYPE_tag2member_t *t2m_f, *t2m_l;
 				int edx_max = edx + elements[edx].optional;
 				/*
 				 * Rewind to the first element with that tag,
@@ -346,7 +347,8 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 			 * or an extension (...),
 			 * or an end of the indefinite-length structure.
 			 */
-			if(!IN_EXTENSION_GROUP(specs, edx)) {
+			if(!IN_EXTENSION_GROUP(specs,
+				edx + elements[edx].optional)) {
 				ASN_DEBUG("Unexpected tag %s (at %d)",
 					ber_tlv_tag_string(tlv_tag), edx);
 				ASN_DEBUG("Expected tag %s (%s)%s",
@@ -358,7 +360,10 @@ SEQUENCE_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 			} else {
 				/* Skip this tag */
 				ssize_t skip;
+				edx += elements[edx].optional;
 
+				ASN_DEBUG("Skipping unexpected %s (at %d)",
+					ber_tlv_tag_string(tlv_tag), edx);
 				skip = ber_skip_length(opt_codec_ctx,
 					BER_TLV_CONSTRUCTED(ptr),
 					(const char *)ptr + tag_len,
@@ -527,7 +532,7 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
 			if(!memb_ptr) {
 				if(elm->optional) continue;
 				/* Mandatory element is missing */
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 			}
 		} else {
 			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
@@ -548,10 +553,10 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
 	ret = der_write_tags(td, computed_size, tag_mode, 1, tag, cb, app_key);
 	ASN_DEBUG("Wrote tags: %ld (+%ld)", (long)ret, (long)computed_size);
 	if(ret == -1)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 	erval.encoded = computed_size + ret;
 
-	if(!cb) _ASN_ENCODED_OK(erval);
+	if(!cb) ASN__ENCODED_OK(erval);
 
 	/*
 	 * Encode all members.
@@ -581,9 +586,9 @@ SEQUENCE_encode_der(asn_TYPE_descriptor_t *td,
 		/*
 		 * Encoded size is not equal to the computed size.
 		 */
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
-	_ASN_ENCODED_OK(erval);
+	ASN__ENCODED_OK(erval);
 }
 
 
@@ -648,6 +653,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		ssize_t ch_size;		/* Chunk size */
 		xer_check_tag_e tcv;		/* Tag check value */
 		asn_TYPE_member_t *elm;
+		int n;
 
 		/*
 		 * Go inside the inner member of a sequence.
@@ -661,8 +667,7 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 			if(elm->flags & ATF_POINTER) {
 				/* Member is a pointer to another structure */
-				memb_ptr2 = (void **)((char *)st
-					+ elm->memb_offset);
+				memb_ptr2 = (void **)((char *)st + elm->memb_offset);
 			} else {
 				memb_ptr = (char *)st + elm->memb_offset;
 				memb_ptr2 = &memb_ptr;
@@ -687,11 +692,12 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		 */
 		ch_size = xer_next_token(&ctx->context, buf_ptr, size,
 			&ch_type);
-		switch(ch_size) {
-		case -1: RETURN(RC_FAIL);
-		case 0:  RETURN(RC_WMORE);
-		default:
+		if(ch_size == -1) {
+		    RETURN(RC_FAIL);
+        } else {
 			switch(ch_type) {
+            case PXER_WMORE:
+                RETURN(RC_WMORE);
 			case PXER_COMMENT:	/* Got XML comment */
 			case PXER_TEXT:		/* Ignore free-standing text */
 				XER_ADVANCE(ch_size);	/* Skip silently */
@@ -774,7 +780,6 @@ SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 				edx_end = edx + elements[edx].optional + 1;
 				if(edx_end > td->elements_count)
 					edx_end = td->elements_count;
-				int n;
 				for(n = edx; n < edx_end; n++) {
 					elm = &td->elements[n];
 					tcv = xer_check_tag(buf_ptr,
@@ -853,7 +858,7 @@ SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	int edx;
 
 	if(!sptr)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	er.encoded = 0;
 
@@ -870,29 +875,29 @@ SEQUENCE_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 				if(elm->optional)
 					continue;
 				/* Mandatory element is missing */
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 			}
 		} else {
 			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
 		}
 
-		if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
-		_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+		if(!xcan) ASN__TEXT_INDENT(1, ilevel);
+		ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 
 		/* Print the member itself */
 		tmper = elm->type->xer_encoder(elm->type, memb_ptr,
 			ilevel + 1, flags, cb, app_key);
 		if(tmper.encoded == -1) return tmper;
 
-		_ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+		ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
 		er.encoded += 5 + (2 * mlen) + tmper.encoded;
 	}
 
-	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
 int
@@ -976,7 +981,7 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 	int edx;
 
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -994,7 +999,7 @@ SEQUENCE_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 			if(!memb_ptr) {
 				if(elm->optional)
 					continue;
-				_ASN_CTFAIL(app_key, td,
+				ASN__CTFAIL(app_key, td, sptr,
 				"%s: mandatory element %s absent (%s:%d)",
 				td->name, elm->name, __FILE__, __LINE__);
 				return -1;
@@ -1027,7 +1032,7 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
 	asn_SEQUENCE_specifics_t *specs = (asn_SEQUENCE_specifics_t *)td->specifics;
 	void *st = *sptr;	/* Target structure. */
-	int extpresent = 0;	/* Extension additions are present */
+	int extpresent;		/* Extension additions are present */
 	uint8_t *opres;		/* Presence of optional root members */
 	asn_per_data_t opmd;
 	asn_dec_rval_t rv;
@@ -1035,12 +1040,12 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 	(void)constraints;
 
-	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
-		_ASN_DECODE_FAILED;
+	if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
+		ASN__DECODE_FAILED;
 
 	if(!st) {
 		st = *sptr = CALLOC(1, specs->struct_size);
-		if(!st) _ASN_DECODE_FAILED;
+		if(!st) ASN__DECODE_FAILED;
 	}
 
 	ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name);
@@ -1048,37 +1053,40 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	/* Handle extensions */
 	if(specs->ext_before >= 0) {
 		extpresent = per_get_few_bits(pd, 1);
-		if(extpresent < 0) _ASN_DECODE_STARVED;
+		if(extpresent < 0) ASN__DECODE_STARVED;
+	} else {
+		extpresent = 0;
 	}
 
 	/* Prepare a place and read-in the presence bitmap */
+	memset(&opmd, 0, sizeof(opmd));
 	if(specs->roms_count) {
 		opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1);
-		if(!opres) _ASN_DECODE_FAILED;
+		if(!opres) ASN__DECODE_FAILED;
 		/* Get the presence map */
 		if(per_get_many_bits(pd, opres, 0, specs->roms_count)) {
 			FREEMEM(opres);
-			_ASN_DECODE_STARVED;
+			ASN__DECODE_STARVED;
 		}
 		opmd.buffer = opres;
-		opmd.nboff = 0;
 		opmd.nbits = specs->roms_count;
 		ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)",
 			td->name, specs->roms_count, *opres);
 	} else {
 		opres = 0;
-		memset(&opmd, 0, sizeof opmd);
 	}
 
 	/*
 	 * Get the sequence ROOT elements.
 	 */
-	for(edx = 0; edx < ((specs->ext_before < 0)
-			? td->elements_count : specs->ext_before + 1); edx++) {
+	for(edx = 0; edx < td->elements_count; edx++) {
 		asn_TYPE_member_t *elm = &td->elements[edx];
 		void *memb_ptr;		/* Pointer to the member */
 		void **memb_ptr2;	/* Pointer to that pointer */
 
+		if(IN_EXTENSION_GROUP(specs, edx))
+			continue;
+
 		/* Fetch the pointer to this member */
 		if(elm->flags & ATF_POINTER) {
 			memb_ptr2 = (void **)((char *)st + elm->memb_offset);
@@ -1099,8 +1107,9 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 					/* Fill-in DEFAULT */
 					if(elm->default_value(1, memb_ptr2)) {
 						FREEMEM(opres);
-						_ASN_DECODE_FAILED;
+						ASN__DECODE_FAILED;
 					}
+					ASN_DEBUG("Filled-in default");
 				}
 				/* The member is just not present */
 				continue;
@@ -1120,63 +1129,201 @@ SEQUENCE_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		}
 	}
 
+	/* Optionality map is not needed anymore */
+	FREEMEM(opres);
+
 	/*
 	 * Deal with extensions.
 	 */
 	if(extpresent) {
-		ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name);
-		_ASN_DECODE_FAILED;
-	} else {
-		for(edx = specs->roms_count; edx < specs->roms_count
-				+ specs->aoms_count; edx++) {
-			asn_TYPE_member_t *elm = &td->elements[edx];
-			void *memb_ptr;		/* Pointer to the member */
-			void **memb_ptr2;	/* Pointer to that pointer */
+		ssize_t bmlength;
+		uint8_t *epres;		/* Presence of extension members */
+		asn_per_data_t epmd;
 
-			if(!elm->default_value) continue;
+		bmlength = uper_get_nslength(pd);
+		if(bmlength < 0) ASN__DECODE_STARVED;
 
-			/* Fetch the pointer to this member */
-			if(elm->flags & ATF_POINTER) {
-				memb_ptr2 = (void **)((char *)st
-						+ elm->memb_offset);
-			} else {
-				memb_ptr = (char *)st + elm->memb_offset;
-				memb_ptr2 = &memb_ptr;
-			}
+		ASN_DEBUG("Extensions %ld present in %s", (long)bmlength, td->name);
+
+		epres = (uint8_t *)MALLOC((bmlength + 15) >> 3);
+		if(!epres) ASN__DECODE_STARVED;
+
+		/* Get the extensions map */
+		if(per_get_many_bits(pd, epres, 0, bmlength)) {
+			FREEMEM(epres);
+			ASN__DECODE_STARVED;
+		}
+
+		memset(&epmd, 0, sizeof(epmd));
+		epmd.buffer = epres;
+		epmd.nbits = bmlength;
+		ASN_DEBUG("Read in extensions bitmap for %s of %ld bits (%x..)",
+			td->name, (long)bmlength, *epres);
+
+	    /* Go over extensions and read them in */
+	    for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
+		asn_TYPE_member_t *elm = &td->elements[edx];
+		void *memb_ptr;		/* Pointer to the member */
+		void **memb_ptr2;	/* Pointer to that pointer */
+		int present;
 
-			/* Set default value */
-			if(elm->default_value(1, memb_ptr2)) {
-				FREEMEM(opres);
-				_ASN_DECODE_FAILED;
+		if(!IN_EXTENSION_GROUP(specs, edx)) {
+			ASN_DEBUG("%d is not extension", edx);
+			continue;
+		}
+
+		/* Fetch the pointer to this member */
+		if(elm->flags & ATF_POINTER) {
+			memb_ptr2 = (void **)((char *)st + elm->memb_offset);
+		} else {
+			memb_ptr = (void *)((char *)st + elm->memb_offset);
+			memb_ptr2 = &memb_ptr;
+		}
+
+		present = per_get_few_bits(&epmd, 1);
+		if(present <= 0) {
+			if(present < 0) break;	/* No more extensions */
+			continue;
+		}
+
+		ASN_DEBUG("Decoding member %s in %s %p", elm->name, td->name, *memb_ptr2);
+		rv = uper_open_type_get(opt_codec_ctx, elm->type,
+			elm->per_constraints, memb_ptr2, pd);
+		if(rv.code != RC_OK) {
+			FREEMEM(epres);
+			return rv;
+		}
+	    }
+
+		/* Skip over overflow extensions which aren't present
+		 * in this system's version of the protocol */
+		for(;;) {
+			ASN_DEBUG("Getting overflow extensions");
+			switch(per_get_few_bits(&epmd, 1)) {
+			case -1: break;
+			case 0: continue;
+			default:
+				if(uper_open_type_skip(opt_codec_ctx, pd)) {
+					FREEMEM(epres);
+					ASN__DECODE_STARVED;
+				}
 			}
+			break;
+		}
+
+		FREEMEM(epres);
+	}
+
+	/* Fill DEFAULT members in extensions */
+	for(edx = specs->roms_count; edx < specs->roms_count
+			+ specs->aoms_count; edx++) {
+		asn_TYPE_member_t *elm = &td->elements[edx];
+		void **memb_ptr2;	/* Pointer to member pointer */
+
+		if(!elm->default_value) continue;
+
+		/* Fetch the pointer to this member */
+		if(elm->flags & ATF_POINTER) {
+			memb_ptr2 = (void **)((char *)st
+					+ elm->memb_offset);
+			if(*memb_ptr2) continue;
+		} else {
+			continue;	/* Extensions are all optionals */
+		}
+
+		/* Set default value */
+		if(elm->default_value(1, memb_ptr2)) {
+			ASN__DECODE_FAILED;
 		}
 	}
 
 	rv.consumed = 0;
 	rv.code = RC_OK;
-	FREEMEM(opres);
 	return rv;
 }
 
+static int
+SEQUENCE_handle_extensions(asn_TYPE_descriptor_t *td, void *sptr,
+		asn_per_outp_t *po1, asn_per_outp_t *po2) {
+	asn_SEQUENCE_specifics_t *specs
+		= (asn_SEQUENCE_specifics_t *)td->specifics;
+	int exts_present = 0;
+	int exts_count = 0;
+	int edx;
+
+	if(specs->ext_before < 0)
+		return 0;
+
+	/* Find out which extensions are present */
+	for(edx = specs->ext_after + 1; edx < td->elements_count; edx++) {
+		asn_TYPE_member_t *elm = &td->elements[edx];
+		void *memb_ptr;		/* Pointer to the member */
+		void **memb_ptr2;	/* Pointer to that pointer */
+		int present;
+
+		if(!IN_EXTENSION_GROUP(specs, edx)) {
+			ASN_DEBUG("%s (@%d) is not extension", elm->type->name, edx);
+			continue;
+		}
+
+		/* Fetch the pointer to this member */
+		if(elm->flags & ATF_POINTER) {
+			memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+			present = (*memb_ptr2 != 0);
+		} else {
+			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
+			memb_ptr2 = &memb_ptr;
+			present = 1;
+		}
+
+		ASN_DEBUG("checking %s (@%d) present => %d",
+			elm->type->name, edx, present);
+		exts_count++;
+		exts_present += present;
+
+		/* Encode as presence marker */
+		if(po1 && per_put_few_bits(po1, present, 1))
+			return -1;
+		/* Encode as open type field */
+		if(po2 && present && uper_open_type_put(elm->type,
+				elm->per_constraints, *memb_ptr2, po2))
+			return -1;
+
+	}
+
+	return exts_present ? exts_count : 0;
+}
+
 asn_enc_rval_t
 SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
 	asn_SEQUENCE_specifics_t *specs
 		= (asn_SEQUENCE_specifics_t *)td->specifics;
 	asn_enc_rval_t er;
+	int n_extensions;
 	int edx;
 	int i;
 
 	(void)constraints;
 
 	if(!sptr)
-		_ASN_ENCODE_FAILED;
+		ASN__ENCODE_FAILED;
 
 	er.encoded = 0;
 
 	ASN_DEBUG("Encoding %s as SEQUENCE (UPER)", td->name);
-	if(specs->ext_before >= 0)
-		_ASN_ENCODE_FAILED;	/* We don't encode extensions yet */
+
+
+	/*
+	 * X.691#18.1 Whether structure is extensible
+	 * and whether to encode extensions
+	 */
+	if(specs->ext_before >= 0) {
+		n_extensions = SEQUENCE_handle_extensions(td, sptr, 0, 0);
+		per_put_few_bits(po, n_extensions ? 1 : 0, 1);
+	} else {
+		n_extensions = 0;	/* There are no extensions to encode */
+	}
 
 	/* Encode a presence bitmap */
 	for(i = 0; i < specs->roms_count; i++) {
@@ -1208,18 +1355,25 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
 			elm->default_value ? "def" : "wtv",
 			td->name, elm->name, present ? "present" : "absent");
 		if(per_put_few_bits(po, present, 1))
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 	}
 
 	/*
-	 * Get the sequence ROOT elements.
+	 * Encode the sequence ROOT elements.
 	 */
-	for(edx = 0; edx < ((specs->ext_before < 0)
-			? td->elements_count : specs->ext_before + 1); edx++) {
+	ASN_DEBUG("ext_after = %d, ec = %d, eb = %d", specs->ext_after, td->elements_count, specs->ext_before);
+	for(edx = 0; edx < ((specs->ext_after < 0)
+		? td->elements_count : specs->ext_before - 1); edx++) {
+
 		asn_TYPE_member_t *elm = &td->elements[edx];
 		void *memb_ptr;		/* Pointer to the member */
 		void **memb_ptr2;	/* Pointer to that pointer */
 
+		if(IN_EXTENSION_GROUP(specs, edx))
+			continue;
+
+		ASN_DEBUG("About to encode %s", elm->type->name);
+
 		/* Fetch the pointer to this member */
 		if(elm->flags & ATF_POINTER) {
 			memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
@@ -1229,7 +1383,7 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
 				if(elm->optional)
 					continue;
 				/* Mandatory element is missing */
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 			}
 		} else {
 			memb_ptr = (void *)((char *)sptr + elm->memb_offset);
@@ -1240,12 +1394,32 @@ SEQUENCE_encode_uper(asn_TYPE_descriptor_t *td,
 		if(elm->default_value && elm->default_value(0, memb_ptr2) == 1)
 			continue;
 
+		ASN_DEBUG("Encoding %s->%s", td->name, elm->name);
 		er = elm->type->uper_encoder(elm->type, elm->per_constraints,
 			*memb_ptr2, po);
 		if(er.encoded == -1)
 			return er;
 	}
 
-	_ASN_ENCODED_OK(er);
+	/* No extensions to encode */
+	if(!n_extensions) ASN__ENCODED_OK(er);
+
+	ASN_DEBUG("Length of %d bit-map", n_extensions);
+	/* #18.8. Write down the presence bit-map length. */
+	if(uper_put_nslength(po, n_extensions))
+		ASN__ENCODE_FAILED;
+
+	ASN_DEBUG("Bit-map of %d elements", n_extensions);
+	/* #18.7. Encoding the extensions presence bit-map. */
+	/* TODO: act upon NOTE in #18.7 for canonical PER */
+	if(SEQUENCE_handle_extensions(td, sptr, po, 0) != n_extensions)
+		ASN__ENCODE_FAILED;
+
+	ASN_DEBUG("Writing %d extensions", n_extensions);
+	/* #18.9. Encode extensions as open type fields. */
+	if(SEQUENCE_handle_extensions(td, sptr, 0, po) != n_extensions)
+		ASN__ENCODE_FAILED;
+
+	ASN__ENCODED_OK(er);
 }
 
diff --git a/libs/smux/constr_SEQUENCE_OF.c b/libs/smux/constr_SEQUENCE_OF.c
index aa101176..8a08ee8a 100644
--- a/libs/smux/constr_SEQUENCE_OF.c
+++ b/libs/smux/constr_SEQUENCE_OF.c
@@ -52,7 +52,7 @@ SEQUENCE_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
 	computed_size += encoding_size;
 	if(!cb) {
 		erval.encoded = computed_size;
-		_ASN_ENCODED_OK(erval);
+		ASN__ENCODED_OK(erval);
 	}
 
 	ASN_DEBUG("Encoding members of SEQUENCE OF %s", td->name);
@@ -101,7 +101,7 @@ SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	int xcan = (flags & XER_F_CANONICAL);
 	int i;
 
-	if(!sptr) _ASN_ENCODE_FAILED;
+	if(!sptr) ASN__ENCODE_FAILED;
 
 	er.encoded = 0;
 
@@ -111,8 +111,8 @@ SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		if(!memb_ptr) continue;
 
 		if(mname) {
-			if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
-			_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+			if(!xcan) ASN__TEXT_INDENT(1, ilevel);
+			ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 		}
 
 		tmper = elm->type->xer_encoder(elm->type, memb_ptr,
@@ -121,23 +121,23 @@ SEQUENCE_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
                 if(tmper.encoded == 0 && specs->as_XMLValueList) {
                         const char *name = elm->type->xml_tag;
 			size_t len = strlen(name);
-			if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel + 1);
-			_ASN_CALLBACK3("<", 1, name, len, "/>", 2);
+			if(!xcan) ASN__TEXT_INDENT(1, ilevel + 1);
+			ASN__CALLBACK3("<", 1, name, len, "/>", 2);
                 }
 
 		if(mname) {
-			_ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+			ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
 			er.encoded += 5;
 		}
 
 		er.encoded += (2 * mlen) + tmper.encoded;
 	}
 
-	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
 asn_enc_rval_t
@@ -149,7 +149,7 @@ SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
 	asn_TYPE_member_t *elm = td->elements;
 	int seq;
 
-	if(!sptr) _ASN_ENCODE_FAILED;
+	if(!sptr) ASN__ENCODE_FAILED;
 	list = _A_SEQUENCE_FROM_VOID(sptr);
 
 	er.encoded = 0;
@@ -170,17 +170,17 @@ SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
 		if(ct->flags & APC_EXTENSIBLE) {
 			/* Declare whether size is in extension root */
 			if(per_put_few_bits(po, not_in_root, 1))
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 			if(not_in_root) ct = 0;
 		} else if(not_in_root && ct->effective_bits >= 0)
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 	}
 
 	if(ct && ct->effective_bits >= 0) {
 		/* X.691, #19.5: No length determinant */
 		if(per_put_few_bits(po, list->count - ct->lower_bound,
 				ct->effective_bits))
-			_ASN_ENCODE_FAILED;
+			ASN__ENCODE_FAILED;
 	}
 
 	for(seq = -1; seq < list->count;) {
@@ -190,19 +190,19 @@ SEQUENCE_OF_encode_uper(asn_TYPE_descriptor_t *td,
 			mayEncode = list->count;
 		} else {
 			mayEncode = uper_put_length(po, list->count - seq);
-			if(mayEncode < 0) _ASN_ENCODE_FAILED;
+			if(mayEncode < 0) ASN__ENCODE_FAILED;
 		}
 
 		while(mayEncode--) {
 			void *memb_ptr = list->array[seq++];
-			if(!memb_ptr) _ASN_ENCODE_FAILED;
+			if(!memb_ptr) ASN__ENCODE_FAILED;
 			er = elm->type->uper_encoder(elm->type,
 				elm->per_constraints, memb_ptr, po);
 			if(er.encoded == -1)
-				_ASN_ENCODE_FAILED;
+				ASN__ENCODE_FAILED;
 		}
 	}
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
diff --git a/libs/smux/constr_SET_OF.c b/libs/smux/constr_SET_OF.c
index 0d5efa4f..2dbc6e51 100644
--- a/libs/smux/constr_SET_OF.c
+++ b/libs/smux/constr_SET_OF.c
@@ -227,6 +227,8 @@ SET_OF_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 			}
 			/* Fall through */
 		case RC_FAIL: /* Fatal error */
+			ASN_STRUCT_FREE(*elm->type, ctx->ptr);
+			ctx->ptr = 0;
 			RETURN(RC_FAIL);
 		} /* switch(rval) */
 		
@@ -357,7 +359,7 @@ SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
 
 	if(!cb || list->count == 0) {
 		erval.encoded = computed_size;
-		_ASN_ENCODED_OK(erval);
+		ASN__ENCODED_OK(erval);
 	}
 
 	/*
@@ -449,7 +451,7 @@ SET_OF_encode_der(asn_TYPE_descriptor_t *td, void *ptr,
 		erval.encoded = computed_size;
 	}
 
-	_ASN_ENCODED_OK(erval);
+	ASN__ENCODED_OK(erval);
 }
 
 #undef	XER_ADVANCE
@@ -547,11 +549,12 @@ SET_OF_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		 */
 		ch_size = xer_next_token(&ctx->context,
 			buf_ptr, size, &ch_type);
-		switch(ch_size) {
-		case -1: RETURN(RC_FAIL);
-		case 0:  RETURN(RC_WMORE);
-		default:
+		if(ch_size == -1) {
+            RETURN(RC_FAIL);
+        } else {
 			switch(ch_type) {
+            case PXER_WMORE:
+                RETURN(RC_WMORE);
 			case PXER_COMMENT:	/* Got XML comment */
 			case PXER_TEXT:		/* Ignore free-standing text */
 				XER_ADVANCE(ch_size);	/* Skip silently */
@@ -665,11 +668,11 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 	asn_app_consume_bytes_f *original_cb = cb;
 	int i;
 
-	if(!sptr) _ASN_ENCODE_FAILED;
+	if(!sptr) ASN__ENCODE_FAILED;
 
 	if(xcan) {
 		encs = (xer_tmp_enc_t *)MALLOC(list->count * sizeof(encs[0]));
-		if(!encs) _ASN_ENCODE_FAILED;
+		if(!encs) ASN__ENCODE_FAILED;
 		cb = SET_OF_encode_xer_callback;
 	}
 
@@ -688,12 +691,12 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		}
 
 		if(mname) {
-			if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel);
-			_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+			if(!xcan) ASN__TEXT_INDENT(1, ilevel);
+			ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 		}
 
 		if(!xcan && specs->as_XMLValueList == 1)
-			_i_ASN_TEXT_INDENT(1, ilevel + 1);
+			ASN__TEXT_INDENT(1, ilevel + 1);
 		tmper = elm->type->xer_encoder(elm->type, memb_ptr,
 				ilevel + (specs->as_XMLValueList != 2),
 				flags, cb, app_key);
@@ -705,18 +708,18 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		if(tmper.encoded == 0 && specs->as_XMLValueList) {
 			const char *name = elm->type->xml_tag;
 			size_t len = strlen(name);
-			_ASN_CALLBACK3("<", 1, name, len, "/>", 2);
+			ASN__CALLBACK3("<", 1, name, len, "/>", 2);
 		}
 
 		if(mname) {
-			_ASN_CALLBACK3("</", 2, mname, mlen, ">", 1);
+			ASN__CALLBACK3("</", 2, mname, mlen, ">", 1);
 			er.encoded += 5;
 		}
 
 		er.encoded += (2 * mlen) + tmper.encoded;
 	}
 
-	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
+	if(!xcan) ASN__TEXT_INDENT(1, ilevel - 1);
 
 	if(encs) {
 		xer_tmp_enc_t *enc = encs;
@@ -728,7 +731,7 @@ SET_OF_encode_xer(asn_TYPE_descriptor_t *td, void *sptr,
 		qsort(encs, encs_count, sizeof(encs[0]), SET_OF_xer_order);
 
 		for(; enc < end; enc++) {
-			_ASN_CALLBACK(enc->buffer, enc->offset);
+			ASN__CALLBACK(enc->buffer, enc->offset);
 			FREEMEM(enc->buffer);
 			enc->buffer = 0;
 			control_size += enc->offset;
@@ -749,7 +752,7 @@ cleanup:
 		}
 		FREEMEM(encs);
 	}
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 }
 
 int
@@ -787,8 +790,10 @@ SET_OF_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
 void
 SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
 	if(td && ptr) {
+		asn_SET_OF_specifics_t *specs;
 		asn_TYPE_member_t *elm = td->elements;
 		asn_anonymous_set_ *list = _A_SET_FROM_VOID(ptr);
+		asn_struct_ctx_t *ctx;	/* Decoder context */
 		int i;
 
 		/*
@@ -804,6 +809,13 @@ SET_OF_free(asn_TYPE_descriptor_t *td, void *ptr, int contents_only) {
 
 		asn_set_empty(list);	/* Remove (list->array) */
 
+		specs = (asn_SET_OF_specifics_t *)td->specifics;
+		ctx = (asn_struct_ctx_t *)((char *)ptr + specs->ctx_offset);
+		if(ctx->ptr) {
+			ASN_STRUCT_FREE(*elm->type, ctx->ptr);
+			ctx->ptr = 0;
+		}
+
 		if(!contents_only) {
 			FREEMEM(ptr);
 		}
@@ -819,7 +831,7 @@ SET_OF_constraint(asn_TYPE_descriptor_t *td, const void *sptr,
 	int i;
 
 	if(!sptr) {
-		_ASN_CTFAIL(app_key, td,
+		ASN__CTFAIL(app_key, td, sptr,
 			"%s: value not given (%s:%d)",
 			td->name, __FILE__, __LINE__);
 		return -1;
@@ -864,15 +876,15 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	int repeat = 0;
 	ssize_t nelems;
 
-	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
-		_ASN_DECODE_FAILED;
+	if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
+		ASN__DECODE_FAILED;
 
 	/*
 	 * Create the target structure if it is not present already.
 	 */
 	if(!st) {
 		st = *sptr = CALLOC(1, specs->struct_size);
-		if(!st) _ASN_DECODE_FAILED;
+		if(!st) ASN__DECODE_FAILED;
 	}                                                                       
 	list = _A_SET_FROM_VOID(st);
 
@@ -883,7 +895,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 
 	if(ct && ct->flags & APC_EXTENSIBLE) {
 		int value = per_get_few_bits(pd, 1);
-		if(value < 0) _ASN_DECODE_STARVED;
+		if(value < 0) ASN__DECODE_STARVED;
 		if(value) ct = 0;	/* Not restricted! */
 	}
 
@@ -892,7 +904,7 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 		nelems = per_get_few_bits(pd, ct->effective_bits);
 		ASN_DEBUG("Preparing to fetch %ld+%ld elements from %s",
 			(long)nelems, ct->lower_bound, td->name);
-		if(nelems < 0)  _ASN_DECODE_STARVED;
+		if(nelems < 0)  ASN__DECODE_STARVED;
 		nelems += ct->lower_bound;
 	} else {
 		nelems = -1;
@@ -904,8 +916,8 @@ SET_OF_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 			nelems = uper_get_length(pd,
 				ct ? ct->effective_bits : -1, &repeat);
 			ASN_DEBUG("Got to decode %d elements (eff %d)",
-				(int)nelems, ct ? ct->effective_bits : -1);
-			if(nelems < 0) _ASN_DECODE_STARVED;
+				(int)nelems, (int)(ct ? ct->effective_bits : -1));
+			if(nelems < 0) ASN__DECODE_STARVED;
 		}
 
 		for(i = 0; i < nelems; i++) {
diff --git a/libs/smux/constr_TYPE.c b/libs/smux/constr_TYPE.c
index 4bc88d44..322f68c8 100644
--- a/libs/smux/constr_TYPE.c
+++ b/libs/smux/constr_TYPE.c
@@ -17,7 +17,7 @@ static asn_app_consume_bytes_f _print2fp;
  * Return the outmost tag of the type.
  */
 ber_tlv_tag_t
-asn_TYPE_outmost_tag(asn_TYPE_descriptor_t *type_descriptor,
+asn_TYPE_outmost_tag(const asn_TYPE_descriptor_t *type_descriptor,
 		const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag) {
 
 	if(tag_mode)
diff --git a/libs/smux/der_encoder.c b/libs/smux/der_encoder.c
index 6c859e1b..1c014802 100644
--- a/libs/smux/der_encoder.c
+++ b/libs/smux/der_encoder.c
@@ -80,8 +80,8 @@ der_write_tags(asn_TYPE_descriptor_t *sd,
 		ber_tlv_tag_t tag,	/* EXPLICIT or IMPLICIT tag */
 		asn_app_consume_bytes_f *cb,
 		void *app_key) {
-	ber_tlv_tag_t *tags;	/* Copy of tags stream */
-	int tags_count;		/* Number of tags */
+	const ber_tlv_tag_t *tags;	/* Copy of tags stream */
+	int tags_count;			/* Number of tags */
 	size_t overall_length;
 	ssize_t *lens;
 	int i;
@@ -102,8 +102,9 @@ der_write_tags(asn_TYPE_descriptor_t *sd,
 		 * and initialize it appropriately.
 		 */
 		int stag_offset;
-		tags = (ber_tlv_tag_t *)alloca((sd->tags_count + 1) * sizeof(ber_tlv_tag_t));
-		if(!tags) {	/* Can fail on !x86 */
+		ber_tlv_tag_t *tags_buf;
+		tags_buf = (ber_tlv_tag_t *)alloca((sd->tags_count + 1) * sizeof(ber_tlv_tag_t));
+		if(!tags_buf) {	/* Can fail on !x86 */
 			errno = ENOMEM;
 			return -1;
 		}
@@ -111,10 +112,11 @@ der_write_tags(asn_TYPE_descriptor_t *sd,
 			+ 1	/* EXPLICIT or IMPLICIT tag is given */
 			- ((tag_mode == -1) && sd->tags_count);
 		/* Copy tags over */
-		tags[0] = tag;
+		tags_buf[0] = tag;
 		stag_offset = -1 + ((tag_mode == -1) && sd->tags_count);
 		for(i = 1; i < tags_count; i++)
-			tags[i] = sd->tags[i + stag_offset];
+			tags_buf[i] = sd->tags[i + stag_offset];
+		tags = tags_buf;
 	} else {
 		tags = sd->tags;
 		tags_count = sd->tags_count;
diff --git a/libs/smux/include/stg/ApplicationSyntax.h b/libs/smux/include/stg/ApplicationSyntax.h
index 90a87076..a0f37545 100644
--- a/libs/smux/include/stg/ApplicationSyntax.h
+++ b/libs/smux/include/stg/ApplicationSyntax.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_ApplicationSyntax_H_
@@ -56,3 +56,4 @@ extern asn_TYPE_descriptor_t asn_DEF_ApplicationSyntax;
 #endif
 
 #endif	/* _ApplicationSyntax_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/AtEntry.h b/libs/smux/include/stg/AtEntry.h
index a0aba105..d07e8e94 100644
--- a/libs/smux/include/stg/AtEntry.h
+++ b/libs/smux/include/stg/AtEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_AtEntry_H_
@@ -39,3 +39,4 @@ extern asn_TYPE_descriptor_t asn_DEF_AtEntry;
 #endif
 
 #endif	/* _AtEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/ClosePDU.h b/libs/smux/include/stg/ClosePDU.h
index a3d1e7a9..0e90b6c4 100644
--- a/libs/smux/include/stg/ClosePDU.h
+++ b/libs/smux/include/stg/ClosePDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_ClosePDU_H_
@@ -46,3 +46,4 @@ xer_type_encoder_f ClosePDU_encode_xer;
 #endif
 
 #endif	/* _ClosePDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/Counter.h b/libs/smux/include/stg/Counter.h
index 3c770ada..3b7b7699 100644
--- a/libs/smux/include/stg/Counter.h
+++ b/libs/smux/include/stg/Counter.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_Counter_H_
@@ -12,14 +12,14 @@
 #include <asn_application.h>
 
 /* Including external dependencies */
-#include <INTEGER.h>
+#include <NativeInteger.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* Counter */
-typedef INTEGER_t	 Counter_t;
+typedef unsigned long	 Counter_t;
 
 /* Implementation */
 extern asn_TYPE_descriptor_t asn_DEF_Counter;
@@ -36,3 +36,4 @@ xer_type_encoder_f Counter_encode_xer;
 #endif
 
 #endif	/* _Counter_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/DisplayString.h b/libs/smux/include/stg/DisplayString.h
index ac6862c2..0be1c6cb 100644
--- a/libs/smux/include/stg/DisplayString.h
+++ b/libs/smux/include/stg/DisplayString.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_DisplayString_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f DisplayString_encode_xer;
 #endif
 
 #endif	/* _DisplayString_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/EgpNeighEntry.h b/libs/smux/include/stg/EgpNeighEntry.h
index 79d3eedd..422ce2df 100644
--- a/libs/smux/include/stg/EgpNeighEntry.h
+++ b/libs/smux/include/stg/EgpNeighEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_EgpNeighEntry_H_
@@ -51,3 +51,4 @@ extern asn_TYPE_descriptor_t asn_DEF_EgpNeighEntry;
 #endif
 
 #endif	/* _EgpNeighEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/Gauge.h b/libs/smux/include/stg/Gauge.h
index f3e17c5e..1fba79e9 100644
--- a/libs/smux/include/stg/Gauge.h
+++ b/libs/smux/include/stg/Gauge.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_Gauge_H_
@@ -12,14 +12,14 @@
 #include <asn_application.h>
 
 /* Including external dependencies */
-#include <INTEGER.h>
+#include <NativeInteger.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* Gauge */
-typedef INTEGER_t	 Gauge_t;
+typedef unsigned long	 Gauge_t;
 
 /* Implementation */
 extern asn_TYPE_descriptor_t asn_DEF_Gauge;
@@ -36,3 +36,4 @@ xer_type_encoder_f Gauge_encode_xer;
 #endif
 
 #endif	/* _Gauge_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/GetNextRequest-PDU.h b/libs/smux/include/stg/GetNextRequest-PDU.h
index f9298ec6..cecfd5ae 100644
--- a/libs/smux/include/stg/GetNextRequest-PDU.h
+++ b/libs/smux/include/stg/GetNextRequest-PDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_GetNextRequest_PDU_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f GetNextRequest_PDU_encode_xer;
 #endif
 
 #endif	/* _GetNextRequest_PDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/GetRequest-PDU.h b/libs/smux/include/stg/GetRequest-PDU.h
index 9449451f..872c5a2e 100644
--- a/libs/smux/include/stg/GetRequest-PDU.h
+++ b/libs/smux/include/stg/GetRequest-PDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_GetRequest_PDU_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f GetRequest_PDU_encode_xer;
 #endif
 
 #endif	/* _GetRequest_PDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/GetResponse-PDU.h b/libs/smux/include/stg/GetResponse-PDU.h
index 12e3fba1..b154ea3d 100644
--- a/libs/smux/include/stg/GetResponse-PDU.h
+++ b/libs/smux/include/stg/GetResponse-PDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_GetResponse_PDU_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f GetResponse_PDU_encode_xer;
 #endif
 
 #endif	/* _GetResponse_PDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/INTEGER.h b/libs/smux/include/stg/INTEGER.h
index 62832b12..9a880970 100644
--- a/libs/smux/include/stg/INTEGER.h
+++ b/libs/smux/include/stg/INTEGER.h
@@ -24,12 +24,14 @@ typedef struct asn_INTEGER_enum_map_s {
 } asn_INTEGER_enum_map_t;
 
 /* This type describes an enumeration for INTEGER and ENUMERATED types */
-typedef struct asn_INTEGER_specifics_s {
-	asn_INTEGER_enum_map_t *value2enum;	/* N -> "tag"; sorted by N */
-	unsigned int *enum2value;		/* "tag" => N; sorted by tag */
+typedef const struct asn_INTEGER_specifics_s {
+	const asn_INTEGER_enum_map_t *value2enum;	/* N -> "tag"; sorted by N */
+	const unsigned int *enum2value;		/* "tag" => N; sorted by tag */
 	int map_count;				/* Elements in either map */
 	int extension;				/* This map is extensible */
 	int strict_enumeration;			/* Enumeration set is fixed */
+	int field_width;			/* Size of native integer */
+	int field_unsigned;			/* Signed=0, unsigned=1 */
 } asn_INTEGER_specifics_t;
 
 asn_struct_print_f INTEGER_print;
@@ -51,7 +53,22 @@ per_type_encoder_f INTEGER_encode_uper;
  * -1/ENOMEM: Memory allocation failed (in asn_long2INTEGER()).
  */
 int asn_INTEGER2long(const INTEGER_t *i, long *l);
+int asn_INTEGER2ulong(const INTEGER_t *i, unsigned long *l);
 int asn_long2INTEGER(INTEGER_t *i, long l);
+int asn_ulong2INTEGER(INTEGER_t *i, unsigned long l);
+
+/* A a reified version of strtol(3) with nicer error reporting. */
+enum asn_strtol_result_e {
+    ASN_STRTOL_ERROR_RANGE = -3,  /* Input outside of numeric range for long type */
+    ASN_STRTOL_ERROR_INVAL = -2,  /* Invalid data encountered (e.g., "+-") */
+    ASN_STRTOL_EXPECT_MORE = -1,  /* More data expected (e.g. "+") */
+    ASN_STRTOL_OK          =  0,  /* Conversion succeded, number ends at (*end) */
+    ASN_STRTOL_EXTRA_DATA  =  1   /* Conversion succeded, but the string has extra stuff */
+};
+enum asn_strtol_result_e asn_strtol_lim(const char *str, const char **end, long *l);
+
+/* The asn_strtol is going to be DEPRECATED soon */
+enum asn_strtol_result_e asn_strtol(const char *str, const char *end, long *l);
 
 /*
  * Convert the integer value into the corresponding enumeration map entry.
diff --git a/libs/smux/include/stg/IfEntry.h b/libs/smux/include/stg/IfEntry.h
index eb30717b..9fdd9477 100644
--- a/libs/smux/include/stg/IfEntry.h
+++ b/libs/smux/include/stg/IfEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_IfEntry_H_
@@ -62,3 +62,4 @@ extern asn_TYPE_descriptor_t asn_DEF_IfEntry;
 #endif
 
 #endif	/* _IfEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/IpAddrEntry.h b/libs/smux/include/stg/IpAddrEntry.h
index 9e36f32a..0a44b3cb 100644
--- a/libs/smux/include/stg/IpAddrEntry.h
+++ b/libs/smux/include/stg/IpAddrEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_IpAddrEntry_H_
@@ -41,3 +41,4 @@ extern asn_TYPE_descriptor_t asn_DEF_IpAddrEntry;
 #endif
 
 #endif	/* _IpAddrEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/IpAddress.h b/libs/smux/include/stg/IpAddress.h
index 06c1d4a3..544cb40c 100644
--- a/libs/smux/include/stg/IpAddress.h
+++ b/libs/smux/include/stg/IpAddress.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_IpAddress_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f IpAddress_encode_xer;
 #endif
 
 #endif	/* _IpAddress_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/IpNetToMediaEntry.h b/libs/smux/include/stg/IpNetToMediaEntry.h
index 1eb8124f..ca72bff6 100644
--- a/libs/smux/include/stg/IpNetToMediaEntry.h
+++ b/libs/smux/include/stg/IpNetToMediaEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_IpNetToMediaEntry_H_
@@ -40,3 +40,4 @@ extern asn_TYPE_descriptor_t asn_DEF_IpNetToMediaEntry;
 #endif
 
 #endif	/* _IpNetToMediaEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/IpRouteEntry.h b/libs/smux/include/stg/IpRouteEntry.h
index 5651a8fc..28030dcb 100644
--- a/libs/smux/include/stg/IpRouteEntry.h
+++ b/libs/smux/include/stg/IpRouteEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_IpRouteEntry_H_
@@ -49,3 +49,4 @@ extern asn_TYPE_descriptor_t asn_DEF_IpRouteEntry;
 #endif
 
 #endif	/* _IpRouteEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/Message.h b/libs/smux/include/stg/Message.h
index 2621d73c..3049e477 100644
--- a/libs/smux/include/stg/Message.h
+++ b/libs/smux/include/stg/Message.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_Message_H_
@@ -44,3 +44,4 @@ extern asn_TYPE_descriptor_t asn_DEF_Message;
 #endif
 
 #endif	/* _Message_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/NetworkAddress.h b/libs/smux/include/stg/NetworkAddress.h
index 8c73220b..8bcba17d 100644
--- a/libs/smux/include/stg/NetworkAddress.h
+++ b/libs/smux/include/stg/NetworkAddress.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_NetworkAddress_H_
@@ -44,3 +44,4 @@ extern asn_TYPE_descriptor_t asn_DEF_NetworkAddress;
 #endif
 
 #endif	/* _NetworkAddress_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/OBJECT_IDENTIFIER.h b/libs/smux/include/stg/OBJECT_IDENTIFIER.h
index 2bb5d032..c2c6373e 100644
--- a/libs/smux/include/stg/OBJECT_IDENTIFIER.h
+++ b/libs/smux/include/stg/OBJECT_IDENTIFIER.h
@@ -68,7 +68,7 @@ xer_type_encoder_f OBJECT_IDENTIFIER_encode_xer;
  * WARNING: The function always returns the real number of arcs,
  * even if there is no sufficient (_arc_slots) provided.
  */
-int OBJECT_IDENTIFIER_get_arcs(OBJECT_IDENTIFIER_t *_oid,
+int OBJECT_IDENTIFIER_get_arcs(const OBJECT_IDENTIFIER_t *_oid,
 	void *_arcs,			/* e.g., unsigned int arcs[N] */
 	unsigned int _arc_type_size,	/* e.g., sizeof(arcs[0]) */
 	unsigned int _arc_slots		/* e.g., N */);
@@ -91,12 +91,12 @@ int OBJECT_IDENTIFIER_set_arcs(OBJECT_IDENTIFIER_t *_oid,
 /*
  * Print the specified OBJECT IDENTIFIER arc.
  */
-int OBJECT_IDENTIFIER_print_arc(uint8_t *arcbuf, int arclen,
+int OBJECT_IDENTIFIER_print_arc(const uint8_t *arcbuf, int arclen,
 	int add, /* Arbitrary offset, required to process the first two arcs */
 	asn_app_consume_bytes_f *cb, void *app_key);
 
 /* Same as above, but returns the number of written digits, instead of 0 */
-ssize_t OBJECT_IDENTIFIER__dump_arc(uint8_t *arcbuf, int arclen, int add,
+ssize_t OBJECT_IDENTIFIER__dump_arc(const uint8_t *arcbuf, int arclen, int add,
 	asn_app_consume_bytes_f *cb, void *app_key);
 
 /*
@@ -127,7 +127,7 @@ int OBJECT_IDENTIFIER_parse_arcs(const char *oid_text, ssize_t oid_txt_length,
  * Internal functions.
  * Used by RELATIVE-OID implementation in particular.
  */
-int OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen,
+int OBJECT_IDENTIFIER_get_single_arc(const uint8_t *arcbuf, unsigned int arclen,
 	signed int add, void *value, unsigned int value_size);
 int OBJECT_IDENTIFIER_set_single_arc(uint8_t *arcbuf,
 	const void *arcval, unsigned int arcval_size, int _prepared_order);
diff --git a/libs/smux/include/stg/OCTET_STRING.h b/libs/smux/include/stg/OCTET_STRING.h
index 5150161a..013c7b13 100644
--- a/libs/smux/include/stg/OCTET_STRING.h
+++ b/libs/smux/include/stg/OCTET_STRING.h
@@ -63,14 +63,20 @@ OCTET_STRING_t *OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td,
  * Internally useful stuff. *
  ****************************/
 
-typedef struct asn_OCTET_STRING_specifics_s {
+typedef const struct asn_OCTET_STRING_specifics_s {
 	/*
 	 * Target structure description.
 	 */
 	int struct_size;	/* Size of the structure */
 	int ctx_offset;		/* Offset of the asn_struct_ctx_t member */
 
-	int subvariant;		/* {0,1,2} for O-S, BIT STRING or ANY */
+	enum asn_OS_Subvariant {
+		ASN_OSUBV_ANY,	/* The open type (ANY) */
+		ASN_OSUBV_BIT,	/* BIT STRING */
+		ASN_OSUBV_STR,	/* String types, not {BMP,Universal}String  */
+		ASN_OSUBV_U16,	/* 16-bit character (BMPString) */
+		ASN_OSUBV_U32	/* 32-bit character (UniversalString) */
+	} subvariant;
 } asn_OCTET_STRING_specifics_t;
 
 #ifdef __cplusplus
diff --git a/libs/smux/include/stg/ObjectName.h b/libs/smux/include/stg/ObjectName.h
index 256577b3..4187cd0c 100644
--- a/libs/smux/include/stg/ObjectName.h
+++ b/libs/smux/include/stg/ObjectName.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_ObjectName_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f ObjectName_encode_xer;
 #endif
 
 #endif	/* _ObjectName_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/ObjectSyntax.h b/libs/smux/include/stg/ObjectSyntax.h
index 9030accb..ad56e7e0 100644
--- a/libs/smux/include/stg/ObjectSyntax.h
+++ b/libs/smux/include/stg/ObjectSyntax.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_ObjectSyntax_H_
@@ -47,3 +47,4 @@ extern asn_TYPE_descriptor_t asn_DEF_ObjectSyntax;
 #endif
 
 #endif	/* _ObjectSyntax_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/Opaque.h b/libs/smux/include/stg/Opaque.h
index aa8e2d5f..ff94eff6 100644
--- a/libs/smux/include/stg/Opaque.h
+++ b/libs/smux/include/stg/Opaque.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_Opaque_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f Opaque_encode_xer;
 #endif
 
 #endif	/* _Opaque_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/OpenPDU.h b/libs/smux/include/stg/OpenPDU.h
index 5d7e1da6..1b77d558 100644
--- a/libs/smux/include/stg/OpenPDU.h
+++ b/libs/smux/include/stg/OpenPDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_OpenPDU_H_
@@ -44,3 +44,4 @@ extern asn_TYPE_descriptor_t asn_DEF_OpenPDU;
 #endif
 
 #endif	/* _OpenPDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/PDU.h b/libs/smux/include/stg/PDU.h
index cbc7e714..10e30f17 100644
--- a/libs/smux/include/stg/PDU.h
+++ b/libs/smux/include/stg/PDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_PDU_H_
@@ -49,3 +49,4 @@ extern asn_TYPE_descriptor_t asn_DEF_PDU;
 #endif
 
 #endif	/* _PDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/PDUs.h b/libs/smux/include/stg/PDUs.h
index 90bb089f..db197d31 100644
--- a/libs/smux/include/stg/PDUs.h
+++ b/libs/smux/include/stg/PDUs.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_PDUs_H_
@@ -56,3 +56,4 @@ extern asn_TYPE_descriptor_t asn_DEF_PDUs;
 #endif
 
 #endif	/* _PDUs_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/PhysAddress.h b/libs/smux/include/stg/PhysAddress.h
index d6c5fa17..08e43e91 100644
--- a/libs/smux/include/stg/PhysAddress.h
+++ b/libs/smux/include/stg/PhysAddress.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_PhysAddress_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f PhysAddress_encode_xer;
 #endif
 
 #endif	/* _PhysAddress_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/RReqPDU.h b/libs/smux/include/stg/RReqPDU.h
index 17f53094..570c1964 100644
--- a/libs/smux/include/stg/RReqPDU.h
+++ b/libs/smux/include/stg/RReqPDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_RReqPDU_H_
@@ -46,3 +46,4 @@ extern asn_TYPE_descriptor_t asn_DEF_RReqPDU;
 #endif
 
 #endif	/* _RReqPDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/RRspPDU.h b/libs/smux/include/stg/RRspPDU.h
index 0d9681ac..f9b43874 100644
--- a/libs/smux/include/stg/RRspPDU.h
+++ b/libs/smux/include/stg/RRspPDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_RRspPDU_H_
@@ -41,3 +41,4 @@ xer_type_encoder_f RRspPDU_encode_xer;
 #endif
 
 #endif	/* _RRspPDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/SMUX-PDUs.h b/libs/smux/include/stg/SMUX-PDUs.h
index 84893249..03387542 100644
--- a/libs/smux/include/stg/SMUX-PDUs.h
+++ b/libs/smux/include/stg/SMUX-PDUs.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_SMUX_PDUs_H_
@@ -59,3 +59,4 @@ extern asn_TYPE_descriptor_t asn_DEF_SMUX_PDUs;
 #endif
 
 #endif	/* _SMUX_PDUs_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/SOutPDU.h b/libs/smux/include/stg/SOutPDU.h
index 55e76185..d0259f9a 100644
--- a/libs/smux/include/stg/SOutPDU.h
+++ b/libs/smux/include/stg/SOutPDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_SOutPDU_H_
@@ -42,3 +42,4 @@ xer_type_encoder_f SOutPDU_encode_xer;
 #endif
 
 #endif	/* _SOutPDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/SetRequest-PDU.h b/libs/smux/include/stg/SetRequest-PDU.h
index 8854574c..1a5636fb 100644
--- a/libs/smux/include/stg/SetRequest-PDU.h
+++ b/libs/smux/include/stg/SetRequest-PDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_SetRequest_PDU_H_
@@ -36,3 +36,4 @@ xer_type_encoder_f SetRequest_PDU_encode_xer;
 #endif
 
 #endif	/* _SetRequest_PDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/SimpleOpen.h b/libs/smux/include/stg/SimpleOpen.h
index 5950a6c1..4f838ade 100644
--- a/libs/smux/include/stg/SimpleOpen.h
+++ b/libs/smux/include/stg/SimpleOpen.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "SMUX"
  * 	found in "SMUX.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_SimpleOpen_H_
@@ -46,3 +46,4 @@ extern asn_TYPE_descriptor_t asn_DEF_SimpleOpen;
 #endif
 
 #endif	/* _SimpleOpen_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/SimpleSyntax.h b/libs/smux/include/stg/SimpleSyntax.h
index c04f3ab2..dcf32c95 100644
--- a/libs/smux/include/stg/SimpleSyntax.h
+++ b/libs/smux/include/stg/SimpleSyntax.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_SimpleSyntax_H_
@@ -53,3 +53,4 @@ extern asn_TYPE_descriptor_t asn_DEF_SimpleSyntax;
 #endif
 
 #endif	/* _SimpleSyntax_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/TcpConnEntry.h b/libs/smux/include/stg/TcpConnEntry.h
index 3160e31f..fb3d33ca 100644
--- a/libs/smux/include/stg/TcpConnEntry.h
+++ b/libs/smux/include/stg/TcpConnEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_TcpConnEntry_H_
@@ -41,3 +41,4 @@ extern asn_TYPE_descriptor_t asn_DEF_TcpConnEntry;
 #endif
 
 #endif	/* _TcpConnEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/TimeTicks.h b/libs/smux/include/stg/TimeTicks.h
index ea92820f..fe7ea1db 100644
--- a/libs/smux/include/stg/TimeTicks.h
+++ b/libs/smux/include/stg/TimeTicks.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1155-SMI"
  * 	found in "RFC1155-SMI.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_TimeTicks_H_
@@ -12,14 +12,14 @@
 #include <asn_application.h>
 
 /* Including external dependencies */
-#include <INTEGER.h>
+#include <NativeInteger.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* TimeTicks */
-typedef INTEGER_t	 TimeTicks_t;
+typedef unsigned long	 TimeTicks_t;
 
 /* Implementation */
 extern asn_TYPE_descriptor_t asn_DEF_TimeTicks;
@@ -36,3 +36,4 @@ xer_type_encoder_f TimeTicks_encode_xer;
 #endif
 
 #endif	/* _TimeTicks_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/Trap-PDU.h b/libs/smux/include/stg/Trap-PDU.h
index d8a89e11..f4169aeb 100644
--- a/libs/smux/include/stg/Trap-PDU.h
+++ b/libs/smux/include/stg/Trap-PDU.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_Trap_PDU_H_
@@ -55,3 +55,4 @@ extern asn_TYPE_descriptor_t asn_DEF_Trap_PDU;
 #endif
 
 #endif	/* _Trap_PDU_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/UdpEntry.h b/libs/smux/include/stg/UdpEntry.h
index e4a10264..af9772d5 100644
--- a/libs/smux/include/stg/UdpEntry.h
+++ b/libs/smux/include/stg/UdpEntry.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1213-MIB"
  * 	found in "RFC1213-MIB.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_UdpEntry_H_
@@ -37,3 +37,4 @@ extern asn_TYPE_descriptor_t asn_DEF_UdpEntry;
 #endif
 
 #endif	/* _UdpEntry_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/VarBind.h b/libs/smux/include/stg/VarBind.h
index 63ecad5f..6291d640 100644
--- a/libs/smux/include/stg/VarBind.h
+++ b/libs/smux/include/stg/VarBind.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_VarBind_H_
@@ -37,3 +37,4 @@ extern asn_TYPE_descriptor_t asn_DEF_VarBind;
 #endif
 
 #endif	/* _VarBind_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/VarBindList.h b/libs/smux/include/stg/VarBindList.h
index 36ef1617..b9061796 100644
--- a/libs/smux/include/stg/VarBindList.h
+++ b/libs/smux/include/stg/VarBindList.h
@@ -1,8 +1,8 @@
 /*
- * Generated by asn1c-0.9.21 (http://lionet.info/asn1c)
+ * Generated by asn1c-0.9.28 (http://lionet.info/asn1c)
  * From ASN.1 module "RFC1157-SNMP"
  * 	found in "RFC1157-SNMP.asn1"
- * 	`asn1c -fskeletons-copy`
+ * 	`asn1c -S/mnt/data/software/asn1c/skeletons -fcompound-names -fwide-types`
  */
 
 #ifndef	_VarBindList_H_
@@ -41,3 +41,4 @@ extern asn_TYPE_descriptor_t asn_DEF_VarBindList;
 #include "VarBind.h"
 
 #endif	/* _VarBindList_H_ */
+#include <asn_internal.h>
diff --git a/libs/smux/include/stg/asn_application.h b/libs/smux/include/stg/asn_application.h
index f40cd86a..71e9ba61 100644
--- a/libs/smux/include/stg/asn_application.h
+++ b/libs/smux/include/stg/asn_application.h
@@ -5,8 +5,8 @@
 /*
  * Application-level ASN.1 callbacks.
  */
-#ifndef	_ASN_APPLICATION_H_
-#define	_ASN_APPLICATION_H_
+#ifndef	ASN_APPLICATION_H
+#define	ASN_APPLICATION_H
 
 #include "asn_system.h"		/* for platform-dependent types */
 #include "asn_codecs.h"		/* for ASN.1 codecs specifics */
@@ -44,4 +44,4 @@ typedef void (asn_app_constraint_failed_f)(void *application_specific_key,
 
 #include "constr_TYPE.h"	/* for asn_TYPE_descriptor_t */
 
-#endif	/* _ASN_APPLICATION_H_ */
+#endif	/* ASN_APPLICATION_H */
diff --git a/libs/smux/include/stg/asn_codecs.h b/libs/smux/include/stg/asn_codecs.h
index 4a251d94..4b2a2942 100644
--- a/libs/smux/include/stg/asn_codecs.h
+++ b/libs/smux/include/stg/asn_codecs.h
@@ -3,8 +3,8 @@
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
-#ifndef	_ASN_CODECS_H_
-#define	_ASN_CODECS_H_
+#ifndef	ASN_CODECS_H
+#define	ASN_CODECS_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -57,15 +57,15 @@ typedef struct asn_enc_rval_s {
 	/* Pointer to the structure of that type */
 	void *structure_ptr;
 } asn_enc_rval_t;
-#define	_ASN_ENCODE_FAILED do {					\
+#define	ASN__ENCODE_FAILED do {					\
 	asn_enc_rval_t tmp_error;				\
 	tmp_error.encoded = -1;					\
 	tmp_error.failed_type = td;				\
 	tmp_error.structure_ptr = sptr;				\
-	ASN_DEBUG("Failed to encode element %s", td->name);	\
+	ASN_DEBUG("Failed to encode element %s", td ? td->name : "");	\
 	return tmp_error;					\
 } while(0)
-#define	_ASN_ENCODED_OK(rval) do {				\
+#define	ASN__ENCODED_OK(rval) do {				\
 	rval.structure_ptr = 0;					\
 	rval.failed_type = 0;					\
 	return rval;						\
@@ -88,14 +88,14 @@ typedef struct asn_dec_rval_s {
 	enum asn_dec_rval_code_e code;	/* Result code */
 	size_t consumed;		/* Number of bytes consumed */
 } asn_dec_rval_t;
-#define	_ASN_DECODE_FAILED do {					\
+#define	ASN__DECODE_FAILED do {					\
 	asn_dec_rval_t tmp_error;				\
 	tmp_error.code = RC_FAIL;				\
 	tmp_error.consumed = 0;					\
-	ASN_DEBUG("Failed to decode element %s", td->name);	\
+	ASN_DEBUG("Failed to decode element %s", td ? td->name : "");	\
 	return tmp_error;					\
 } while(0)
-#define	_ASN_DECODE_STARVED do {				\
+#define	ASN__DECODE_STARVED do {				\
 	asn_dec_rval_t tmp_error;				\
 	tmp_error.code = RC_WMORE;				\
 	tmp_error.consumed = 0;					\
@@ -106,4 +106,4 @@ typedef struct asn_dec_rval_s {
 }
 #endif
 
-#endif	/* _ASN_CODECS_H_ */
+#endif	/* ASN_CODECS_H */
diff --git a/libs/smux/include/stg/asn_internal.h b/libs/smux/include/stg/asn_internal.h
index 67f055a6..9c94ca6c 100644
--- a/libs/smux/include/stg/asn_internal.h
+++ b/libs/smux/include/stg/asn_internal.h
@@ -1,13 +1,13 @@
 /*-
- * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>.
+ * Copyright (c) 2003, 2004, 2005, 2007 Lev Walkin <vlm@lionet.info>.
  * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 /*
  * Declarations internally useful for the ASN.1 support code.
  */
-#ifndef	_ASN_INTERNAL_H_
-#define	_ASN_INTERNAL_H_
+#ifndef	ASN_INTERNAL_H
+#define	ASN_INTERNAL_H
 
 #include "asn_application.h"	/* Application-visible API */
 
@@ -20,7 +20,7 @@ extern "C" {
 #endif
 
 /* Environment version might be used to avoid running with the old library */
-#define	ASN1C_ENVIRONMENT_VERSION	920	/* Compile-time version */
+#define	ASN1C_ENVIRONMENT_VERSION	923	/* Compile-time version */
 int get_asn1c_environment_version(void);	/* Run-time version */
 
 #define	CALLOC(nmemb, size)	calloc(nmemb, size)
@@ -28,6 +28,9 @@ int get_asn1c_environment_version(void);	/* Run-time version */
 #define	REALLOC(oldptr, size)	realloc(oldptr, size)
 #define	FREEMEM(ptr)		free(ptr)
 
+#define	asn_debug_indent	0
+#define ASN_DEBUG_INDENT_ADD(i) do{}while(0)
+
 /*
  * A macro for debugging the ASN.1 internals.
  * You may enable or override it.
@@ -35,59 +38,73 @@ int get_asn1c_environment_version(void);	/* Run-time version */
 #ifndef	ASN_DEBUG	/* If debugging code is not defined elsewhere... */
 #if	EMIT_ASN_DEBUG == 1	/* And it was asked to emit this code... */
 #ifdef	__GNUC__
-#define	ASN_DEBUG(fmt, args...)	do {		\
-		fprintf(stderr, fmt, ##args);	\
-		fprintf(stderr, " (%s:%d)\n",	\
-			__FILE__, __LINE__);	\
+#ifdef	ASN_THREAD_SAFE
+/* Thread safety requires sacrifice in output indentation:
+ * Retain empty definition of ASN_DEBUG_INDENT_ADD. */
+#else	/* !ASN_THREAD_SAFE */
+#undef  ASN_DEBUG_INDENT_ADD
+#undef  asn_debug_indent
+int asn_debug_indent;
+#define ASN_DEBUG_INDENT_ADD(i) do { asn_debug_indent += i; } while(0)
+#endif	/* ASN_THREAD_SAFE */
+#define	ASN_DEBUG(fmt, args...)	do {			\
+		int adi = asn_debug_indent;		\
+		while(adi--) fprintf(stderr, " ");	\
+		fprintf(stderr, fmt, ##args);		\
+		fprintf(stderr, " (%s:%d)\n",		\
+			__FILE__, __LINE__);		\
 	} while(0)
 #else	/* !__GNUC__ */
 void ASN_DEBUG_f(const char *fmt, ...);
 #define	ASN_DEBUG	ASN_DEBUG_f
 #endif	/* __GNUC__ */
 #else	/* EMIT_ASN_DEBUG != 1 */
-static inline void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
+static void ASN_DEBUG(const char *fmt, ...) { (void)fmt; }
 #endif	/* EMIT_ASN_DEBUG */
 #endif	/* ASN_DEBUG */
 
 /*
  * Invoke the application-supplied callback and fail, if something is wrong.
  */
-#define	__ASN_E_cbc(buf, size)	(cb((buf), (size), app_key) < 0)
-#define	_ASN_E_CALLBACK(foo)	do {					\
+#define	ASN__E_cbc(buf, size)	(cb((buf), (size), app_key) < 0)
+#define	ASN__E_CALLBACK(foo)	do {					\
 		if(foo)	goto cb_failed;					\
 	} while(0)
-#define	_ASN_CALLBACK(buf, size)					\
-	_ASN_E_CALLBACK(__ASN_E_cbc(buf, size))
-#define	_ASN_CALLBACK2(buf1, size1, buf2, size2)			\
-	_ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1) || __ASN_E_cbc(buf2, size2))
-#define	_ASN_CALLBACK3(buf1, size1, buf2, size2, buf3, size3)		\
-	_ASN_E_CALLBACK(__ASN_E_cbc(buf1, size1)			\
-		|| __ASN_E_cbc(buf2, size2)				\
-		|| __ASN_E_cbc(buf3, size3))
+#define	ASN__CALLBACK(buf, size)					\
+	ASN__E_CALLBACK(ASN__E_cbc(buf, size))
+#define	ASN__CALLBACK2(buf1, size1, buf2, size2)			\
+	ASN__E_CALLBACK(ASN__E_cbc(buf1, size1) || ASN__E_cbc(buf2, size2))
+#define	ASN__CALLBACK3(buf1, size1, buf2, size2, buf3, size3)		\
+	ASN__E_CALLBACK(ASN__E_cbc(buf1, size1)			\
+		|| ASN__E_cbc(buf2, size2)				\
+		|| ASN__E_cbc(buf3, size3))
 
-#define	_i_ASN_TEXT_INDENT(nl, level) do {				\
-	int __level = (level);						\
-	int __nl = ((nl) != 0);						\
-	int __i;							\
-	if(__nl) _ASN_CALLBACK("\n", 1);				\
-	for(__i = 0; __i < __level; __i++)				\
-		_ASN_CALLBACK("    ", 4);				\
-	er.encoded += __nl + 4 * __level;				\
-} while(0)
+#define	ASN__TEXT_INDENT(nl, level) do {            \
+        int tmp_level = (level);                    \
+        int tmp_nl = ((nl) != 0);                   \
+        int tmp_i;                                  \
+        if(tmp_nl) ASN__CALLBACK("\n", 1);          \
+        if(tmp_level < 0) tmp_level = 0;            \
+        for(tmp_i = 0; tmp_i < tmp_level; tmp_i++)  \
+            ASN__CALLBACK("    ", 4);               \
+        er.encoded += tmp_nl + 4 * tmp_level;       \
+    } while(0)
 
-#define	_i_INDENT(nl)	do {						\
-	int __i;							\
-	if((nl) && cb("\n", 1, app_key) < 0) return -1;			\
-	for(__i = 0; __i < ilevel; __i++)				\
-		if(cb("    ", 4, app_key) < 0) return -1;		\
-} while(0)
+#define	_i_INDENT(nl)	do {                        \
+        int tmp_i;                                  \
+        if((nl) && cb("\n", 1, app_key) < 0)        \
+            return -1;                              \
+        for(tmp_i = 0; tmp_i < ilevel; tmp_i++)     \
+            if(cb("    ", 4, app_key) < 0)          \
+                return -1;                          \
+    } while(0)
 
 /*
  * Check stack against overflow, if limit is set.
  */
-#define	_ASN_DEFAULT_STACK_MAX	(30000)
-static inline int
-_ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
+#define	ASN__DEFAULT_STACK_MAX	(30000)
+static int __attribute__((unused))
+ASN__STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
 	if(ctx && ctx->max_stack_size) {
 
 		/* ctx MUST be allocated on the stack */
@@ -108,4 +125,4 @@ _ASN_STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
 }
 #endif
 
-#endif	/* _ASN_INTERNAL_H_ */
+#endif	/* ASN_INTERNAL_H */
diff --git a/libs/smux/include/stg/asn_system.h b/libs/smux/include/stg/asn_system.h
index d7ebdaa4..d19837ed 100644
--- a/libs/smux/include/stg/asn_system.h
+++ b/libs/smux/include/stg/asn_system.h
@@ -1,35 +1,51 @@
 /*-
- * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2003, 2004, 2007 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 /*
  * Miscellaneous system-dependent types.
  */
-#ifndef	_ASN_SYSTEM_H_
-#define	_ASN_SYSTEM_H_
+#ifndef	ASN_SYSTEM_H
+#define	ASN_SYSTEM_H
 
 #ifdef	HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE /* for snprintf() on some linux systems  */
+#endif
+
 #include <stdio.h>	/* For snprintf(3) */
 #include <stdlib.h>	/* For *alloc(3) */
 #include <string.h>	/* For memcpy(3) */
 #include <sys/types.h>	/* For size_t */
+#include <limits.h>	/* For LONG_MAX */
 #include <stdarg.h>	/* For va_start */
 #include <stddef.h>	/* for offsetof and ptrdiff_t */
 
-#ifdef	WIN32
+#ifdef	HAVE_ALLOCA_H
+#include <alloca.h>	/* For alloca(3) */
+#endif
+
+#ifdef	_WIN32
 
 #include <malloc.h>
-#include <stdint.h>
 #define	 snprintf	_snprintf
 #define	 vsnprintf	_vsnprintf
 
+/* To avoid linking with ws2_32.lib, here's the definition of ntohl() */
+#define sys_ntohl(l)	((((l) << 24)  & 0xff000000)	\
+			| (((l) << 8) & 0xff0000)	\
+			| (((l) >> 8)  & 0xff00)	\
+			| ((l >> 24) & 0xff))
+
 #ifdef _MSC_VER			/* MSVS.Net */
 #ifndef __cplusplus
 #define inline __inline
 #endif
+#ifndef	ASSUMESTDTYPES	/* Standard types have been defined elsewhere */
 #define	ssize_t		SSIZE_T
 typedef	char		int8_t;
 typedef	short		int16_t;
@@ -37,6 +53,7 @@ typedef	int		int32_t;
 typedef	unsigned char	uint8_t;
 typedef	unsigned short	uint16_t;
 typedef	unsigned int	uint32_t;
+#endif	/* ASSUMESTDTYPES */
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <float.h>
@@ -44,9 +61,11 @@ typedef	unsigned int	uint32_t;
 #define finite _finite
 #define copysign _copysign
 #define	ilogb	_logb
+#else	/* !_MSC_VER */
+#include <stdint.h>
 #endif	/* _MSC_VER */
 
-#else	/* !WIN32 */
+#else	/* !_WIN32 */
 
 #if defined(__vxworks)
 #include <types/vxTypes.h>
@@ -74,20 +93,34 @@ typedef	unsigned int	uint32_t;
 #endif	/* defined(sun) */
 #endif
 
+#include <netinet/in.h> /* for ntohl() */
+#define	sys_ntohl(foo)	ntohl(foo)
+
 #endif	/* defined(__vxworks) */
 
-#endif	/* WIN32 */
+#endif	/* _WIN32 */
 
 #if	__GNUC__ >= 3
 #ifndef	GCC_PRINTFLIKE
 #define	GCC_PRINTFLIKE(fmt,var)	__attribute__((format(printf,fmt,var)))
 #endif
+#ifndef	GCC_NOTUSED
+#define	GCC_NOTUSED		__attribute__((unused))
+#endif
 #else
 #ifndef	GCC_PRINTFLIKE
 #define	GCC_PRINTFLIKE(fmt,var)	/* nothing */
 #endif
+#ifndef	GCC_NOTUSED
+#define	GCC_NOTUSED
+#endif
 #endif
 
+/* Figure out if thread safety is requested */
+#if !defined(ASN_THREAD_SAFE) && (defined(THREAD_SAFE) || defined(_REENTRANT))
+#define	ASN_THREAD_SAFE
+#endif	/* Thread safety */
+
 #ifndef	offsetof	/* If not defined by <stddef.h> */
 #define	offsetof(s, m)	((ptrdiff_t)&(((s *)0)->m) - (ptrdiff_t)((s *)0))
 #endif	/* offsetof */
@@ -101,4 +134,4 @@ typedef	unsigned int	uint32_t;
 #endif /* __GNUC__ */
 #endif	/* MIN */
 
-#endif	/* _ASN_SYSTEM_H_ */
+#endif	/* ASN_SYSTEM_H */
diff --git a/libs/smux/include/stg/ber_decoder.h b/libs/smux/include/stg/ber_decoder.h
index 768133b6..9fe2e895 100644
--- a/libs/smux/include/stg/ber_decoder.h
+++ b/libs/smux/include/stg/ber_decoder.h
@@ -17,6 +17,7 @@ struct asn_codec_ctx_s;		/* Forward declaration */
 /*
  * The BER decoder of any type.
  * This function may be invoked directly from the application.
+ * The der_encode() function (der_encoder.h) is an opposite to ber_decode().
  */
 asn_dec_rval_t ber_decode(struct asn_codec_ctx_s *opt_codec_ctx,
 	struct asn_TYPE_descriptor_s *type_descriptor,
diff --git a/libs/smux/include/stg/constr_CHOICE.h b/libs/smux/include/stg/constr_CHOICE.h
index 83404e6d..e824a220 100644
--- a/libs/smux/include/stg/constr_CHOICE.h
+++ b/libs/smux/include/stg/constr_CHOICE.h
@@ -12,7 +12,7 @@
 extern "C" {
 #endif
 
-typedef struct asn_CHOICE_specifics_s {
+typedef const struct asn_CHOICE_specifics_s {
 	/*
 	 * Target structure description.
 	 */
@@ -24,7 +24,7 @@ typedef struct asn_CHOICE_specifics_s {
 	/*
 	 * Tags to members mapping table.
 	 */
-	asn_TYPE_tag2member_t *tag2el;
+	const asn_TYPE_tag2member_t *tag2el;
 	int tag2el_count;
 
 	/* Canonical ordering of CHOICE elements, for PER */
diff --git a/libs/smux/include/stg/constr_SEQUENCE.h b/libs/smux/include/stg/constr_SEQUENCE.h
index 5f589d5c..c2aeb667 100644
--- a/libs/smux/include/stg/constr_SEQUENCE.h
+++ b/libs/smux/include/stg/constr_SEQUENCE.h
@@ -11,7 +11,7 @@
 extern "C" {
 #endif
 
-typedef struct asn_SEQUENCE_specifics_s {
+typedef const struct asn_SEQUENCE_specifics_s {
 	/*
 	 * Target structure description.
 	 */
@@ -21,14 +21,14 @@ typedef struct asn_SEQUENCE_specifics_s {
 	/*
 	 * Tags to members mapping table (sorted).
 	 */
-	asn_TYPE_tag2member_t *tag2el;
+	const asn_TYPE_tag2member_t *tag2el;
 	int tag2el_count;
 
 	/*
 	 * Optional members of the extensions root (roms) or additions (aoms).
 	 * Meaningful for PER.
 	 */
-	int *oms;		/* Optional MemberS */
+	const int *oms;		/* Optional MemberS */
 	int  roms_count;	/* Root optional members count */
 	int  aoms_count;	/* Additions optional members count */
 
diff --git a/libs/smux/include/stg/constr_SET_OF.h b/libs/smux/include/stg/constr_SET_OF.h
index bcd09662..75e18cfa 100644
--- a/libs/smux/include/stg/constr_SET_OF.h
+++ b/libs/smux/include/stg/constr_SET_OF.h
@@ -11,7 +11,7 @@
 extern "C" {
 #endif
 
-typedef struct asn_SET_OF_specifics_s {
+typedef const struct asn_SET_OF_specifics_s {
 	/*
 	 * Target structure description.
 	 */
diff --git a/libs/smux/include/stg/constr_TYPE.h b/libs/smux/include/stg/constr_TYPE.h
index 95507c80..a9cd86dc 100644
--- a/libs/smux/include/stg/constr_TYPE.h
+++ b/libs/smux/include/stg/constr_TYPE.h
@@ -73,7 +73,7 @@ typedef int (asn_struct_print_f)(
  * Do not use it in your application.
  */
 typedef ber_tlv_tag_t (asn_outmost_tag_f)(
-		struct asn_TYPE_descriptor_s *type_descriptor,
+		const struct asn_TYPE_descriptor_s *type_descriptor,
 		const void *struct_ptr, int tag_mode, ber_tlv_tag_t tag);
 /* The instance of the above function type; used internally. */
 asn_outmost_tag_f asn_TYPE_outmost_tag;
@@ -83,8 +83,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. "" in some cases. */
-	char *xml_tag;	/* Name used in XML tag */
+	const char *name;	/* A name of the ASN.1 type. "" in some cases. */
+	const char *xml_tag;	/* Name used in XML tag */
 
 	/*
 	 * Generalized functions for dealing with the specific type.
@@ -108,10 +108,10 @@ typedef struct asn_TYPE_descriptor_s {
 	 * Tags that are expected to occur.
 	 */
 	asn_outmost_tag_f  *outmost_tag;	/* <optional, internal> */
-	ber_tlv_tag_t *tags;	/* Effective tags sequence for this type */
-	int tags_count;		/* Number of tags which are expected */
-	ber_tlv_tag_t *all_tags;/* Every tag for BER/containment */
-	int all_tags_count;	/* Number of tags */
+	const ber_tlv_tag_t *tags;	/* Effective tags sequence for this type */
+	int tags_count;			/* Number of tags which are expected */
+	const ber_tlv_tag_t *all_tags;	/* Every tag for BER/containment */
+	int all_tags_count;		/* Number of tags */
 
 	asn_per_constraints_t *per_constraints;	/* PER compiled constraints */
 
@@ -125,7 +125,7 @@ typedef struct asn_TYPE_descriptor_s {
 	 * Additional information describing the type, used by appropriate
 	 * functions above.
 	 */
-	void *specifics;
+	const void *specifics;
 } asn_TYPE_descriptor_t;
 
 /*
@@ -147,7 +147,7 @@ typedef struct asn_TYPE_member_s {
 	asn_constr_check_f *memb_constraints;	/* Constraints validator */
 	asn_per_constraints_t *per_constraints;	/* PER compiled constraints */
 	int (*default_value)(int setval, void **sptr);	/* DEFAULT <value> */
-	char *name;			/* ASN.1 identifier of the element */
+	const char *name;			/* ASN.1 identifier of the element */
 } asn_TYPE_member_t;
 
 /*
diff --git a/libs/smux/include/stg/constraints.h b/libs/smux/include/stg/constraints.h
index 5032345e..48d49e24 100644
--- a/libs/smux/include/stg/constraints.h
+++ b/libs/smux/include/stg/constraints.h
@@ -2,8 +2,8 @@
  * Copyright (c) 2004, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
-#ifndef	_ASN1_CONSTRAINTS_VALIDATOR_H_
-#define	_ASN1_CONSTRAINTS_VALIDATOR_H_
+#ifndef	ASN1_CONSTRAINTS_VALIDATOR_H
+#define	ASN1_CONSTRAINTS_VALIDATOR_H
 
 #include <asn_system.h>		/* Platform-dependent types */
 
@@ -54,10 +54,10 @@ asn_constr_check_f asn_generic_unknown_constraint; /* Not fully supported */
 /*
  * Invoke the callback with a complete error message.
  */
-#define	_ASN_CTFAIL	if(ctfailcb) ctfailcb
+#define	ASN__CTFAIL	if(ctfailcb) ctfailcb
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif	/* _ASN1_CONSTRAINTS_VALIDATOR_H_ */
+#endif	/* ASN1_CONSTRAINTS_VALIDATOR_H */
diff --git a/libs/smux/include/stg/der_encoder.h b/libs/smux/include/stg/der_encoder.h
index 4e2fb06c..61431c6d 100644
--- a/libs/smux/include/stg/der_encoder.h
+++ b/libs/smux/include/stg/der_encoder.h
@@ -15,6 +15,7 @@ struct asn_TYPE_descriptor_s;	/* Forward declaration */
 
 /*
  * The DER encoder of any type. May be invoked by the application.
+ * The ber_decode() function (ber_decoder.h) is an opposite of der_encode().
  */
 asn_enc_rval_t der_encode(struct asn_TYPE_descriptor_s *type_descriptor,
 		void *struct_ptr,	/* Structure to be encoded */
diff --git a/libs/smux/include/stg/per_decoder.h b/libs/smux/include/stg/per_decoder.h
index 26aaf594..8397a545 100644
--- a/libs/smux/include/stg/per_decoder.h
+++ b/libs/smux/include/stg/per_decoder.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2005 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2005, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #ifndef	_PER_DECODER_H_
@@ -14,8 +14,20 @@ extern "C" {
 
 struct asn_TYPE_descriptor_s;	/* Forward declaration */
 
+/*
+ * Unaligned PER decoder of a "complete encoding" as per X.691#10.1.
+ * On success, this call always returns (.consumed >= 1), as per X.691#10.1.3.
+ */
+asn_dec_rval_t uper_decode_complete(struct asn_codec_ctx_s *opt_codec_ctx,
+	struct asn_TYPE_descriptor_s *type_descriptor,	/* Type to decode */
+	void **struct_ptr,	/* Pointer to a target structure's pointer */
+	const void *buffer,	/* Data to be decoded */
+	size_t size		/* Size of data buffer */
+	);
+
 /*
  * Unaligned PER decoder of any ASN.1 type. May be invoked by the application.
+ * WARNING: This call returns the number of BITS read from the stream. Beware.
  */
 asn_dec_rval_t uper_decode(struct asn_codec_ctx_s *opt_codec_ctx,
 	struct asn_TYPE_descriptor_s *type_descriptor,	/* Type to decode */
diff --git a/libs/smux/include/stg/per_encoder.h b/libs/smux/include/stg/per_encoder.h
index 9ac130b7..95a6506e 100644
--- a/libs/smux/include/stg/per_encoder.h
+++ b/libs/smux/include/stg/per_encoder.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2006, 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #ifndef	_PER_ENCODER_H_
@@ -16,6 +16,9 @@ struct asn_TYPE_descriptor_s;	/* Forward declaration */
 
 /*
  * Unaligned PER encoder of any ASN.1 type. May be invoked by the application.
+ * WARNING: This function returns the number of encoded bits in the .encoded
+ * field of the return value. Use the following formula to convert to bytes:
+ * 	bytes = ((.encoded + 7) / 8)
  */
 asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor,
 	void *struct_ptr,	/* Structure to be encoded */
@@ -23,7 +26,11 @@ asn_enc_rval_t uper_encode(struct asn_TYPE_descriptor_s *type_descriptor,
 	void *app_key		/* Arbitrary callback argument */
 );
 
-/* A variant of uper_encode() which encodes data into the existing buffer */
+/*
+ * A variant of uper_encode() which encodes data into the existing buffer
+ * WARNING: This function returns the number of encoded bits in the .encoded
+ * field of the return value.
+ */
 asn_enc_rval_t uper_encode_to_buffer(
 	struct asn_TYPE_descriptor_s *type_descriptor,
 	void *struct_ptr,	/* Structure to be encoded */
@@ -31,6 +38,19 @@ asn_enc_rval_t uper_encode_to_buffer(
 	size_t buffer_size	/* Initial buffer size (max) */
 );
 
+/*
+ * A variant of uper_encode_to_buffer() which allocates buffer itself.
+ * Returns the number of bytes in the buffer or -1 in case of failure.
+ * WARNING: This function produces a "Production of the complete encoding",
+ * with length of at least one octet. Contrast this to precise bit-packing
+ * encoding of uper_encode() and uper_encode_to_buffer().
+ */
+ssize_t uper_encode_to_new_buffer(
+	struct asn_TYPE_descriptor_s *type_descriptor,
+	asn_per_constraints_t *constraints,
+	void *struct_ptr,	/* Structure to be encoded */
+	void **buffer_r		/* Buffer allocated and returned */
+);
 
 /*
  * Type of the generic PER encoder function.
diff --git a/libs/smux/include/stg/per_opentype.h b/libs/smux/include/stg/per_opentype.h
new file mode 100644
index 00000000..facfaa63
--- /dev/null
+++ b/libs/smux/include/stg/per_opentype.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef	_PER_OPENTYPE_H_
+#define	_PER_OPENTYPE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+asn_dec_rval_t uper_open_type_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd);
+
+int uper_open_type_skip(asn_codec_ctx_t *opt_codec_ctx, asn_per_data_t *pd);
+
+int uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _PER_OPENTYPE_H_ */
diff --git a/libs/smux/include/stg/per_support.h b/libs/smux/include/stg/per_support.h
index 420bb83c..a75ac94f 100644
--- a/libs/smux/include/stg/per_support.h
+++ b/libs/smux/include/stg/per_support.h
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2005-2014 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #ifndef	_PER_SUPPORT_H_
@@ -14,7 +15,7 @@ extern "C" {
 /*
  * Pre-computed PER constraints.
  */
-typedef struct asn_per_constraint_s {
+typedef const struct asn_per_constraint_s {
 	enum asn_per_constraint_flags {
 		APC_UNCONSTRAINED	= 0x0,	/* No PER visible constraints */
 		APC_SEMI_CONSTRAINED	= 0x1,	/* Constrained at "lb" */
@@ -26,18 +27,23 @@ typedef struct asn_per_constraint_s {
 	long lower_bound;		/* "lb" value */
 	long upper_bound;		/* "ub" value */
 } asn_per_constraint_t;
-typedef struct asn_per_constraints_s {
-	asn_per_constraint_t value;
-	asn_per_constraint_t size;
+typedef const struct asn_per_constraints_s {
+	struct asn_per_constraint_s value;
+	struct asn_per_constraint_s size;
+	int (*value2code)(unsigned int value);
+	int (*code2value)(unsigned int code);
 } asn_per_constraints_t;
 
 /*
  * This structure describes a position inside an incoming PER bit stream.
  */
 typedef struct asn_per_data_s {
- const uint8_t *buffer;	/* Pointer to the octet stream */
-        size_t  nboff;	/* Bit offset to the meaningful bit */
-        size_t  nbits;	/* Number of bits in the stream */
+  const uint8_t *buffer;  /* Pointer to the octet stream */
+         size_t  nboff;   /* Bit offset to the meaningful bit */
+         size_t  nbits;   /* Number of bits in the stream */
+         size_t  moved;   /* Number of bits moved through this bit stream */
+  int (*refill)(struct asn_per_data_s *);
+  void *refill_key;
 } asn_per_data_t;
 
 /*
@@ -47,6 +53,9 @@ typedef struct asn_per_data_s {
  */
 int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);
 
+/* Undo the immediately preceeding "get_few_bits" operation */
+void per_get_undo(asn_per_data_t *per_data, int get_nbits);
+
 /*
  * Extract a large number of bits from the specified PER data pointer.
  * This function returns -1 if the specified number of bits could not be
@@ -62,11 +71,22 @@ ssize_t uper_get_length(asn_per_data_t *pd,
 			int effective_bound_bits,
 			int *repeat);
 
+/*
+ * Get the normally small length "n".
+ */
+ssize_t uper_get_nslength(asn_per_data_t *pd);
+
 /*
  * Get the normally small non-negative whole number.
  */
 ssize_t uper_get_nsnnwn(asn_per_data_t *pd);
 
+/* X.691-2008/11, #11.5.6 */
+int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *v, int nbits);
+
+/* Non-thread-safe debugging function, don't use it */
+char *per_data_string(asn_per_data_t *pd);
+
 /*
  * This structure supports forming PER output.
  */
@@ -86,6 +106,10 @@ int per_put_few_bits(asn_per_outp_t *per_data, uint32_t bits, int obits);
 /* Output a large number of bits */
 int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
 
+/* X.691-2008/11, #11.5 */
+int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits);
+int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int nbits);
+
 /*
  * Put the length "n" to the Unaligned PER stream.
  * This function returns the number of units which may be flushed
@@ -93,6 +117,12 @@ int per_put_many_bits(asn_per_outp_t *po, const uint8_t *src, int put_nbits);
  */
 ssize_t uper_put_length(asn_per_outp_t *po, size_t whole_length);
 
+/*
+ * Put the normally small length "n" to the Unaligned PER stream.
+ * Returns 0 or -1.
+ */
+int uper_put_nslength(asn_per_outp_t *po, size_t length);
+
 /*
  * Put the normally small non-negative whole number.
  */
diff --git a/libs/smux/include/stg/xer_decoder.h b/libs/smux/include/stg/xer_decoder.h
index cf0d846f..301b613c 100644
--- a/libs/smux/include/stg/xer_decoder.h
+++ b/libs/smux/include/stg/xer_decoder.h
@@ -60,11 +60,12 @@ asn_dec_rval_t xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
  * 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.
+ * the return value is >= 0.
  */
   typedef enum pxer_chunk_type {
-	PXER_TAG,	/* Complete XER tag */
-	PXER_TEXT,	/* Plain text between XER tags */
+	PXER_WMORE,     /* Chunk type is not clear, more data expected. */
+	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,
@@ -87,12 +88,11 @@ xer_check_tag_e xer_check_tag(const void *buf_ptr, int size,
 		const char *need_tag);
 
 /*
- * Check whether this buffer consists of entirely XER whitespace characters.
+ * Get the number of bytes consisting entirely of XER whitespace characters.
  * RETURN VALUES:
- * 1:	Whitespace or empty string
- * 0:	Non-whitespace
+ * >=0:	Number of whitespace characters in the string.
  */
-int xer_is_whitespace(const void *chunk_buf, size_t chunk_size);
+size_t xer_whitespace_span(const void *chunk_buf, size_t chunk_size);
 
 /*
  * Skip the series of anticipated extensions.
diff --git a/libs/smux/per_decoder.c b/libs/smux/per_decoder.c
index 16dee369..461b7262 100644
--- a/libs/smux/per_decoder.c
+++ b/libs/smux/per_decoder.c
@@ -2,6 +2,40 @@
 #include <asn_internal.h>
 #include <per_decoder.h>
 
+/*
+ * Decode a "Production of a complete encoding", X.691#10.1.
+ * The complete encoding contains at least one byte, and is an integral
+ * multiple of 8 bytes.
+ */
+asn_dec_rval_t
+uper_decode_complete(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size) {
+	asn_dec_rval_t rval;
+
+	rval = uper_decode(opt_codec_ctx, td, sptr, buffer, size, 0, 0);
+	if(rval.consumed) {
+		/*
+		 * We've always given 8-aligned data,
+		 * so convert bits to integral bytes.
+		 */
+		rval.consumed += 7;
+		rval.consumed >>= 3;
+	} else if(rval.code == RC_OK) {
+		if(size) {
+			if(((const uint8_t *)buffer)[0] == 0) {
+				rval.consumed = 1;	/* 1 byte */
+			} else {
+				ASN_DEBUG("Expecting single zeroed byte");
+				rval.code = RC_FAIL;
+			}
+		} else {
+			/* Must contain at least 8 bits. */
+			rval.code = RC_WMORE;
+		}
+	}
+
+	return rval;
+}
+
 asn_dec_rval_t
 uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sptr, const void *buffer, size_t size, int skip_bits, int unused_bits) {
 	asn_codec_ctx_t s_codec_ctx;
@@ -11,7 +45,7 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
 	if(skip_bits < 0 || skip_bits > 7
 	|| unused_bits < 0 || unused_bits > 7
 	|| (unused_bits > 0 && !size))
-		_ASN_DECODE_FAILED;
+		ASN__DECODE_FAILED;
 
 	/*
 	 * Stack checker requires that the codec context
@@ -25,27 +59,31 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
 	} else {
 		/* If context is not given, be security-conscious anyway */
 		memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
-		s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
+		s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
 		opt_codec_ctx = &s_codec_ctx;
 	}
 
 	/* Fill in the position indicator */
+	memset(&pd, 0, sizeof(pd));
 	pd.buffer = (const uint8_t *)buffer;
 	pd.nboff = skip_bits;
 	pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
 	if(pd.nboff > pd.nbits)
-		_ASN_DECODE_FAILED;
+		ASN__DECODE_FAILED;
 
 	/*
 	 * Invoke type-specific decoder.
 	 */
 	if(!td->uper_decoder)
-		_ASN_DECODE_FAILED;	/* PER is not compiled in */
+		ASN__DECODE_FAILED;	/* PER is not compiled in */
 	rval = td->uper_decoder(opt_codec_ctx, td, 0, sptr, &pd);
 	if(rval.code == RC_OK) {
 		/* Return the number of consumed bits */
 		rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
 					+ pd.nboff - skip_bits;
+		ASN_DEBUG("PER decoding consumed %ld, counted %ld",
+			(long)rval.consumed, (long)pd.moved);
+		assert(rval.consumed == pd.moved);
 	} else {
 		/* PER codec is not a restartable */
 		rval.consumed = 0;
diff --git a/libs/smux/per_encoder.c b/libs/smux/per_encoder.c
index 614dd233..47f3c916 100644
--- a/libs/smux/per_encoder.c
+++ b/libs/smux/per_encoder.c
@@ -2,41 +2,11 @@
 #include <asn_internal.h>
 #include <per_encoder.h>
 
-/* Flush partially filled buffer */
-static int _uper_encode_flush_outp(asn_per_outp_t *po);
+static asn_enc_rval_t uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *, void *sptr, asn_app_consume_bytes_f *cb, void *app_key);
 
 asn_enc_rval_t
 uper_encode(asn_TYPE_descriptor_t *td, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
-	asn_per_outp_t po;
-	asn_enc_rval_t er;
-
-	/*
-	 * Invoke type-specific encoder.
-	 */
-	if(!td || !td->uper_encoder)
-		_ASN_ENCODE_FAILED;	/* PER is not compiled in */
-
-	po.buffer = po.tmpspace;
-	po.nboff = 0;
-	po.nbits = 8 * sizeof(po.tmpspace);
-	po.outper = cb;
-	po.op_key = app_key;
-	po.flushed_bytes = 0;
-
-	er = td->uper_encoder(td, 0, sptr, &po);
-	if(er.encoded != -1) {
-		size_t bits_to_flush;
-
-		bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
-
-		/* Set number of bits encoded to a firm value */
-		er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
-
-		if(_uper_encode_flush_outp(&po))
-			_ASN_ENCODE_FAILED;
-	}
-
-	return er;
+	return uper_encode_internal(td, 0, sptr, cb, app_key);
 }
 
 /*
@@ -63,20 +33,71 @@ asn_enc_rval_t
 uper_encode_to_buffer(asn_TYPE_descriptor_t *td, void *sptr, void *buffer, size_t buffer_size) {
 	enc_to_buf_arg key;
 
-	/*
-	 * Invoke type-specific encoder.
-	 */
-	if(!td || !td->uper_encoder)
-		_ASN_ENCODE_FAILED;	/* PER is not compiled in */
-
 	key.buffer = buffer;
 	key.left = buffer_size;
 
-	ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
+	if(td) ASN_DEBUG("Encoding \"%s\" using UNALIGNED PER", td->name);
 
-	return uper_encode(td, sptr, encode_to_buffer_cb, &key);
+	return uper_encode_internal(td, 0, sptr, encode_to_buffer_cb, &key);
+}
+
+typedef struct enc_dyn_arg {
+	void *buffer;
+	size_t length;
+	size_t allocated;
+} enc_dyn_arg;
+static int
+encode_dyn_cb(const void *buffer, size_t size, void *key) {
+	enc_dyn_arg *arg = key;
+	if(arg->length + size >= arg->allocated) {
+		void *p;
+		arg->allocated = arg->allocated ? (arg->allocated << 2) : size;
+		p = REALLOC(arg->buffer, arg->allocated);
+		if(!p) {
+			FREEMEM(arg->buffer);
+			memset(arg, 0, sizeof(*arg));
+			return -1;
+		}
+		arg->buffer = p;
+	}
+	memcpy(((char *)arg->buffer) + arg->length, buffer, size);
+	arg->length += size;
+	return 0;
 }
+ssize_t
+uper_encode_to_new_buffer(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, void **buffer_r) {
+	asn_enc_rval_t er;
+	enc_dyn_arg key;
+
+	memset(&key, 0, sizeof(key));
+
+	er = uper_encode_internal(td, constraints, sptr, encode_dyn_cb, &key);
+	switch(er.encoded) {
+	case -1:
+		FREEMEM(key.buffer);
+		return -1;
+	case 0:
+		FREEMEM(key.buffer);
+		key.buffer = MALLOC(1);
+		if(key.buffer) {
+			*(char *)key.buffer = '\0';
+			*buffer_r = key.buffer;
+			return 1;
+		} else {
+			return -1;
+		}
+	default:
+		*buffer_r = key.buffer;
+		ASN_DEBUG("Complete encoded in %ld bits", (long)er.encoded);
+		return ((er.encoded + 7) >> 3);
+	}
+}
+
+/*
+ * Internally useful functions.
+ */
 
+/* Flush partially filled buffer */
 static int
 _uper_encode_flush_outp(asn_per_outp_t *po) {
 	uint8_t *buf;
@@ -93,3 +114,38 @@ _uper_encode_flush_outp(asn_per_outp_t *po) {
 
 	return po->outper(po->tmpspace, buf - po->tmpspace, po->op_key);
 }
+
+static asn_enc_rval_t
+uper_encode_internal(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_app_consume_bytes_f *cb, void *app_key) {
+	asn_per_outp_t po;
+	asn_enc_rval_t er;
+
+	/*
+	 * Invoke type-specific encoder.
+	 */
+	if(!td || !td->uper_encoder)
+		ASN__ENCODE_FAILED;	/* PER is not compiled in */
+
+	po.buffer = po.tmpspace;
+	po.nboff = 0;
+	po.nbits = 8 * sizeof(po.tmpspace);
+	po.outper = cb;
+	po.op_key = app_key;
+	po.flushed_bytes = 0;
+
+	er = td->uper_encoder(td, constraints, sptr, &po);
+	if(er.encoded != -1) {
+		size_t bits_to_flush;
+
+		bits_to_flush = ((po.buffer - po.tmpspace) << 3) + po.nboff;
+
+		/* Set number of bits encoded to a firm value */
+		er.encoded = (po.flushed_bytes << 3) + bits_to_flush;
+
+		if(_uper_encode_flush_outp(&po))
+			ASN__ENCODE_FAILED;
+	}
+
+	return er;
+}
+
diff --git a/libs/smux/per_opentype.c b/libs/smux/per_opentype.c
new file mode 100644
index 00000000..404aa726
--- /dev/null
+++ b/libs/smux/per_opentype.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2007 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#include <asn_internal.h>
+#include <per_support.h>
+#include <constr_TYPE.h>
+#include <per_opentype.h>
+
+typedef struct uper_ugot_key {
+	asn_per_data_t oldpd;	/* Old per data source */
+	size_t unclaimed;
+	size_t ot_moved;	/* Number of bits moved by OT processing */
+	int repeat;
+} uper_ugot_key;
+
+static int uper_ugot_refill(asn_per_data_t *pd);
+static int per_skip_bits(asn_per_data_t *pd, int skip_nbits);
+static asn_dec_rval_t uper_sot_suck(asn_codec_ctx_t *, asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd);
+
+/*
+ * Encode an "open type field".
+ * #10.1, #10.2
+ */
+int
+uper_open_type_put(asn_TYPE_descriptor_t *td, asn_per_constraints_t *constraints, void *sptr, asn_per_outp_t *po) {
+	void *buf;
+	void *bptr;
+	ssize_t size;
+	size_t toGo;
+
+	ASN_DEBUG("Open type put %s ...", td->name);
+
+	size = uper_encode_to_new_buffer(td, constraints, sptr, &buf);
+	if(size <= 0) return -1;
+
+	for(bptr = buf, toGo = size; toGo;) {
+		ssize_t maySave = uper_put_length(po, toGo);
+		ASN_DEBUG("Prepending length %d to %s and allowing to save %d",
+			(int)size, td->name, (int)maySave);
+		if(maySave < 0) break;
+		if(per_put_many_bits(po, bptr, maySave * 8)) break;
+		bptr = (char *)bptr + maySave;
+		toGo -= maySave;
+	}
+
+	FREEMEM(buf);
+	if(toGo) return -1;
+
+	ASN_DEBUG("Open type put %s of length %ld + overhead (1byte?)",
+		td->name, (long)size);
+
+	return 0;
+}
+
+static asn_dec_rval_t
+uper_open_type_get_simple(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
+	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+	asn_dec_rval_t rv;
+	ssize_t chunk_bytes;
+	int repeat;
+	uint8_t *buf = 0;
+	size_t bufLen = 0;
+	size_t bufSize = 0;
+	asn_per_data_t spd;
+	size_t padding;
+
+	ASN__STACK_OVERFLOW_CHECK(ctx);
+
+	ASN_DEBUG("Getting open type %s...", td->name);
+
+	do {
+		chunk_bytes = uper_get_length(pd, -1, &repeat);
+		if(chunk_bytes < 0) {
+			FREEMEM(buf);
+			ASN__DECODE_STARVED;
+		}
+		if(bufLen + chunk_bytes > bufSize) {
+			void *ptr;
+			bufSize = chunk_bytes + (bufSize << 2);
+			ptr = REALLOC(buf, bufSize);
+			if(!ptr) {
+				FREEMEM(buf);
+				ASN__DECODE_FAILED;
+			}
+			buf = ptr;
+		}
+		if(per_get_many_bits(pd, buf + bufLen, 0, chunk_bytes << 3)) {
+			FREEMEM(buf);
+			ASN__DECODE_STARVED;
+		}
+		bufLen += chunk_bytes;
+	} while(repeat);
+
+	ASN_DEBUG("Getting open type %s encoded in %ld bytes", td->name,
+		(long)bufLen);
+
+	memset(&spd, 0, sizeof(spd));
+	spd.buffer = buf;
+	spd.nbits = bufLen << 3;
+
+	ASN_DEBUG_INDENT_ADD(+4);
+	rv = td->uper_decoder(ctx, td, constraints, sptr, &spd);
+	ASN_DEBUG_INDENT_ADD(-4);
+
+	if(rv.code == RC_OK) {
+		/* Check padding validity */
+		padding = spd.nbits - spd.nboff;
+                if ((padding < 8 ||
+		/* X.691#10.1.3 */
+		(spd.nboff == 0 && spd.nbits == 8 && spd.buffer == buf)) &&
+                    per_get_few_bits(&spd, padding) == 0) {
+			/* Everything is cool */
+			FREEMEM(buf);
+			return rv;
+		}
+		FREEMEM(buf);
+		if(padding >= 8) {
+			ASN_DEBUG("Too large padding %d in open type", (int)padding);
+			ASN__DECODE_FAILED;
+		} else {
+			ASN_DEBUG("Non-zero padding");
+			ASN__DECODE_FAILED;
+		}
+	} else {
+		FREEMEM(buf);
+		/* rv.code could be RC_WMORE, nonsense in this context */
+		rv.code = RC_FAIL; /* Noone would give us more */
+	}
+
+	return rv;
+}
+
+static asn_dec_rval_t GCC_NOTUSED
+uper_open_type_get_complex(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
+	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+	uper_ugot_key arg;
+	asn_dec_rval_t rv;
+	ssize_t padding;
+
+	ASN__STACK_OVERFLOW_CHECK(ctx);
+
+	ASN_DEBUG("Getting open type %s from %s", td->name,
+		per_data_string(pd));
+	arg.oldpd = *pd;
+	arg.unclaimed = 0;
+	arg.ot_moved = 0;
+	arg.repeat = 1;
+	pd->refill = uper_ugot_refill;
+	pd->refill_key = &arg;
+	pd->nbits = pd->nboff;	/* 0 good bits at this point, will refill */
+	pd->moved = 0;	/* This now counts the open type size in bits */
+
+	ASN_DEBUG_INDENT_ADD(+4);
+	rv = td->uper_decoder(ctx, td, constraints, sptr, pd);
+	ASN_DEBUG_INDENT_ADD(-4);
+
+#define	UPDRESTOREPD	do {						\
+	/* buffer and nboff are valid, preserve them. */		\
+	pd->nbits = arg.oldpd.nbits - (pd->moved - arg.ot_moved);	\
+	pd->moved = arg.oldpd.moved + (pd->moved - arg.ot_moved);	\
+	pd->refill = arg.oldpd.refill;					\
+	pd->refill_key = arg.oldpd.refill_key;				\
+  } while(0)
+
+	if(rv.code != RC_OK) {
+		UPDRESTOREPD;
+		return rv;
+	}
+
+	ASN_DEBUG("OpenType %s pd%s old%s unclaimed=%d, repeat=%d", td->name,
+		per_data_string(pd),
+		per_data_string(&arg.oldpd),
+		(int)arg.unclaimed, (int)arg.repeat);
+
+	padding = pd->moved % 8;
+	if(padding) {
+		int32_t pvalue;
+		if(padding > 7) {
+			ASN_DEBUG("Too large padding %d in open type",
+				(int)padding);
+			rv.code = RC_FAIL;
+			UPDRESTOREPD;
+			return rv;
+		}
+		padding = 8 - padding;
+		ASN_DEBUG("Getting padding of %d bits", (int)padding);
+		pvalue = per_get_few_bits(pd, padding);
+		switch(pvalue) {
+		case -1:
+			ASN_DEBUG("Padding skip failed");
+			UPDRESTOREPD;
+			ASN__DECODE_STARVED;
+		case 0: break;
+		default:
+			ASN_DEBUG("Non-blank padding (%d bits 0x%02x)",
+				(int)padding, (int)pvalue);
+			UPDRESTOREPD;
+			ASN__DECODE_FAILED;
+		}
+	}
+	if(pd->nboff != pd->nbits) {
+		ASN_DEBUG("Open type %s overhead pd%s old%s", td->name,
+			per_data_string(pd), per_data_string(&arg.oldpd));
+		if(1) {
+			UPDRESTOREPD;
+			ASN__DECODE_FAILED;
+		} else {
+			arg.unclaimed += pd->nbits - pd->nboff;
+		}
+	}
+
+	/* Adjust pd back so it points to original data */
+	UPDRESTOREPD;
+
+	/* Skip data not consumed by the decoder */
+	if(arg.unclaimed) {
+		ASN_DEBUG("Getting unclaimed %d", (int)arg.unclaimed);
+		switch(per_skip_bits(pd, arg.unclaimed)) {
+		case -1:
+			ASN_DEBUG("Claim of %d failed", (int)arg.unclaimed);
+			ASN__DECODE_STARVED;
+		case 0:
+			ASN_DEBUG("Got claim of %d", (int)arg.unclaimed);
+			break;
+		default:
+			/* Padding must be blank */
+			ASN_DEBUG("Non-blank unconsumed padding");
+			ASN__DECODE_FAILED;
+		}
+		arg.unclaimed = 0;
+	}
+
+	if(arg.repeat) {
+		ASN_DEBUG("Not consumed the whole thing");
+		rv.code = RC_FAIL;
+		return rv;
+	}
+
+	return rv;
+}
+
+
+asn_dec_rval_t
+uper_open_type_get(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
+	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+
+	return uper_open_type_get_simple(ctx, td, constraints, sptr, pd);
+}
+
+int
+uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
+	asn_TYPE_descriptor_t s_td;
+	asn_dec_rval_t rv;
+
+	s_td.name = "<unknown extension>";
+	s_td.uper_decoder = uper_sot_suck;
+
+	rv = uper_open_type_get(ctx, &s_td, 0, 0, pd);
+	if(rv.code != RC_OK)
+		return -1;
+	else
+		return 0;
+}
+
+/*
+ * Internal functions.
+ */
+
+static asn_dec_rval_t
+uper_sot_suck(asn_codec_ctx_t *ctx, asn_TYPE_descriptor_t *td,
+	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
+	asn_dec_rval_t rv;
+
+	(void)ctx;
+	(void)td;
+	(void)constraints;
+	(void)sptr;
+
+	while(per_get_few_bits(pd, 24) >= 0);
+
+	rv.code = RC_OK;
+	rv.consumed = pd->moved;
+
+	return rv;
+}
+
+static int
+uper_ugot_refill(asn_per_data_t *pd) {
+	uper_ugot_key *arg = pd->refill_key;
+	ssize_t next_chunk_bytes, next_chunk_bits;
+	ssize_t avail;
+
+	asn_per_data_t *oldpd = &arg->oldpd;
+
+	ASN_DEBUG("REFILLING pd->moved=%ld, oldpd->moved=%ld",
+		(long)pd->moved, (long)oldpd->moved);
+
+	/* Advance our position to where pd is */
+	oldpd->buffer = pd->buffer;
+	oldpd->nboff  = pd->nboff;
+	oldpd->nbits -= pd->moved - arg->ot_moved;
+	oldpd->moved += pd->moved - arg->ot_moved;
+	arg->ot_moved = pd->moved;
+
+	if(arg->unclaimed) {
+		/* Refill the container */
+		if(per_get_few_bits(oldpd, 1))
+			return -1;
+		if(oldpd->nboff == 0) {
+			assert(0);
+			return -1;
+		}
+		pd->buffer = oldpd->buffer;
+		pd->nboff = oldpd->nboff - 1;
+		pd->nbits = oldpd->nbits;
+		ASN_DEBUG("UNCLAIMED <- return from (pd->moved=%ld)",
+			(long)pd->moved);
+		return 0;
+	}
+
+	if(!arg->repeat) {
+		ASN_DEBUG("Want more but refill doesn't have it");
+		return -1;
+	}
+
+	next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat);
+	ASN_DEBUG("Open type LENGTH %ld bytes at off %ld, repeat %ld",
+		(long)next_chunk_bytes, (long)oldpd->moved, (long)arg->repeat);
+	if(next_chunk_bytes < 0) return -1;
+	if(next_chunk_bytes == 0) {
+		pd->refill = 0;	/* No more refills, naturally */
+		assert(!arg->repeat);	/* Implementation guarantee */
+	}
+	next_chunk_bits = next_chunk_bytes << 3;
+	avail = oldpd->nbits - oldpd->nboff;
+	if(avail >= next_chunk_bits) {
+		pd->nbits = oldpd->nboff + next_chunk_bits;
+		arg->unclaimed = 0;
+		ASN_DEBUG("!+Parent frame %ld bits, alloting %ld [%ld..%ld] (%ld)",
+			(long)next_chunk_bits, (long)oldpd->moved,
+			(long)oldpd->nboff, (long)oldpd->nbits,
+			(long)(oldpd->nbits - oldpd->nboff));
+	} else {
+		pd->nbits = oldpd->nbits;
+		arg->unclaimed = next_chunk_bits - avail;
+		ASN_DEBUG("!-Parent frame %ld, require %ld, will claim %ld",
+			(long)avail, (long)next_chunk_bits,
+			(long)arg->unclaimed);
+	}
+	pd->buffer = oldpd->buffer;
+	pd->nboff = oldpd->nboff;
+	ASN_DEBUG("Refilled pd%s old%s",
+		per_data_string(pd), per_data_string(oldpd));
+	return 0;
+}
+
+static int
+per_skip_bits(asn_per_data_t *pd, int skip_nbits) {
+	int hasNonZeroBits = 0;
+	while(skip_nbits > 0) {
+		int skip;
+
+		/* per_get_few_bits() is more efficient when nbits <= 24 */
+		if(skip_nbits < 24)
+			skip = skip_nbits;
+		else
+			skip = 24;
+		skip_nbits -= skip;
+
+		switch(per_get_few_bits(pd, skip)) {
+		case -1: return -1;	/* Starving */
+		case 0: continue;	/* Skipped empty space */
+		default: hasNonZeroBits = 1; continue;
+		}
+	}
+	return hasNonZeroBits;
+}
diff --git a/libs/smux/per_support.c b/libs/smux/per_support.c
index c8344193..14b4c4c7 100644
--- a/libs/smux/per_support.c
+++ b/libs/smux/per_support.c
@@ -1,25 +1,67 @@
 /*
- * Copyright (c) 2005, 2006 Lev Walkin <vlm@lionet.info>. All rights reserved.
+ * Copyright (c) 2005-2014 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #include <asn_system.h>
 #include <asn_internal.h>
 #include <per_support.h>
 
+char *
+per_data_string(asn_per_data_t *pd) {
+	static char buf[2][32];
+	static int n;
+	n = (n+1) % 2;
+	snprintf(buf[n], sizeof(buf[n]),
+		"{m=%ld span %+ld[%d..%d] (%d)}",
+		(long)pd->moved,
+		(((long)pd->buffer) & 0xf),
+		(int)pd->nboff, (int)pd->nbits,
+		(int)(pd->nbits - pd->nboff));
+	return buf[n];
+}
+
+void
+per_get_undo(asn_per_data_t *pd, int nbits) {
+	if((ssize_t)pd->nboff < nbits) {
+		assert((ssize_t)pd->nboff < nbits);
+	} else {
+		pd->nboff -= nbits;
+		pd->moved -= nbits;
+	}
+}
+
 /*
  * Extract a small number of bits (<= 31) from the specified PER data pointer.
  */
 int32_t
 per_get_few_bits(asn_per_data_t *pd, int nbits) {
 	size_t off;	/* Next after last bit offset */
+	ssize_t nleft;	/* Number of bits left in this stream */
 	uint32_t accum;
 	const uint8_t *buf;
 
-	if(nbits < 0 || pd->nboff + nbits > pd->nbits)
+	if(nbits < 0)
 		return -1;
 
-	ASN_DEBUG("[PER get %d bits from %p+%d bits]",
-		nbits, pd->buffer, pd->nboff);
+	nleft = pd->nbits - pd->nboff;
+	if(nbits > nleft) {
+		int32_t tailv, vhead;
+		if(!pd->refill || nbits > 31) return -1;
+		/* Accumulate unused bytes before refill */
+		ASN_DEBUG("Obtain the rest %d bits (want %d)",
+			(int)nleft, (int)nbits);
+		tailv = per_get_few_bits(pd, nleft);
+		if(tailv < 0) return -1;
+		/* Refill (replace pd contents with new data) */
+		if(pd->refill(pd))
+			return -1;
+		nbits -= nleft;
+		vhead = per_get_few_bits(pd, nbits);
+		/* Combine the rest of previous pd with the head of new one */
+		tailv = (tailv << nbits) | vhead;  /* Could == -1 */
+		return tailv;
+	}
 
 	/*
 	 * Normalize position indicator.
@@ -29,7 +71,9 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
 		pd->nbits  -= (pd->nboff & ~0x07);
 		pd->nboff  &= 0x07;
 	}
-	off = (pd->nboff += nbits);
+	pd->moved += nbits;
+	pd->nboff += nbits;
+	off = pd->nboff;
 	buf = pd->buffer;
 
 	/*
@@ -47,15 +91,29 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
 	else if(nbits <= 31) {
 		asn_per_data_t tpd = *pd;
 		/* Here are we with our 31-bits limit plus 1..7 bits offset. */
-		tpd.nboff -= nbits;
+		per_get_undo(&tpd, nbits);
+		/* The number of available bits in the stream allow
+		 * for the following operations to take place without
+		 * invoking the ->refill() function */
 		accum  = per_get_few_bits(&tpd, nbits - 24) << 24;
 		accum |= per_get_few_bits(&tpd, 24);
 	} else {
-		pd->nboff -= nbits;	/* Oops, revert back */
+		per_get_undo(pd, nbits);
 		return -1;
 	}
 
-	return (accum & (((uint32_t)1 << nbits) - 1));
+	accum &= (((uint32_t)1 << nbits) - 1);
+
+	ASN_DEBUG("  [PER got %2d<=%2d bits => span %d %+ld[%d..%d]:%02x (%d) => 0x%x]",
+		(int)nbits, (int)nleft,
+		(int)pd->moved,
+		(((long)pd->buffer) & 0xf),
+		(int)pd->nboff, (int)pd->nbits,
+		((pd->buffer != NULL)?pd->buffer[0]:0),
+		(int)(pd->nbits - pd->nboff),
+		(int)accum);
+
+	return accum;
 }
 
 /*
@@ -129,6 +187,30 @@ uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
 	return (16384 * value);
 }
 
+/*
+ * Get the normally small length "n".
+ * This procedure used to decode length of extensions bit-maps
+ * for SET and SEQUENCE types.
+ */
+ssize_t
+uper_get_nslength(asn_per_data_t *pd) {
+	ssize_t length;
+
+	ASN_DEBUG("Getting normally small length");
+
+	if(per_get_few_bits(pd, 1) == 0) {
+		length = per_get_few_bits(pd, 6) + 1;
+		if(length <= 0) return -1;
+		ASN_DEBUG("l=%d", (int)length);
+		return length;
+	} else {
+		int repeat;
+		length = uper_get_length(pd, -1, &repeat);
+		if(length >= 0 && !repeat) return length;
+		return -1; /* Error, or do not support >16K extensions */
+	}
+}
+
 /*
  * Get the normally small non-negative whole number.
  * X.691, #10.6
@@ -156,8 +238,8 @@ uper_get_nsnnwn(asn_per_data_t *pd) {
 }
 
 /*
- * Put the normally small non-negative whole number.
- * X.691, #10.6
+ * X.691-11/2008, #11.6
+ * Encoding of a normally small non-negative whole number
  */
 int
 uper_put_nsnnwn(asn_per_outp_t *po, int n) {
@@ -182,6 +264,58 @@ uper_put_nsnnwn(asn_per_outp_t *po, int n) {
 }
 
 
+/* X.691-2008/11, #11.5.6 -> #11.3 */
+int uper_get_constrained_whole_number(asn_per_data_t *pd, unsigned long *out_value, int nbits) {
+	unsigned long lhalf;    /* Lower half of the number*/
+	long half;
+
+	if(nbits <= 31) {
+		half = per_get_few_bits(pd, nbits);
+		if(half < 0) return -1;
+		*out_value = half;
+		return 0;
+	}
+
+	if((size_t)nbits > 8 * sizeof(*out_value))
+		return -1;  /* RANGE */
+
+	half = per_get_few_bits(pd, 31);
+	if(half < 0) return -1;
+
+	if(uper_get_constrained_whole_number(pd, &lhalf, nbits - 31))
+		return -1;
+
+	*out_value = ((unsigned long)half << (nbits - 31)) | lhalf;
+	return 0;
+}
+
+
+/* X.691-2008/11, #11.5.6 -> #11.3 */
+int uper_put_constrained_whole_number_s(asn_per_outp_t *po, long v, int nbits) {
+	/*
+	 * Assume signed number can be safely coerced into
+	 * unsigned of the same range.
+	 * The following testing code will likely be optimized out
+	 * by compiler if it is true.
+	 */
+	unsigned long uvalue1 = ULONG_MAX;
+	         long svalue  = uvalue1;
+	unsigned long uvalue2 = svalue;
+	assert(uvalue1 == uvalue2);
+	return uper_put_constrained_whole_number_u(po, v, nbits);
+}
+
+int uper_put_constrained_whole_number_u(asn_per_outp_t *po, unsigned long v, int nbits) {
+	if(nbits <= 31) {
+		return per_put_few_bits(po, v, nbits);
+	} else {
+		/* Put higher portion first, followed by lower 31-bit */
+		if(uper_put_constrained_whole_number_u(po, v >> 31, nbits - 31))
+			return -1;
+		return per_put_few_bits(po, v, 31);
+	}
+}
+
 /*
  * Put a small number of bits (<= 31).
  */
@@ -193,8 +327,8 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
 
 	if(obits <= 0 || obits >= 32) return obits ? -1 : 0;
 
-	ASN_DEBUG("[PER put %d bits to %p+%d bits]",
-			obits, po->buffer, po->nboff);
+	ASN_DEBUG("[PER put %d bits %x to %p+%d bits]",
+			obits, (int)bits, po->buffer, (int)po->nboff);
 
 	/*
 	 * Normalize position indicator.
@@ -210,7 +344,9 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
 	 */
 	if(po->nboff + obits > po->nbits) {
 		int complete_bytes = (po->buffer - po->tmpspace);
-		if(po->outper(po->buffer, complete_bytes, po->op_key) < 0)
+		ASN_DEBUG("[PER output %ld complete + %ld]",
+			(long)complete_bytes, (long)po->flushed_bytes);
+		if(po->outper(po->tmpspace, complete_bytes, po->op_key) < 0)
 			return -1;
 		if(po->nboff)
 			po->tmpspace[0] = po->buffer[0];
@@ -224,41 +360,47 @@ per_put_few_bits(asn_per_outp_t *po, uint32_t bits, int obits) {
 	 */
 	buf = po->buffer;
 	omsk = ~((1 << (8 - po->nboff)) - 1);
-	off = (po->nboff += obits);
+	off = (po->nboff + obits);
 
 	/* Clear data of debris before meaningful bits */
 	bits &= (((uint32_t)1 << obits) - 1);
 
-	ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits, bits, bits,
-		po->nboff - obits, off, buf[0], omsk&0xff, buf[0] & omsk);
+	ASN_DEBUG("[PER out %d %u/%x (t=%d,o=%d) %x&%x=%x]", obits,
+		(int)bits, (int)bits,
+		(int)po->nboff, (int)off,
+		buf[0], (int)(omsk&0xff),
+		(int)(buf[0] & omsk));
 
 	if(off <= 8)	/* Completely within 1 byte */
+		po->nboff = off,
 		bits <<= (8 - off),
 		buf[0] = (buf[0] & omsk) | bits;
 	else if(off <= 16)
+		po->nboff = off,
 		bits <<= (16 - off),
 		buf[0] = (buf[0] & omsk) | (bits >> 8),
 		buf[1] = bits;
 	else if(off <= 24)
+		po->nboff = off,
 		bits <<= (24 - off),
 		buf[0] = (buf[0] & omsk) | (bits >> 16),
 		buf[1] = bits >> 8,
 		buf[2] = bits;
 	else if(off <= 31)
+		po->nboff = off,
 		bits <<= (32 - off),
 		buf[0] = (buf[0] & omsk) | (bits >> 24),
 		buf[1] = bits >> 16,
 		buf[2] = bits >> 8,
 		buf[3] = bits;
 	else {
-		ASN_DEBUG("->[PER out split %d]", obits);
-		per_put_few_bits(po, bits >> 8, 24);
+		per_put_few_bits(po, bits >> (obits - 24), 24);
 		per_put_few_bits(po, bits, obits - 24);
-		ASN_DEBUG("<-[PER out split %d]", obits);
 	}
 
-	ASN_DEBUG("[PER out %u/%x => %02x buf+%d]",
-		bits, bits, buf[0], po->buffer - po->tmpspace);
+	ASN_DEBUG("[PER out %u/%x => %02x buf+%ld]",
+		(int)bits, (int)bits, buf[0],
+		(long)(po->buffer - po->tmpspace));
 
 	return 0;
 }
@@ -316,3 +458,26 @@ uper_put_length(asn_per_outp_t *po, size_t length) {
 			? -1 : (ssize_t)(length << 14);
 }
 
+
+/*
+ * Put the normally small length "n" into the stream.
+ * This procedure used to encode length of extensions bit-maps
+ * for SET and SEQUENCE types.
+ */
+int
+uper_put_nslength(asn_per_outp_t *po, size_t length) {
+
+	if(length <= 64) {
+		/* #10.9.3.4 */
+		if(length == 0) return -1;
+		return per_put_few_bits(po, length-1, 7) ? -1 : 0;
+	} else {
+		if(uper_put_length(po, length) != (ssize_t)length) {
+			/* This might happen in case of >16K extensions */
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
diff --git a/libs/smux/regen.sh b/libs/smux/regen.sh
new file mode 100755
index 00000000..2624ffd1
--- /dev/null
+++ b/libs/smux/regen.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+set -euo pipefail
+
+ASN1C=${ASN1C:-"/usr/bin/asn1c"}
+
+ASN1C_FLAGS="${ASN1C_FLAGS:-""} -fcompound-names -fwide-types"
+
+${ASN1C} ${ASN1C_FLAGS} RFC1213-MIB.asn1 RFC1155-SMI.asn1 RFC1157-SNMP.asn1 SMUX.asn1
+mv *.h include/stg/
+rm Makefile.am.sample
+rm converter-sample.c
diff --git a/libs/smux/xer_decoder.c b/libs/smux/xer_decoder.c
index 161dc78c..299a7c1e 100644
--- a/libs/smux/xer_decoder.c
+++ b/libs/smux/xer_decoder.c
@@ -27,7 +27,7 @@ xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	} else {
 		/* If context is not given, be security-conscious anyway */
 		memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
-		s_codec_ctx.max_stack_size = _ASN_DEFAULT_STACK_MAX;
+		s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
 		opt_codec_ctx = &s_codec_ctx;
 	}
 
@@ -70,6 +70,7 @@ xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_ty
 	if(ret < 0) return -1;
 	if(arg.callback_not_invoked) {
 		assert(ret == 0);	/* No data was consumed */
+        *ch_type = PXER_WMORE;
 		return 0;		/* Try again with more data */
 	} else {
 		assert(arg.chunk_size);
@@ -83,7 +84,9 @@ xer_next_token(int *stateContext, const void *buffer, size_t size, pxer_chunk_ty
 	case PXML_TEXT:
 		*ch_type = PXER_TEXT;
 		break;
-	case PXML_TAG: return 0;	/* Want more */
+	case PXML_TAG:
+        *ch_type = PXER_WMORE;
+        return 0;	/* Want more */
 	case PXML_TAG_END:
 		*ch_type = PXER_TAG;
 		break;
@@ -109,7 +112,8 @@ xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
 
 	if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
 		if(size >= 2)
-		ASN_DEBUG("Broken XML tag: \"%c...%c\"", buf[0], buf[size - 1]);
+			ASN_DEBUG("Broken XML tag: \"%c...%c\"",
+			buf[0], buf[size - 1]);
 		return XCT_BROKEN;
 	}
 
@@ -230,12 +234,12 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
 		 */
 		ch_size = xer_next_token(&ctx->context, buf_ptr, size,
 			&ch_type);
-		switch(ch_size) {
-		case -1: RETURN(RC_FAIL);
-		case 0:
-			RETURN(RC_WMORE);
-		default:
+		if(ch_size == -1) {
+            RETURN(RC_FAIL);
+        } else {
 			switch(ch_type) {
+			case PXER_WMORE:
+                RETURN(RC_WMORE);
 			case PXER_COMMENT:		/* Got XML comment */
 				ADVANCE(ch_size);	/* Skip silently */
 				continue;
@@ -315,8 +319,8 @@ xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
 }
 
 
-int
-xer_is_whitespace(const void *chunk_buf, size_t chunk_size) {
+size_t
+xer_whitespace_span(const void *chunk_buf, size_t chunk_size) {
 	const char *p = (const char *)chunk_buf;
 	const char *pend = p + chunk_size;
 
@@ -329,12 +333,13 @@ xer_is_whitespace(const void *chunk_buf, size_t chunk_size) {
 		 * SPACE (32)
 		 */
 		case 0x09: case 0x0a: case 0x0d: case 0x20:
-			break;
+			continue;
 		default:
-			return 0;
+			break;
 		}
+		break;
 	}
-	return 1;       /* All whitespace */
+	return (p - (const char *)chunk_buf);
 }
 
 /*
diff --git a/libs/smux/xer_encoder.c b/libs/smux/xer_encoder.c
index aa7cf040..46065758 100644
--- a/libs/smux/xer_encoder.c
+++ b/libs/smux/xer_encoder.c
@@ -23,18 +23,18 @@ xer_encode(asn_TYPE_descriptor_t *td, void *sptr,
 	mname = td->xml_tag;
 	mlen = strlen(mname);
 
-	_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
+	ASN__CALLBACK3("<", 1, mname, mlen, ">", 1);
 
 	tmper = td->xer_encoder(td, sptr, 1, xer_flags, cb, app_key);
 	if(tmper.encoded == -1) return tmper;
 
-	_ASN_CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
+	ASN__CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
 
 	er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
 
-	_ASN_ENCODED_OK(er);
+	ASN__ENCODED_OK(er);
 cb_failed:
-	_ASN_ENCODE_FAILED;
+	ASN__ENCODE_FAILED;
 }
 
 /*
diff --git a/libs/smux/xer_support.c b/libs/smux/xer_support.c
index 9e34e692..36b4bfbf 100644
--- a/libs/smux/xer_support.c
+++ b/libs/smux/xer_support.c
@@ -22,16 +22,7 @@ typedef enum {
 	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
+static const 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,
@@ -79,8 +70,11 @@ _charclass[256] = {
 #define TOKEN_CB(_type, _ns, _current_too)			\
 	TOKEN_CB_CALL(_type, _ns, _current_too, 0)
 
+#define PXML_TAG_FINAL_CHUNK_TYPE      PXML_TAG_END
+#define PXML_COMMENT_FINAL_CHUNK_TYPE  PXML_COMMENT_END
+
 #define TOKEN_CB_FINAL(_type, _ns, _current_too)		\
-	TOKEN_CB_CALL(final_chunk_type[_type], _ns, _current_too, 1)
+	TOKEN_CB_CALL( _type ## _FINAL_CHUNK_TYPE , _ns, _current_too, 1)
 
 /*
  * Parser itself