add some INTEGER OER encoding code
diff --git a/skeletons/INTEGER_oer.c b/skeletons/INTEGER_oer.c
index a606bf9..73c7e7f 100644
--- a/skeletons/INTEGER_oer.c
+++ b/skeletons/INTEGER_oer.c
@@ -87,23 +87,23 @@
 
         rval.consumed += req_bytes;
         return rval;
-    } else if(ct && (ct->flags & AOC_HAS_LOWER_BOUND)) {
+    } else if(ct
+              && ((ct->flags
+                  & (AOC_HAS_LOWER_BOUND | AOC_HAS_UPPER_BOUND))
+                        == (AOC_HAS_LOWER_BOUND | AOC_HAS_UPPER_BOUND))) {
         /* X.969 08/2015 10.2(b) - no lower bound or negative lower bound */
 
         intmax_t lb = ct->lower_bound;
         intmax_t ub = ct->upper_bound;
 
-        if(ct->flags & AOC_HAS_UPPER_BOUND) {
-            if(lb >= -128 && ub <= 127) {
-                req_bytes = 1;
-            } else if(lb >= -32768 && ub <= 32767) {
-                req_bytes = 2;
-            } else if(lb >= -2147483648L && ub <= 2147483647L) {
-                req_bytes = 4;
-            } else if(lb >= -9223372036854775808LL
-                      && ub <= 9223372036854775807LL) {
-                req_bytes = 8;
-            }
+        if(lb >= -128 && ub <= 127) {
+            req_bytes = 1;
+        } else if(lb >= -32768 && ub <= 32767) {
+            req_bytes = 2;
+        } else if(lb >= -2147483648L && ub <= 2147483647L) {
+            req_bytes = 4;
+        } else if(lb >= -9223372036854775808LL && ub <= 9223372036854775807LL) {
+            req_bytes = 8;
         }
     }
 
@@ -138,4 +138,110 @@
     return rval;
 }
 
+/*
+ * Encode as Canonical OER.
+ */
+asn_enc_rval_t
+INTEGER_encode_oer(asn_TYPE_descriptor_t *td,
+                   asn_oer_constraints_t *constraints, void *sptr,
+                   asn_app_consume_bytes_f *cb, void *app_key) {
+    const INTEGER_t *st = *(const INTEGER_t **)sptr;
+    asn_enc_rval_t er;
+    asn_oer_constraint_t *ct;
+    const uint8_t *buf;
+    const uint8_t *end;
+    size_t useful_bytes;
+    size_t req_bytes = 0;
+    int encode_as_unsigned;
+    int sign = 0;
+
+    if(!st || st->size == 0) ASN__ENCODE_FAILED;
+
+    if(!constraints) constraints = td->oer_constraints;
+    ct = constraints ? &constraints->value : 0;
+
+    er.encoded = 0;
+
+    buf = st->buf;
+    end = buf + st->size;
+
+    encode_as_unsigned =
+        ct && (ct->flags & AOC_HAS_LOWER_BOUND) && ct->lower_bound >= 0;
+
+    sign = (buf && buf < end) ? buf[0] & 0x80 : 0;
+
+    if(encode_as_unsigned && sign) {
+        /* The value given is a signed value. Can't proceed. */
+        ASN__ENCODE_FAILED;
+    }
+
+    /* Ignore 9 leading zeroes or ones */
+    for(; buf + 1 < end; buf++) {
+        if(buf[0] == 0x0 && ((buf[1] & 0x80) == 0 || encode_as_unsigned)) {
+            continue;
+        } else if(buf[0] == 0xff && (buf[1] & 0x80) != 0) {
+            continue;
+        }
+        break;
+    }
+
+    useful_bytes = end - buf;
+    if(encode_as_unsigned) {
+        intmax_t ub = ct->upper_bound;
+
+        if(ub <= 255) {
+            req_bytes = 1;
+        } else if(ub <= 65535) {
+            req_bytes = 2;
+        } else if(ub <= 4294967295UL) {
+            req_bytes = 4;
+        } else if(ub <= 18446744073709551615ULL) {
+            req_bytes = 8;
+        }
+    } else if(ct
+              && ((ct->flags
+                  & (AOC_HAS_LOWER_BOUND | AOC_HAS_UPPER_BOUND))
+                        == (AOC_HAS_LOWER_BOUND | AOC_HAS_UPPER_BOUND))) {
+        /* X.969 08/2015 10.2(b) - no lower bound or negative lower bound */
+
+        intmax_t lb = ct->lower_bound;
+        intmax_t ub = ct->upper_bound;
+
+        if(lb >= -128 && ub <= 127) {
+            req_bytes = 1;
+        } else if(lb >= -32768 && ub <= 32767) {
+            req_bytes = 2;
+        } else if(lb >= -2147483648L && ub <= 2147483647L) {
+            req_bytes = 4;
+        } else if(lb >= -9223372036854775808LL && ub <= 9223372036854775807LL) {
+            req_bytes = 8;
+        }
+    }
+
+    if(req_bytes == 0) {
+        ssize_t r = oer_serialize_length(useful_bytes, cb, app_key);
+        if(r < 0) {
+            ASN__ENCODE_FAILED;
+        }
+        er.encoded += r;
+        req_bytes = useful_bytes;
+    } else if(req_bytes < useful_bytes) {
+        ASN__ENCODE_FAILED;
+    }
+
+    er.encoded += req_bytes;
+
+    for(; req_bytes > useful_bytes; req_bytes--) {
+        if(cb(sign?"\xff":"\0", 1, app_key) < 0) {
+            ASN__ENCODE_FAILED;
+        }
+    }
+
+    if(cb(buf, useful_bytes, app_key) < 0) {
+        ASN__ENCODE_FAILED;
+    }
+
+    ASN__ENCODED_OK(er);
+}
+
 #endif  /* ASN_DISABLE_OER_SUPPORT */
diff --git a/skeletons/oer_support.c b/skeletons/oer_support.c
index 62d2f6d..096652c 100644
--- a/skeletons/oer_support.c
+++ b/skeletons/oer_support.c
@@ -63,3 +63,54 @@
 }
 
 
+/*
+ * Serialize OER length. Returns the number of bytes serialized
+ * or -1 if a given callback returned with negative result.
+ */
+ssize_t
+oer_serialize_length(size_t length, asn_app_consume_bytes_f *cb,
+                     void *app_key) {
+    uint8_t scratch[1 + sizeof(length)];
+    uint8_t *sp = scratch;
+    int littleEndian = 1;   /* Run-time detection */
+    const uint8_t *pstart;
+    const uint8_t *pend;
+    const uint8_t *p;
+    int add;
+
+    if(length <= 127) {
+        uint8_t b = length;
+        if(cb(&b, 1, app_key) < 0) {
+            return -1;
+        }
+        return 1;
+    }
+
+    if(*(char *)&littleEndian) {
+        pstart = (const uint8_t *)&length + sizeof(length);
+        pend = (const uint8_t *)&length;
+        add = -1;
+    } else {
+        pstart = (const uint8_t *)&length;
+        pend = pstart + sizeof(length);
+        add = 1;
+    }
+
+    for(p = pstart; p != pend; p += add) {
+        /* Skip leading zeros. */
+        if(*p) break;
+    }
+
+    for(sp = scratch + 1; p != pend; p += add, sp++) {
+        *sp = *p;
+    }
+    assert((sp - scratch) - 1 <= 0x7f);
+    scratch[0] = 0x80 + ((sp - scratch) - 1);
+
+    if(cb(scratch, sp - scratch, app_key) < 0) {
+        return -1;
+    }
+
+    return sp - scratch;
+}
+
diff --git a/skeletons/oer_support.h b/skeletons/oer_support.h
index 3fba47e..727d7db 100644
--- a/skeletons/oer_support.h
+++ b/skeletons/oer_support.h
@@ -38,6 +38,12 @@
  */
 ssize_t oer_fetch_length(const void *bufptr, size_t size, size_t *len_r);
 
+/*
+ * Serialize OER length. Returns the number of bytes serialized
+ * or -1 if a given callback returned with negative result.
+ */
+ssize_t oer_serialize_length(size_t length, asn_app_consume_bytes_f *cb, void *app_key);
+
 
 #ifdef __cplusplus
 }