decode Open Type in XER
diff --git a/examples/sample.source.J2735/sample-MessageFrame-1.xer b/examples/sample.source.J2735/sample-MessageFrame-1.xer
new file mode 100644
index 0000000..1063d08
--- /dev/null
+++ b/examples/sample.source.J2735/sample-MessageFrame-1.xer
@@ -0,0 +1,140 @@
+<MessageFrame>
+    <messageId>20</messageId>
+    <value>
+        <BasicSafetyMessage>
+            <coreData>
+                <msgCnt>88</msgCnt>
+                <id>00 00 00 00</id>
+                <secMark>59000</secMark>
+                <lat>511041141</lat>
+                <long>-1341224725</long>
+                <elev>188</elev>
+                <accuracy>
+                    <semiMajor>255</semiMajor>
+                    <semiMinor>255</semiMinor>
+                    <orientation>65535</orientation>
+                </accuracy>
+                <transmission><unavailable/></transmission>
+                <speed>0</speed>
+                <heading>15290</heading>
+                <angle>127</angle>
+                <accelSet>
+                    <long>2001</long>
+                    <lat>2001</lat>
+                    <vert>-127</vert>
+                    <yaw>0</yaw>
+                </accelSet>
+                <brakes>
+                    <wheelBrakes>
+                        10000
+                    </wheelBrakes>
+                    <traction><unavailable/></traction>
+                    <abs><unavailable/></abs>
+                    <scs><unavailable/></scs>
+                    <brakeBoost><unavailable/></brakeBoost>
+                    <auxBrakes><unavailable/></auxBrakes>
+                </brakes>
+                <size>
+                    <width>0</width>
+                    <length>0</length>
+                </size>
+            </coreData>
+            <partII>
+                <PartIIcontent>
+                    <partII-Id>0</partII-Id>
+                    <partII-Value>
+                        <VehicleSafetyExtensions>
+                            <pathHistory>
+                                <crumbData>
+                                    <PathHistoryPoint>
+                                        <latOffset>-131072</latOffset>
+                                        <lonOffset>-131072</lonOffset>
+                                        <elevationOffset>-2048</elevationOffset>
+                                        <timeOffset>1</timeOffset>
+                                    </PathHistoryPoint>
+                                    <PathHistoryPoint>
+                                        <latOffset>131071</latOffset>
+                                        <lonOffset>131071</lonOffset>
+                                        <elevationOffset>2037</elevationOffset>
+                                        <timeOffset>65535</timeOffset>
+                                    </PathHistoryPoint>
+                                </crumbData>
+                            </pathHistory>
+                            <pathPrediction>
+                                <radiusOfCurve>32767</radiusOfCurve>
+                                <confidence>0</confidence>
+                            </pathPrediction>
+                        </VehicleSafetyExtensions>
+                    </partII-Value>
+                </PartIIcontent>
+            </partII>
+        </BasicSafetyMessage>
+    </value>
+</MessageFrame>
+<MessageFrame>
+    <messageId>20</messageId>
+    <value>
+        <BasicSafetyMessage>
+            <coreData>
+                <msgCnt>89</msgCnt>
+                <id>FF 00 00 01</id>
+                <secMark>59000</secMark>
+                <lat>511041141</lat>
+                <long>-1341224725</long>
+                <elev>188</elev>
+                <accuracy>
+                    <semiMajor>255</semiMajor>
+                    <semiMinor>255</semiMinor>
+                    <orientation>65535</orientation>
+                </accuracy>
+                <transmission><unavailable/></transmission>
+                <speed>0</speed>
+                <heading>15290</heading>
+                <angle>127</angle>
+                <accelSet>
+                    <long>2001</long>
+                    <lat>2001</lat>
+                    <vert>-127</vert>
+                    <yaw>0</yaw>
+                </accelSet>
+                <brakes>
+                    <wheelBrakes>
+                        10000
+                    </wheelBrakes>
+                    <traction><unavailable/></traction>
+                    <abs><unavailable/></abs>
+                    <scs><unavailable/></scs>
+                    <brakeBoost><unavailable/></brakeBoost>
+                    <auxBrakes><unavailable/></auxBrakes>
+                </brakes>
+                <size>
+                    <width>0</width>
+                    <length>0</length>
+                </size>
+            </coreData>
+            <partII>
+                <PartIIcontent>
+                    <partII-Id>0</partII-Id>
+                    <partII-Value>
+                        <VehicleSafetyExtensions>
+                            <pathHistory>
+                                <crumbData>
+                                    <PathHistoryPoint>
+                                        <latOffset>0</latOffset>
+                                        <lonOffset>0</lonOffset>
+                                        <elevationOffset>0</elevationOffset>
+                                        <timeOffset>1</timeOffset>
+                                    </PathHistoryPoint>
+                                </crumbData>
+                            </pathHistory>
+                            <pathPrediction>
+                                <radiusOfCurve>0</radiusOfCurve>
+                                <confidence>0</confidence>
+                            </pathPrediction>
+                        </VehicleSafetyExtensions>
+                    </partII-Value>
+                </PartIIcontent>
+            </partII>
+        </BasicSafetyMessage>
+    </value>
+</MessageFrame>
diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am
index 1af93c2..3d33484 100644
--- a/skeletons/Makefile.am
+++ b/skeletons/Makefile.am
@@ -42,7 +42,8 @@
 	NumericString.c NumericString.h			\
 	OBJECT_IDENTIFIER.c OBJECT_IDENTIFIER.h		\
 	OCTET_STRING.c OCTET_STRING.h	\
-    OCTET_STRING_oer.c \
+	OCTET_STRING_oer.c \
+	OPEN_TYPE.c OPEN_TYPE.h					\
 	ObjectDescriptor.c ObjectDescriptor.h		\
 	PrintableString.c PrintableString.h		\
 	REAL.c REAL.h					\
diff --git a/skeletons/OPEN_TYPE.c b/skeletons/OPEN_TYPE.c
index 6f90028..6c73eef 100644
--- a/skeletons/OPEN_TYPE.c
+++ b/skeletons/OPEN_TYPE.c
@@ -23,6 +23,171 @@
 	0,	/* Use generic outmost tag fetcher */
 };
 
+#undef  XER_ADVANCE
+#define XER_ADVANCE(num_bytes)           \
+    do {                                 \
+        size_t num = num_bytes;          \
+        ptr = ((const char *)ptr) + num; \
+        size -= num;                     \
+        consumed_myself += num;          \
+    } while(0)
+
+asn_dec_rval_t
+OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
+                  void *sptr, asn_TYPE_member_t *elm, const void *ptr,
+                  size_t size) {
+    size_t consumed_myself = 0;
+    asn_type_selector_result_t selected;
+    void *memb_ptr;   /* Pointer to the member */
+    void **memb_ptr2; /* Pointer to that pointer */
+    void *inner_value;
+    const char *xml_tag;
+    asn_dec_rval_t rv;
+
+    int xer_context = 0;
+    ssize_t ch_size;
+    pxer_chunk_type_e ch_type;
+
+    if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
+        ASN__DECODE_FAILED;
+    }
+
+    selected = elm->type_selector(td, sptr);
+    if(!selected.presence_index) {
+        ASN__DECODE_FAILED;
+    }
+
+    /* Fetch the pointer to this member */
+    assert(elm->flags == ATF_OPEN_TYPE);
+    if(elm->flags & ATF_POINTER) {
+        memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
+    } else {
+        memb_ptr = (char *)sptr + elm->memb_offset;
+        memb_ptr2 = &memb_ptr;
+    }
+    if(*memb_ptr2 != NULL) {
+        /* Make sure we reset the structure first before encoding */
+        if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
+           != 0) {
+            ASN__DECODE_FAILED;
+        }
+    }
+
+    /*
+     * Confirm wrapper.
+     */
+    for(;;) {
+        ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
+        if(ch_size <= 0) {
+            ASN__DECODE_FAILED;
+        } else {
+            switch(ch_type) {
+            case PXER_WMORE:
+                ASN__DECODE_STARVED;
+            case PXER_COMMENT:
+            case PXER_TEXT:
+                XER_ADVANCE(ch_size);
+                continue;
+            case PXER_TAG:
+                break;
+            }
+            break;
+        }
+    }
+
+    /*
+     * Wrapper value confirmed.
+     */
+    switch(xer_check_tag(ptr, ch_size, elm->name)) {
+    case XCT_OPENING:
+        XER_ADVANCE(ch_size);
+        break;
+    case XCT_BROKEN:
+    default:
+        ASN__DECODE_FAILED;
+    }
+
+    inner_value =
+        (char *)*memb_ptr2
+        + elm->type->elements[selected.presence_index - 1].memb_offset;
+
+    rv = selected.type_descriptor->op->xer_decoder(
+        opt_codec_ctx, selected.type_descriptor, &inner_value, NULL, ptr, size);
+    XER_ADVANCE(rv.consumed);
+    rv.consumed = 0;
+    switch(rv.code) {
+    case RC_OK:
+        if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
+                                       selected.presence_index)
+           == 0) {
+            break;
+        } else {
+            rv.code = RC_FAIL;
+        }
+        /* Fall through */
+    case RC_FAIL:
+        /* Point to a best position where failure occurred */
+        rv.consumed = consumed_myself;
+        /* Fall through */
+    case RC_WMORE:
+        /* Wrt. rv.consumed==0:
+         * In case a genuine RC_WMORE, the whole Open Type decoding
+         * will have to be restarted.
+         */
+        if(*memb_ptr2) {
+            asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
+            if(elm->flags & ATF_POINTER) {
+                ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
+                *memb_ptr2 = NULL;
+            } else {
+                ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
+                                              inner_value);
+                memset(*memb_ptr2, 0, specs->struct_size);
+            }
+        }
+        return rv;
+    }
+
+    /*
+     * Finalize wrapper.
+     */
+    for(;;) {
+        ch_size = xer_next_token(&xer_context, ptr, size, &ch_type);
+        if(ch_size <= 0) {
+            ASN__DECODE_FAILED;
+        } else {
+            switch(ch_type) {
+            case PXER_WMORE:
+                ASN__DECODE_STARVED;
+            case PXER_COMMENT:
+            case PXER_TEXT:
+                XER_ADVANCE(ch_size);
+                continue;
+            case PXER_TAG:
+                break;
+            }
+            break;
+        }
+    }
+
+    /*
+     * Wrapper value confirmed.
+     */
+    switch(xer_check_tag(ptr, ch_size, elm->name)) {
+    case XCT_CLOSING:
+        XER_ADVANCE(ch_size);
+        break;
+    case XCT_BROKEN:
+    default:
+        ASN__DECODE_FAILED;
+    }
+
+    rv.consumed += consumed_myself;
+
+    return rv;
+}
+
+
 #ifndef  ASN_DISABLE_PER_SUPPORT
 
 asn_dec_rval_t
@@ -32,6 +197,7 @@
     asn_type_selector_result_t selected;
     void *memb_ptr;   /* Pointer to the member */
     void **memb_ptr2; /* Pointer to that pointer */
+    void *inner_value;
     asn_dec_rval_t rv;
 
     if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
@@ -59,7 +225,7 @@
         }
     }
 
-    void *inner_value =
+    inner_value =
         (char *)*memb_ptr2
         + elm->type->elements[selected.presence_index - 1].memb_offset;
 
diff --git a/skeletons/OPEN_TYPE.h b/skeletons/OPEN_TYPE.h
index 060675a..ff49ada 100644
--- a/skeletons/OPEN_TYPE.h
+++ b/skeletons/OPEN_TYPE.h
@@ -28,11 +28,11 @@
  * Decode an Open Type which is potentially constraiend
  * by the other members of the parent structure.
  */
-asn_dec_rval_t OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
-                                  asn_TYPE_descriptor_t *parent_type,
-                                  void *parent_structure,
-                                  asn_TYPE_member_t *element,
-                                  asn_per_data_t *pd);
+asn_dec_rval_t OPEN_TYPE_xer_get(asn_codec_ctx_t *opt_codec_ctx,
+                                 asn_TYPE_descriptor_t *parent_type,
+                                 void *parent_structure,
+                                 asn_TYPE_member_t *element, const void *ptr,
+                                 size_t size);
 
 asn_dec_rval_t OPEN_TYPE_oer_get(asn_codec_ctx_t *opt_codec_ctx,
                                   asn_TYPE_descriptor_t *parent_type,
@@ -40,6 +40,12 @@
                                   asn_TYPE_member_t *element,
                                   const void *ptr, size_t size);
 
+asn_dec_rval_t OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
+                                  asn_TYPE_descriptor_t *parent_type,
+                                  void *parent_structure,
+                                  asn_TYPE_member_t *element,
+                                  asn_per_data_t *pd);
+
 
 #ifdef __cplusplus
 }
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index b863d5f..ba74067 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -594,12 +594,13 @@
 
 
 #undef	XER_ADVANCE
-#define	XER_ADVANCE(num_bytes)	do {			\
-		size_t num = num_bytes;			\
-		buf_ptr = ((const char *)buf_ptr) + num;\
-		size -= num;				\
-		consumed_myself += num;			\
-	} while(0)
+#define XER_ADVANCE(num_bytes)           \
+    do {                                 \
+        size_t num = (num_bytes);        \
+        ptr = ((const char *)ptr) + num; \
+        size -= num;                     \
+        consumed_myself += num;          \
+    } while(0)
 
 /*
  * Decode the XER (XML) data.
@@ -607,7 +608,7 @@
 asn_dec_rval_t
 SEQUENCE_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
 	void **struct_ptr, const char *opt_mname,
-		const void *buf_ptr, size_t size) {
+		const void *ptr, size_t size) {
 	/*
 	 * Bring closer parts of structure description.
 	 */
@@ -672,10 +673,14 @@
 				memb_ptr2 = &memb_ptr;
 			}
 
-			/* Invoke the inner type decoder, m.b. multiple times */
-			tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
-					elm->type, memb_ptr2, elm->name,
-					buf_ptr, size);
+			if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) {
+				tmprval = OPEN_TYPE_xer_get(opt_codec_ctx, td, st, elm, ptr, size);
+			} else {
+				/* Invoke the inner type decoder, m.b. multiple times */
+				tmprval = elm->type->op->xer_decoder(opt_codec_ctx,
+						elm->type, memb_ptr2, elm->name,
+						ptr, size);
+			}
 			XER_ADVANCE(tmprval.consumed);
 			if(tmprval.code != RC_OK)
 				RETURN(tmprval.code);
@@ -689,14 +694,14 @@
 		/*
 		 * Get the next part of the XML stream.
 		 */
-		ch_size = xer_next_token(&ctx->context, buf_ptr, size,
+		ch_size = xer_next_token(&ctx->context, ptr, size,
 			&ch_type);
 		if(ch_size == -1) {
 		    RETURN(RC_FAIL);
-        } else {
+		} else {
 			switch(ch_type) {
-            case PXER_WMORE:
-                RETURN(RC_WMORE);
+			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 */
@@ -706,7 +711,7 @@
 			}
 		}
 
-		tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
+		tcv = xer_check_tag(ptr, ch_size, xml_tag);
 		ASN_DEBUG("XER/SEQUENCE: tcv = %d, ph=%d [%s]",
 			tcv, ctx->phase, xml_tag);
 
@@ -782,8 +787,7 @@
 					edx_end = td->elements_count;
 				for(n = edx; n < edx_end; n++) {
 					elm = &td->elements[n];
-					tcv = xer_check_tag(buf_ptr,
-						ch_size, elm->name);
+					tcv = xer_check_tag(ptr, ch_size, elm->name);
 					switch(tcv) {
 					case XCT_BOTH:
 					case XCT_OPENING:
@@ -836,12 +840,12 @@
 		}
 
 		ASN_DEBUG("Unexpected XML tag in SEQUENCE [%c%c%c%c%c%c]",
-			size>0?((const char *)buf_ptr)[0]:'.',
-			size>1?((const char *)buf_ptr)[1]:'.',
-			size>2?((const char *)buf_ptr)[2]:'.',
-			size>3?((const char *)buf_ptr)[3]:'.',
-			size>4?((const char *)buf_ptr)[4]:'.',
-			size>5?((const char *)buf_ptr)[5]:'.');
+			size>0?((const char *)ptr)[0]:'.',
+			size>1?((const char *)ptr)[1]:'.',
+			size>2?((const char *)ptr)[2]:'.',
+			size>3?((const char *)ptr)[3]:'.',
+			size>4?((const char *)ptr)[4]:'.',
+			size>5?((const char *)ptr)[5]:'.');
 		break;
 	}
 
@@ -1135,7 +1139,7 @@
 		if((elm->flags & ATF_OPEN_TYPE) && elm->type_selector) {
 			rv = OPEN_TYPE_uper_get(opt_codec_ctx, td, st, elm, pd);
 		} else {
-            		rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
+			rv = elm->type->op->uper_decoder(opt_codec_ctx, elm->type,
 					elm->per_constraints, memb_ptr2, pd);
 		}
 		if(rv.code != RC_OK) {