BIT STRING decode for OER
diff --git a/examples/sample.source.1609.2/Makefile b/examples/sample.source.1609.2/Makefile
index b57dc68..43b9620 100644
--- a/examples/sample.source.1609.2/Makefile
+++ b/examples/sample.source.1609.2/Makefile
@@ -288,6 +288,7 @@
 ASN_MODULE_SOURCES+=constr_SEQUENCE_oer.c
 ASN_MODULE_SOURCES+=constr_CHOICE_oer.c
 ASN_MODULE_SOURCES+=constr_SET_OF_oer.c
+ASN_MODULE_SOURCES+=BIT_STRING_oer.c
 ASN_CONVERTER_SOURCES+=pdu_collection.c
 
 
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index 7e9b82c..3eabf0c 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -30,8 +30,8 @@
 	0,
 	0,
 #else
-	0,
-	0,
+	BIT_STRING_decode_oer,
+	BIT_STRING_encode_oer,
 #endif  /* ASN_DISABLE_OER_SUPPORT */
 #ifdef	ASN_DISABLE_PER_SUPPORT
 	0,
diff --git a/skeletons/BIT_STRING.h b/skeletons/BIT_STRING.h
index ed3d108..2b19584 100644
--- a/skeletons/BIT_STRING.h
+++ b/skeletons/BIT_STRING.h
@@ -28,6 +28,8 @@
 asn_struct_compare_f BIT_STRING_compare;
 asn_constr_check_f BIT_STRING_constraint;
 xer_type_encoder_f BIT_STRING_encode_xer;
+oer_type_decoder_f BIT_STRING_decode_oer;
+oer_type_encoder_f BIT_STRING_encode_oer;
 
 #define BIT_STRING_free              OCTET_STRING_free
 #define BIT_STRING_decode_ber        OCTET_STRING_decode_ber
diff --git a/skeletons/BIT_STRING_oer.c b/skeletons/BIT_STRING_oer.c
new file mode 100644
index 0000000..55cee4a
--- /dev/null
+++ b/skeletons/BIT_STRING_oer.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
+ * All rights reserved.
+ * Redistribution and modifications are permitted subject to BSD license.
+ */
+#ifndef ASN_DISABLE_OER_SUPPORT
+
+#include <asn_internal.h>
+#include <BIT_STRING.h>
+#include <errno.h>
+
+asn_dec_rval_t
+BIT_STRING_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+                      const asn_oer_constraints_t *constraints, void **sptr,
+                      const void *ptr, size_t size) {
+    BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
+    const asn_oer_constraints_t *cts =
+        constraints ? constraints : td->oer_constraints;
+    ssize_t ct_size = cts ? cts->size : -1;
+    asn_dec_rval_t rval = {RC_OK, 0};
+    size_t expected_length = 0;
+
+    (void)opt_codec_ctx;
+
+    if(!st) {
+        st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st)));
+        if(!st) ASN__DECODE_FAILED;
+    }
+
+    if(ct_size >= 0) {
+        expected_length = (ct_size + 7) >> 3;
+        st->bits_unused = (8 - (ct_size & 7)) & 7;
+    } else {
+        /*
+         * X.696 (08/2015) #13.3.1
+         * Encode length determinant as _number of octets_, but only
+         * if upper bound is not equal to lower bound.
+         */
+        ssize_t len_len = oer_fetch_length(ptr, size, &expected_length);
+        if(len_len > 0) {
+            ptr = (const char *)ptr + len_len;
+            size -= len_len;
+        } else if(len_len == 0) {
+            ASN__DECODE_STARVED;
+        } else if(len_len < 0) {
+            ASN__DECODE_FAILED;
+        }
+
+        if(expected_length < 1) {
+            ASN__DECODE_STARVED;
+        }
+
+        st->bits_unused = ((const uint8_t *)ptr)[0];
+        if(st->bits_unused & ~7) {
+            ASN_DEBUG("%s: unused bits outside of 0..7 range", td->name);
+            ASN__DECODE_FAILED;
+        }
+        ptr = (const char *)ptr + 1;
+        size--;
+        expected_length--;
+        rval.consumed = len_len + 1;
+    }
+
+    if(size < expected_length) {
+        ASN__DECODE_STARVED;
+    } else {
+        uint8_t *buf = MALLOC(expected_length + 1);
+        if(buf == NULL) {
+            ASN__DECODE_FAILED;
+        } else {
+            memcpy(buf, ptr, expected_length);
+            buf[expected_length] = '\0';
+        }
+        FREEMEM(st->buf);
+        st->buf = buf;
+        st->size = expected_length;
+        if(expected_length > 0) {
+            buf[expected_length - 1] &= (0xff << st->bits_unused);
+        }
+
+        rval.consumed += expected_length;
+        return rval;
+    }
+}
+
+/*
+ * Encode as Canonical OER.
+ */
+asn_enc_rval_t
+BIT_STRING_encode_oer(asn_TYPE_descriptor_t *td,
+                        const asn_oer_constraints_t *constraints, void *sptr,
+                        asn_app_consume_bytes_f *cb, void *app_key) {
+    asn_enc_rval_t er = {-1,td,sptr};
+    (void)constraints;
+    (void)cb;
+    (void)app_key;
+    return er;
+}
+
+
+#endif  /* ASN_DISABLE_OER_SUPPORT */
diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am
index 4b36622..d61c66c 100644
--- a/skeletons/Makefile.am
+++ b/skeletons/Makefile.am
@@ -24,6 +24,7 @@
 libasn1cskeletons_la_SOURCES = 				\
 	ANY.c ANY.h					\
 	BIT_STRING.c BIT_STRING.h			\
+	BIT_STRING_oer.c 			\
 	BMPString.c BMPString.h				\
 	BOOLEAN.c BOOLEAN.h				\
 	ENUMERATED.c ENUMERATED.h			\
diff --git a/skeletons/constr_SEQUENCE_oer.c b/skeletons/constr_SEQUENCE_oer.c
index 85566a3..5b2a0bd 100644
--- a/skeletons/constr_SEQUENCE_oer.c
+++ b/skeletons/constr_SEQUENCE_oer.c
@@ -54,10 +54,16 @@
 /*
  * Return pointer to a member.
  */
-static void **element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm) {
-    assert(elm->flags & ATF_POINTER);
-    /* Member is a pointer to another structure */
-    return (void **)((char *)struct_ptr + elm->memb_offset);
+static void **
+element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) {
+    if(elm->flags & ATF_POINTER) {
+        /* Member is a pointer to another structure */
+        return (void **)((char *)struct_ptr + elm->memb_offset);
+    } else {
+        assert(tmp_save_ptr);
+        *tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset);
+        return tmp_save_ptr;
+    }
 }
 
 static void *element_ptr(void *struct_ptr, asn_TYPE_member_t *elm) {
@@ -172,7 +178,9 @@
                 } else if(present == 0) {
                     if(elm->default_value) {
                         /* Fill-in DEFAULT */
-                        if(elm->default_value(1, element_ptrptr(st, elm))) {
+                        void *tmp;
+                        if(elm->default_value(1,
+                                              element_ptrptr(st, elm, &tmp))) {
                             RETURN(RC_FAIL);
                         }
                     }
@@ -306,7 +314,7 @@
             asn_bit_data_t *extadds = ctx->ptr;
             size_t edx = ctx->step;
             asn_TYPE_member_t *elm = &td->elements[edx];
-            void **memb_ptr2 = element_ptrptr(st, elm);
+            void **memb_ptr2 = element_ptrptr(st, elm, 0);
 
             switch(asn_get_few_bits(extadds, 1)) {
             case -1:
diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies
index 6a9e135..8814d68 100644
--- a/skeletons/file-dependencies
+++ b/skeletons/file-dependencies
@@ -79,5 +79,6 @@
 constr_SEQUENCE_oer.c
 constr_CHOICE_oer.c
 constr_SET_OF_oer.c constr_SET_OF.h asn_SET_OF.h asn_SET_OF.c
+BIT_STRING_oer.c
 
 CODEC-PER:			# THIS IS A SPECIAL SECTION