diff --git a/src/main/java/org.onosproject.xran/codecs/api/ARFCNValue.java b/src/main/java/org.onosproject.xran/codecs/api/ARFCNValue.java
new file mode 100644
index 0000000..cffdb07
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ARFCNValue.java
@@ -0,0 +1,44 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+
+
+public class ARFCNValue extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public ARFCNValue() {
+	}
+
+	public ARFCNValue(byte[] code) {
+		super(code);
+	}
+
+	public ARFCNValue(BigInteger value) {
+		super(value);
+	}
+
+	public ARFCNValue(long value) {
+		super(value);
+	}
+
+	@Override
+	public int hashCode() {
+		return value.intValue();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof ARFCNValue) {
+			return value.intValue() == ((ARFCNValue) obj).value.intValue();
+		}
+		return super.equals(obj);
+	}
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/AdmEstCause.java b/src/main/java/org.onosproject.xran/codecs/api/AdmEstCause.java
new file mode 100644
index 0000000..e344fc5
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/AdmEstCause.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class AdmEstCause extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public AdmEstCause() {
+	}
+
+	public AdmEstCause(byte[] code) {
+		super(code);
+	}
+
+	public AdmEstCause(BigInteger value) {
+		super(value);
+	}
+
+	public AdmEstCause(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/AdmEstResponse.java b/src/main/java/org.onosproject.xran/codecs/api/AdmEstResponse.java
new file mode 100644
index 0000000..388b64e
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/AdmEstResponse.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class AdmEstResponse extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public AdmEstResponse() {
+	}
+
+	public AdmEstResponse(byte[] code) {
+		super(code);
+	}
+
+	public AdmEstResponse(BigInteger value) {
+		super(value);
+	}
+
+	public AdmEstResponse(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/AdmEstStatus.java b/src/main/java/org.onosproject.xran/codecs/api/AdmEstStatus.java
new file mode 100644
index 0000000..68680a6
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/AdmEstStatus.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class AdmEstStatus extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public AdmEstStatus() {
+	}
+
+	public AdmEstStatus(byte[] code) {
+		super(code);
+	}
+
+	public AdmEstStatus(BigInteger value) {
+		super(value);
+	}
+
+	public AdmEstStatus(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/BitRate.java b/src/main/java/org.onosproject.xran/codecs/api/BitRate.java
new file mode 100644
index 0000000..7b0b49d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/BitRate.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class BitRate extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public BitRate() {
+	}
+
+	public BitRate(byte[] code) {
+		super(code);
+	}
+
+	public BitRate(BigInteger value) {
+		super(value);
+	}
+
+	public BitRate(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/CACap.java b/src/main/java/org.onosproject.xran/codecs/api/CACap.java
new file mode 100644
index 0000000..cd2ef5c
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/CACap.java
@@ -0,0 +1,231 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerBoolean;
+import org.openmuc.jasn1.ber.types.BerEnum;
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class CACap implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private BerInteger band = null;
+	private BerEnum caclassdl = null;
+	private BerEnum caclassul = null;
+	private BerBoolean crossCarrierSched = null;
+	
+	public CACap() {
+	}
+
+	public CACap(byte[] code) {
+		this.code = code;
+	}
+
+	public void setBand(BerInteger band) {
+		this.band = band;
+	}
+
+	public BerInteger getBand() {
+		return band;
+	}
+
+	public void setCaclassdl(BerEnum caclassdl) {
+		this.caclassdl = caclassdl;
+	}
+
+	public BerEnum getCaclassdl() {
+		return caclassdl;
+	}
+
+	public void setCaclassul(BerEnum caclassul) {
+		this.caclassul = caclassul;
+	}
+
+	public BerEnum getCaclassul() {
+		return caclassul;
+	}
+
+	public void setCrossCarrierSched(BerBoolean crossCarrierSched) {
+		this.crossCarrierSched = crossCarrierSched;
+	}
+
+	public BerBoolean getCrossCarrierSched() {
+		return crossCarrierSched;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += crossCarrierSched.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += caclassul.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += caclassdl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += band.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			band = new BerInteger();
+			subCodeLength += band.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			caclassdl = new BerEnum();
+			subCodeLength += caclassdl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			caclassul = new BerEnum();
+			subCodeLength += caclassul.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			crossCarrierSched = new BerBoolean();
+			subCodeLength += crossCarrierSched.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (band != null) {
+			sb.append("\"band\":").append(band);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (caclassdl != null) {
+			sb.append("\"caclassdl\":").append(caclassdl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (caclassul != null) {
+			sb.append("\"caclassul\":").append(caclassul);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crossCarrierSched != null) {
+			sb.append("\"crossCarrierSched\":").append(crossCarrierSched);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/CRNTI.java b/src/main/java/org.onosproject.xran/codecs/api/CRNTI.java
new file mode 100644
index 0000000..69d5f48
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/CRNTI.java
@@ -0,0 +1,56 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+import javax.xml.bind.DatatypeConverter;
+
+
+public class CRNTI extends BerBitString {
+
+	private static final long serialVersionUID = 1L;
+
+	public CRNTI() {
+	}
+
+	public CRNTI(byte[] code) {
+		super(code);
+	}
+
+	public CRNTI(byte[] value, int numBits) {
+		super(value, numBits);
+	}
+
+	@Override
+	public int hashCode() {
+		return Arrays.hashCode(value);
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof CRNTI) {
+			return Arrays.equals(value, ((CRNTI) obj).value);
+		}
+		return super.equals(obj);
+	}
+
+	@Override
+	public String toString() {
+		return "\"" + DatatypeConverter.printHexBinary(value) + "\"";
+	}
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/CandScell.java b/src/main/java/org.onosproject.xran/codecs/api/CandScell.java
new file mode 100644
index 0000000..7b954d0
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/CandScell.java
@@ -0,0 +1,165 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class CandScell implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PhysCellId pci = null;
+	private ARFCNValue earfcnDl = null;
+	
+	public CandScell() {
+	}
+
+	public CandScell(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPci(PhysCellId pci) {
+		this.pci = pci;
+	}
+
+	public PhysCellId getPci() {
+		return pci;
+	}
+
+	public void setEarfcnDl(ARFCNValue earfcnDl) {
+		this.earfcnDl = earfcnDl;
+	}
+
+	public ARFCNValue getEarfcnDl() {
+		return earfcnDl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += earfcnDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += pci.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			pci = new PhysCellId();
+			subCodeLength += pci.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			earfcnDl = new ARFCNValue();
+			subCodeLength += earfcnDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pci != null) {
+			sb.append("\"pci\": ").append(pci);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (earfcnDl != null) {
+			sb.append("\"earfcnDl\": ").append(earfcnDl);
+		}
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/DCCap.java b/src/main/java/org.onosproject.xran/codecs/api/DCCap.java
new file mode 100644
index 0000000..f3f7c61
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/DCCap.java
@@ -0,0 +1,136 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class DCCap implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private BerEnum drbTypeSplit = null;
+	
+	public DCCap() {
+	}
+
+	public DCCap(byte[] code) {
+		this.code = code;
+	}
+
+	public void setDrbTypeSplit(BerEnum drbTypeSplit) {
+		this.drbTypeSplit = drbTypeSplit;
+	}
+
+	public BerEnum getDrbTypeSplit() {
+		return drbTypeSplit;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += drbTypeSplit.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			drbTypeSplit = new BerEnum();
+			subCodeLength += drbTypeSplit.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (drbTypeSplit != null) {
+			sb.append("\"drbTypeSplit\": ").append(drbTypeSplit);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/DuplexMode.java b/src/main/java/org.onosproject.xran/codecs/api/DuplexMode.java
new file mode 100644
index 0000000..cfbd191
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/DuplexMode.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class DuplexMode extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public DuplexMode() {
+	}
+
+	public DuplexMode(byte[] code) {
+		super(code);
+	}
+
+	public DuplexMode(BigInteger value) {
+		super(value);
+	}
+
+	public DuplexMode(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ECGI.java b/src/main/java/org.onosproject.xran/codecs/api/ECGI.java
new file mode 100644
index 0000000..01789f2
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ECGI.java
@@ -0,0 +1,180 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class ECGI implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PLMNIdentity pLMNIdentity = null;
+	private EUTRANCellIdentifier eUTRANcellIdentifier = null;
+	
+	public ECGI() {
+	}
+
+	public ECGI(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPLMNIdentity(PLMNIdentity pLMNIdentity) {
+		this.pLMNIdentity = pLMNIdentity;
+	}
+
+	public PLMNIdentity getPLMNIdentity() {
+		return pLMNIdentity;
+	}
+
+	public void setEUTRANcellIdentifier(EUTRANCellIdentifier eUTRANcellIdentifier) {
+		this.eUTRANcellIdentifier = eUTRANcellIdentifier;
+	}
+
+	public EUTRANCellIdentifier getEUTRANcellIdentifier() {
+		return eUTRANcellIdentifier;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += eUTRANcellIdentifier.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += pLMNIdentity.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			pLMNIdentity = new PLMNIdentity();
+			subCodeLength += pLMNIdentity.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			eUTRANcellIdentifier = new EUTRANCellIdentifier();
+			subCodeLength += eUTRANcellIdentifier.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pLMNIdentity != null) {
+			sb.append("\"pLMNIdentity\": ").append(pLMNIdentity);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (eUTRANcellIdentifier != null) {
+			sb.append("\"eUTRANcellIdentifier\": ").append(eUTRANcellIdentifier);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (this == o) return true;
+		if (o == null || getClass() != o.getClass()) return false;
+
+		ECGI ecgi = (ECGI) o;
+
+		return eUTRANcellIdentifier.equals(ecgi.eUTRANcellIdentifier);
+	}
+
+	@Override
+	public int hashCode() {
+		return eUTRANcellIdentifier.hashCode();
+	}
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ENBUES1APID.java b/src/main/java/org.onosproject.xran/codecs/api/ENBUES1APID.java
new file mode 100644
index 0000000..2bb7c15
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ENBUES1APID.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ENBUES1APID extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public ENBUES1APID() {
+	}
+
+	public ENBUES1APID(byte[] code) {
+		super(code);
+	}
+
+	public ENBUES1APID(BigInteger value) {
+		super(value);
+	}
+
+	public ENBUES1APID(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABDecision.java b/src/main/java/org.onosproject.xran/codecs/api/ERABDecision.java
new file mode 100644
index 0000000..7d50dc7
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABDecision.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABDecision extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public ERABDecision() {
+	}
+
+	public ERABDecision(byte[] code) {
+		super(code);
+	}
+
+	public ERABDecision(BigInteger value) {
+		super(value);
+	}
+
+	public ERABDecision(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABDirection.java b/src/main/java/org.onosproject.xran/codecs/api/ERABDirection.java
new file mode 100644
index 0000000..d29502c
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABDirection.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABDirection extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public ERABDirection() {
+	}
+
+	public ERABDirection(byte[] code) {
+		super(code);
+	}
+
+	public ERABDirection(BigInteger value) {
+		super(value);
+	}
+
+	public ERABDirection(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABID.java b/src/main/java/org.onosproject.xran/codecs/api/ERABID.java
new file mode 100644
index 0000000..92875c8
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABID.java
@@ -0,0 +1,52 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABID extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public ERABID() {
+	}
+
+	public ERABID(byte[] code) {
+		super(code);
+	}
+
+	public ERABID(BigInteger value) {
+		super(value);
+	}
+
+	public ERABID(long value) {
+		super(value);
+	}
+
+	@Override
+	public int hashCode() {
+		return value.intValue();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof ERABID) {
+			return value.intValue() == ((ERABID) obj).intValue();
+		}
+		return super.equals(obj);
+	}
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABParams.java b/src/main/java/org.onosproject.xran/codecs/api/ERABParams.java
new file mode 100644
index 0000000..237c5d9
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABParams.java
@@ -0,0 +1,154 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABParams implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+	public byte[] code = null;
+	private List<ERABParamsItem> seqOf = null;
+
+	public ERABParams() {
+		seqOf = new ArrayList<ERABParamsItem>();
+	}
+
+	public ERABParams(byte[] code) {
+		this.code = code;
+	}
+
+	public List<ERABParamsItem> getERABParamsItem() {
+		if (seqOf == null) {
+			seqOf = new ArrayList<ERABParamsItem>();
+		}
+		return seqOf;
+	}
+
+	public void setERABParamsItem(ArrayList<ERABParamsItem> erabParamsItem) {
+		seqOf = erabParamsItem;
+	}
+
+	public void addERABParamsItem(ERABParamsItem erabParamsItem) {
+		seqOf.add(erabParamsItem);
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		for (int i = (seqOf.size() - 1); i >= 0; i--) {
+			codeLength += seqOf.get(i).encode(os, true);
+		}
+
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+		int totalLength = length.val;
+
+		while (subCodeLength < totalLength) {
+			ERABParamsItem element = new ERABParamsItem();
+			subCodeLength += element.decode(is, true);
+			seqOf.add(element);
+		}
+		if (subCodeLength != totalLength) {
+			throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+		}
+		codeLength += subCodeLength;
+
+		return codeLength;
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("[\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (seqOf == null) {
+//			sb.append("null");
+		}
+		else {
+			Iterator<ERABParamsItem> it = seqOf.iterator();
+			if (it.hasNext()) {
+				it.next().appendAsString(sb, indentLevel + 1);
+				while (it.hasNext()) {
+					sb.append(",\n");
+					for (int i = 0; i < indentLevel + 1; i++) {
+						sb.append("\t");
+					}
+					it.next().appendAsString(sb, indentLevel + 1);
+				}
+			}
+		}
+
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("]");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABParamsItem.java b/src/main/java/org.onosproject.xran/codecs/api/ERABParamsItem.java
new file mode 100644
index 0000000..9db7698
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABParamsItem.java
@@ -0,0 +1,386 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABParamsItem implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ERABID id = null;
+	private ERABDirection direction = null;
+	private ERABType type = null;
+	private QCI qci = null;
+	private BerInteger arp = null;
+	private BitRate gbrDl = null;
+	private BitRate gbrUl = null;
+	private BitRate mbrDl = null;
+	private BitRate mbrUl = null;
+	
+	public ERABParamsItem() {
+	}
+
+	public ERABParamsItem(byte[] code) {
+		this.code = code;
+	}
+
+	public void setId(ERABID id) {
+		this.id = id;
+	}
+
+	public ERABID getId() {
+		return id;
+	}
+
+	public void setDirection(ERABDirection direction) {
+		this.direction = direction;
+	}
+
+	public ERABDirection getDirection() {
+		return direction;
+	}
+
+	public void setType(ERABType type) {
+		this.type = type;
+	}
+
+	public ERABType getType() {
+		return type;
+	}
+
+	public void setQci(QCI qci) {
+		this.qci = qci;
+	}
+
+	public QCI getQci() {
+		return qci;
+	}
+
+	public void setArp(BerInteger arp) {
+		this.arp = arp;
+	}
+
+	public BerInteger getArp() {
+		return arp;
+	}
+
+	public void setGbrDl(BitRate gbrDl) {
+		this.gbrDl = gbrDl;
+	}
+
+	public BitRate getGbrDl() {
+		return gbrDl;
+	}
+
+	public void setGbrUl(BitRate gbrUl) {
+		this.gbrUl = gbrUl;
+	}
+
+	public BitRate getGbrUl() {
+		return gbrUl;
+	}
+
+	public void setMbrDl(BitRate mbrDl) {
+		this.mbrDl = mbrDl;
+	}
+
+	public BitRate getMbrDl() {
+		return mbrDl;
+	}
+
+	public void setMbrUl(BitRate mbrUl) {
+		this.mbrUl = mbrUl;
+	}
+
+	public BitRate getMbrUl() {
+		return mbrUl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += mbrUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 8
+		os.write(0x88);
+		codeLength += 1;
+		
+		codeLength += mbrDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 7
+		os.write(0x87);
+		codeLength += 1;
+		
+		codeLength += gbrUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 6
+		os.write(0x86);
+		codeLength += 1;
+		
+		codeLength += gbrDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 5
+		os.write(0x85);
+		codeLength += 1;
+		
+		codeLength += arp.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 4
+		os.write(0x84);
+		codeLength += 1;
+		
+		codeLength += qci.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += type.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += direction.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += id.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			id = new ERABID();
+			subCodeLength += id.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			direction = new ERABDirection();
+			subCodeLength += direction.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			type = new ERABType();
+			subCodeLength += type.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			qci = new QCI();
+			subCodeLength += qci.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+			arp = new BerInteger();
+			subCodeLength += arp.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
+			gbrDl = new BitRate();
+			subCodeLength += gbrDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 6)) {
+			gbrUl = new BitRate();
+			subCodeLength += gbrUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 7)) {
+			mbrDl = new BitRate();
+			subCodeLength += mbrDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 8)) {
+			mbrUl = new BitRate();
+			subCodeLength += mbrUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (id != null) {
+			sb.append("\"id\": ").append(id);
+		}
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (direction != null) {
+			sb.append("\"direction\": ").append(direction);
+		}
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (type != null) {
+			sb.append("\"type\": ").append(type);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (qci != null) {
+			sb.append("\"qci\": ").append(qci);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (arp != null) {
+			sb.append("\"arp\": ").append(arp);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (gbrDl != null) {
+			sb.append("\"gbrDl\": ").append(gbrDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (gbrUl != null) {
+			sb.append("\"gbrUl\": ").append(gbrUl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (mbrDl != null) {
+			sb.append("\"mbrDl\": ").append(mbrDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (mbrUl != null) {
+			sb.append("\"mbrUl\": ").append(mbrUl);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABResponse.java b/src/main/java/org.onosproject.xran/codecs/api/ERABResponse.java
new file mode 100644
index 0000000..fdf66fa
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABResponse.java
@@ -0,0 +1,150 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABResponse implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+	public byte[] code = null;
+	private List<ERABResponseItem> seqOf = null;
+
+	public ERABResponse() {
+		seqOf = new ArrayList<ERABResponseItem>();
+	}
+
+	public ERABResponse(byte[] code) {
+		this.code = code;
+	}
+
+	public List<ERABResponseItem> getERABResponseItem() {
+		if (seqOf == null) {
+			seqOf = new ArrayList<ERABResponseItem>();
+		}
+		return seqOf;
+	}
+
+	public void setERABResponse(ERABResponseItem erabResponseItem) {
+		seqOf.add(erabResponseItem);
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		for (int i = (seqOf.size() - 1); i >= 0; i--) {
+			codeLength += seqOf.get(i).encode(os, true);
+		}
+
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+		int totalLength = length.val;
+
+		while (subCodeLength < totalLength) {
+			ERABResponseItem element = new ERABResponseItem();
+			subCodeLength += element.decode(is, true);
+			seqOf.add(element);
+		}
+		if (subCodeLength != totalLength) {
+			throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+		}
+		codeLength += subCodeLength;
+
+		return codeLength;
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("[\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (seqOf == null) {
+			// sb.append("null");
+		}
+		else {
+			Iterator<ERABResponseItem> it = seqOf.iterator();
+			if (it.hasNext()) {
+				it.next().appendAsString(sb, indentLevel + 1);
+				while (it.hasNext()) {
+					sb.append(",\n");
+					for (int i = 0; i < indentLevel + 1; i++) {
+						sb.append("\t");
+					}
+					it.next().appendAsString(sb, indentLevel + 1);
+				}
+			}
+		}
+
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("]");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABResponseItem.java b/src/main/java/org.onosproject.xran/codecs/api/ERABResponseItem.java
new file mode 100644
index 0000000..7608bed
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABResponseItem.java
@@ -0,0 +1,171 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABResponseItem implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ERABID id = null;
+	private ERABDecision decision = null;
+	
+	public ERABResponseItem() {
+	}
+
+	public ERABResponseItem(byte[] code) {
+		this.code = code;
+	}
+
+	public void setId(ERABID id) {
+		this.id = id;
+	}
+
+	public ERABID getId() {
+		return id;
+	}
+
+	public void setDecision(ERABDecision decision) {
+		this.decision = decision;
+	}
+
+	public ERABDecision getDecision() {
+		return decision;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += decision.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += id.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			id = new ERABID();
+			subCodeLength += id.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			decision = new ERABDecision();
+			subCodeLength += decision.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (id != null) {
+			sb.append("\"id\": ").append(id);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (decision != null) {
+			sb.append("\"decision\": ").append(decision);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ERABType.java b/src/main/java/org.onosproject.xran/codecs/api/ERABType.java
new file mode 100644
index 0000000..9f2449c
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ERABType.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ERABType extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public ERABType() {
+	}
+
+	public ERABType(byte[] code) {
+		super(code);
+	}
+
+	public ERABType(BigInteger value) {
+		super(value);
+	}
+
+	public ERABType(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/EUTRANCellIdentifier.java b/src/main/java/org.onosproject.xran/codecs/api/EUTRANCellIdentifier.java
new file mode 100644
index 0000000..7c7f2a2
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/EUTRANCellIdentifier.java
@@ -0,0 +1,45 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.*;
+
+import javax.xml.bind.DatatypeConverter;
+import java.util.Arrays;
+
+
+public class EUTRANCellIdentifier extends BerBitString {
+
+	private static final long serialVersionUID = 1L;
+
+	public EUTRANCellIdentifier() {
+	}
+
+	public EUTRANCellIdentifier(byte[] code) {
+		super(code);
+	}
+
+	public EUTRANCellIdentifier(byte[] value, int numBits) {
+		super(value, numBits);
+	}
+
+	@Override
+	public int hashCode() {
+		return Arrays.hashCode(value);
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof EUTRANCellIdentifier) {
+			return Arrays.equals(value, ((EUTRANCellIdentifier) obj).value);
+		}
+		return super.equals(obj);
+	}
+
+	@Override
+	public String toString() {
+		return "\"" + DatatypeConverter.printHexBinary(value) + "\"";
+	}
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/HOFailureCause.java b/src/main/java/org.onosproject.xran/codecs/api/HOFailureCause.java
new file mode 100644
index 0000000..67be0de
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/HOFailureCause.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class HOFailureCause extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public HOFailureCause() {
+	}
+
+	public HOFailureCause(byte[] code) {
+		super(code);
+	}
+
+	public HOFailureCause(BigInteger value) {
+		super(value);
+	}
+
+	public HOFailureCause(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/MMEUES1APID.java b/src/main/java/org.onosproject.xran/codecs/api/MMEUES1APID.java
new file mode 100644
index 0000000..4967941
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/MMEUES1APID.java
@@ -0,0 +1,54 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import java.util.Objects;
+
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class MMEUES1APID extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public MMEUES1APID() {
+	}
+
+	public MMEUES1APID(byte[] code) {
+		super(code);
+	}
+
+	public MMEUES1APID(BigInteger value) {
+		super(value);
+	}
+
+	public MMEUES1APID(long value) {
+		super(value);
+	}
+
+	@Override
+	public int hashCode() {
+		return value.hashCode();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof MMEUES1APID) {
+			return Objects.equals(value, ((MMEUES1APID) obj).value);
+		}
+		return super.equals(obj);
+	}
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/PCIARFCN.java b/src/main/java/org.onosproject.xran/codecs/api/PCIARFCN.java
new file mode 100644
index 0000000..e3bd88f
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/PCIARFCN.java
@@ -0,0 +1,181 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class PCIARFCN implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PhysCellId pci = null;
+	private ARFCNValue earfcnDl = null;
+	
+	public PCIARFCN() {
+	}
+
+	public PCIARFCN(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPci(PhysCellId pci) {
+		this.pci = pci;
+	}
+
+	public PhysCellId getPci() {
+		return pci;
+	}
+
+	public void setEarfcnDl(ARFCNValue earfcnDl) {
+		this.earfcnDl = earfcnDl;
+	}
+
+	public ARFCNValue getEarfcnDl() {
+		return earfcnDl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += earfcnDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += pci.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			pci = new PhysCellId();
+			subCodeLength += pci.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			earfcnDl = new ARFCNValue();
+			subCodeLength += earfcnDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pci != null) {
+			sb.append("\"pci\": ").append(pci);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (earfcnDl != null) {
+			sb.append("\"earfcnDl\": ").append(earfcnDl);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+	@Override
+	public boolean equals(Object o) {
+		if (o instanceof PCIARFCN) {
+			return pci.equals(((PCIARFCN) o).getPci()) && earfcnDl.equals(((PCIARFCN) o).getEarfcnDl());
+		}
+
+		return super.equals(o);
+	}
+
+	@Override
+	public int hashCode() {
+		int result = pci.hashCode();
+		result = 31 * result + earfcnDl.hashCode();
+		return result;
+	}
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/PLMNIdentity.java b/src/main/java/org.onosproject.xran/codecs/api/PLMNIdentity.java
new file mode 100644
index 0000000..5fe0d69
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/PLMNIdentity.java
@@ -0,0 +1,21 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerOctetString;
+
+
+public class PLMNIdentity extends BerOctetString {
+
+	private static final long serialVersionUID = 1L;
+
+	public PLMNIdentity() {
+	}
+
+	public PLMNIdentity(byte[] value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/PRBUsage.java b/src/main/java/org.onosproject.xran/codecs/api/PRBUsage.java
new file mode 100644
index 0000000..a36141c
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/PRBUsage.java
@@ -0,0 +1,431 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class PRBUsage implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class PrbUsageDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PrbUsageDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PrbUsageDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class PrbUsageUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PrbUsageUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PrbUsageUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PrbUsageDl prbUsageDl = null;
+	private PrbUsageUl prbUsageUl = null;
+	
+	public PRBUsage() {
+	}
+
+	public PRBUsage(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPrbUsageDl(PrbUsageDl prbUsageDl) {
+		this.prbUsageDl = prbUsageDl;
+	}
+
+	public PrbUsageDl getPrbUsageDl() {
+		return prbUsageDl;
+	}
+
+	public void setPrbUsageUl(PrbUsageUl prbUsageUl) {
+		this.prbUsageUl = prbUsageUl;
+	}
+
+	public PrbUsageUl getPrbUsageUl() {
+		return prbUsageUl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += prbUsageUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += prbUsageDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			prbUsageDl = new PrbUsageDl();
+			subCodeLength += prbUsageDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			prbUsageUl = new PrbUsageUl();
+			subCodeLength += prbUsageUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (prbUsageDl != null) {
+			sb.append("\"prbUsageDl\": ");
+			prbUsageDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (prbUsageUl != null) {
+			sb.append("\"prbUsageUl\": ");
+			prbUsageUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/PhysCellId.java b/src/main/java/org.onosproject.xran/codecs/api/PhysCellId.java
new file mode 100644
index 0000000..e05df5b
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/PhysCellId.java
@@ -0,0 +1,43 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class PhysCellId extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public PhysCellId() {
+	}
+
+	public PhysCellId(byte[] code) {
+		super(code);
+	}
+
+	public PhysCellId(BigInteger value) {
+		super(value);
+	}
+
+	public PhysCellId(long value) {
+		super(value);
+	}
+
+	@Override
+	public int hashCode() {
+		return value.intValue();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof PhysCellId) {
+			return value.intValue() == ((PhysCellId) obj).value.intValue();
+		}
+		return super.equals(obj);
+	}
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/PropScell.java b/src/main/java/org.onosproject.xran/codecs/api/PropScell.java
new file mode 100644
index 0000000..9d473be
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/PropScell.java
@@ -0,0 +1,244 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerBoolean;
+import org.openmuc.jasn1.ber.types.BerEnum;
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class PropScell implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PCIARFCN pciArfcn = null;
+	private BerBoolean crossCarrierSchedEnable = null;
+	private BerEnum caDirection = null;
+	private BerInteger deactTimer = null;
+	
+	public PropScell() {
+	}
+
+	public PropScell(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPciArfcn(PCIARFCN pciArfcn) {
+		this.pciArfcn = pciArfcn;
+	}
+
+	public PCIARFCN getPciArfcn() {
+		return pciArfcn;
+	}
+
+	public void setCrossCarrierSchedEnable(BerBoolean crossCarrierSchedEnable) {
+		this.crossCarrierSchedEnable = crossCarrierSchedEnable;
+	}
+
+	public BerBoolean getCrossCarrierSchedEnable() {
+		return crossCarrierSchedEnable;
+	}
+
+	public void setCaDirection(BerEnum caDirection) {
+		this.caDirection = caDirection;
+	}
+
+	public BerEnum getCaDirection() {
+		return caDirection;
+	}
+
+	public void setDeactTimer(BerInteger deactTimer) {
+		this.deactTimer = deactTimer;
+	}
+
+	public BerInteger getDeactTimer() {
+		return deactTimer;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += deactTimer.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += caDirection.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += crossCarrierSchedEnable.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += pciArfcn.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			pciArfcn = new PCIARFCN();
+			subCodeLength += pciArfcn.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			crossCarrierSchedEnable = new BerBoolean();
+			subCodeLength += crossCarrierSchedEnable.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			caDirection = new BerEnum();
+			subCodeLength += caDirection.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			deactTimer = new BerInteger();
+			subCodeLength += deactTimer.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pciArfcn != null) {
+			sb.append("pciArfcn: ");
+			pciArfcn.appendAsString(sb, indentLevel + 1);
+		}
+		else {
+			sb.append("pciArfcn: <empty-required-field>");
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crossCarrierSchedEnable != null) {
+			sb.append("crossCarrierSchedEnable: ").append(crossCarrierSchedEnable);
+		}
+		else {
+			sb.append("crossCarrierSchedEnable: <empty-required-field>");
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (caDirection != null) {
+			sb.append("caDirection: ").append(caDirection);
+		}
+		else {
+			sb.append("caDirection: <empty-required-field>");
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (deactTimer != null) {
+			sb.append("deactTimer: ").append(deactTimer);
+		}
+		else {
+			sb.append("deactTimer: <empty-required-field>");
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/QCI.java b/src/main/java/org.onosproject.xran/codecs/api/QCI.java
new file mode 100644
index 0000000..adee94e
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/QCI.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class QCI extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public QCI() {
+	}
+
+	public QCI(byte[] code) {
+		super(code);
+	}
+
+	public QCI(BigInteger value) {
+		super(value);
+	}
+
+	public QCI(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/RSRPRange.java b/src/main/java/org.onosproject.xran/codecs/api/RSRPRange.java
new file mode 100644
index 0000000..592f41e
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/RSRPRange.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class RSRPRange extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public RSRPRange() {
+	}
+
+	public RSRPRange(byte[] code) {
+		super(code);
+	}
+
+	public RSRPRange(BigInteger value) {
+		super(value);
+	}
+
+	public RSRPRange(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/RSRQRange.java b/src/main/java/org.onosproject.xran/codecs/api/RSRQRange.java
new file mode 100644
index 0000000..4d74e85
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/RSRQRange.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class RSRQRange extends BerInteger {
+
+	private static final long serialVersionUID = 1L;
+
+	public RSRQRange() {
+	}
+
+	public RSRQRange(byte[] code) {
+		super(code);
+	}
+
+	public RSRQRange(BigInteger value) {
+		super(value);
+	}
+
+	public RSRQRange(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/RXSigMeasRepInterval.java b/src/main/java/org.onosproject.xran/codecs/api/RXSigMeasRepInterval.java
new file mode 100644
index 0000000..8ce29aa
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/RXSigMeasRepInterval.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class RXSigMeasRepInterval extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public RXSigMeasRepInterval() {
+	}
+
+	public RXSigMeasRepInterval(byte[] code) {
+		super(code);
+	}
+
+	public RXSigMeasRepInterval(BigInteger value) {
+		super(value);
+	}
+
+	public RXSigMeasRepInterval(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/RXSigRepQty.java b/src/main/java/org.onosproject.xran/codecs/api/RXSigRepQty.java
new file mode 100644
index 0000000..8794f09
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/RXSigRepQty.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class RXSigRepQty extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public RXSigRepQty() {
+	}
+
+	public RXSigRepQty(byte[] code) {
+		super(code);
+	}
+
+	public RXSigRepQty(BigInteger value) {
+		super(value);
+	}
+
+	public RXSigRepQty(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/RXSigReport.java b/src/main/java/org.onosproject.xran/codecs/api/RXSigReport.java
new file mode 100644
index 0000000..f07dd09
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/RXSigReport.java
@@ -0,0 +1,202 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class RXSigReport implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PCIARFCN pciArfcn = null;
+	private RSRPRange rsrp = null;
+	private RSRQRange rsrq = null;
+	
+	public RXSigReport() {
+	}
+
+	public RXSigReport(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPciArfcn(PCIARFCN pciArfcn) {
+		this.pciArfcn = pciArfcn;
+	}
+
+	public PCIARFCN getPciArfcn() {
+		return pciArfcn;
+	}
+
+	public void setRsrp(RSRPRange rsrp) {
+		this.rsrp = rsrp;
+	}
+
+	public RSRPRange getRsrp() {
+		return rsrp;
+	}
+
+	public void setRsrq(RSRQRange rsrq) {
+		this.rsrq = rsrq;
+	}
+
+	public RSRQRange getRsrq() {
+		return rsrq;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += rsrq.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += rsrp.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += pciArfcn.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			pciArfcn = new PCIARFCN();
+			subCodeLength += pciArfcn.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			rsrp = new RSRPRange();
+			subCodeLength += rsrp.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			rsrq = new RSRQRange();
+			subCodeLength += rsrq.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pciArfcn != null) {
+			sb.append("\"pciArfcn\": ");
+			pciArfcn.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (rsrp != null) {
+			sb.append("\"rsrp\": ").append(rsrp);
+		}
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (rsrq != null) {
+			sb.append("\"rsrq\": ").append(rsrq);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/RadioRepPerServCell.java b/src/main/java/org.onosproject.xran/codecs/api/RadioRepPerServCell.java
new file mode 100644
index 0000000..525fb0a
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/RadioRepPerServCell.java
@@ -0,0 +1,790 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class RadioRepPerServCell implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class CqiHist implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public CqiHist() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public CqiHist(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class RiHist implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public RiHist() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public RiHist(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class PuschSinrHist implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PuschSinrHist() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PuschSinrHist(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class PucchSinrHist implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PucchSinrHist() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PucchSinrHist(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PCIARFCN pciArfcn = null;
+	private CqiHist cqiHist = null;
+	private RiHist riHist = null;
+	private PuschSinrHist puschSinrHist = null;
+	private PucchSinrHist pucchSinrHist = null;
+	
+	public RadioRepPerServCell() {
+	}
+
+	public RadioRepPerServCell(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPciArfcn(PCIARFCN pciArfcn) {
+		this.pciArfcn = pciArfcn;
+	}
+
+	public PCIARFCN getPciArfcn() {
+		return pciArfcn;
+	}
+
+	public void setCqiHist(CqiHist cqiHist) {
+		this.cqiHist = cqiHist;
+	}
+
+	public CqiHist getCqiHist() {
+		return cqiHist;
+	}
+
+	public void setRiHist(RiHist riHist) {
+		this.riHist = riHist;
+	}
+
+	public RiHist getRiHist() {
+		return riHist;
+	}
+
+	public void setPuschSinrHist(PuschSinrHist puschSinrHist) {
+		this.puschSinrHist = puschSinrHist;
+	}
+
+	public PuschSinrHist getPuschSinrHist() {
+		return puschSinrHist;
+	}
+
+	public void setPucchSinrHist(PucchSinrHist pucchSinrHist) {
+		this.pucchSinrHist = pucchSinrHist;
+	}
+
+	public PucchSinrHist getPucchSinrHist() {
+		return pucchSinrHist;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += pucchSinrHist.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+		os.write(0xA4);
+		codeLength += 1;
+		
+		codeLength += puschSinrHist.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += riHist.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += cqiHist.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += pciArfcn.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			pciArfcn = new PCIARFCN();
+			subCodeLength += pciArfcn.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			cqiHist = new CqiHist();
+			subCodeLength += cqiHist.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			riHist = new RiHist();
+			subCodeLength += riHist.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			puschSinrHist = new PuschSinrHist();
+			subCodeLength += puschSinrHist.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+			pucchSinrHist = new PucchSinrHist();
+			subCodeLength += pucchSinrHist.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pciArfcn != null) {
+			sb.append("\"pciArfcn\": ");
+			pciArfcn.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (cqiHist != null) {
+			sb.append("\"cqiHist\": ");
+			cqiHist.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (riHist != null) {
+			sb.append("\"riHist\": ");
+			riHist.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (puschSinrHist != null) {
+			sb.append("\"puschSinrHist\": ");
+			puschSinrHist.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pucchSinrHist != null) {
+			sb.append("\"pucchSinrHist\": ");
+			pucchSinrHist.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/ReconfIndReason.java b/src/main/java/org.onosproject.xran/codecs/api/ReconfIndReason.java
new file mode 100644
index 0000000..6ab2221
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/ReconfIndReason.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class ReconfIndReason extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public ReconfIndReason() {
+	}
+
+	public ReconfIndReason(byte[] code) {
+		super(code);
+	}
+
+	public ReconfIndReason(BigInteger value) {
+		super(value);
+	}
+
+	public ReconfIndReason(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/RelCause.java b/src/main/java/org.onosproject.xran/codecs/api/RelCause.java
new file mode 100644
index 0000000..c983d06
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/RelCause.java
@@ -0,0 +1,40 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class RelCause extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public RelCause() {
+	}
+
+	public RelCause(byte[] code) {
+		super(code);
+	}
+
+	public RelCause(BigInteger value) {
+		super(value);
+	}
+
+	public RelCause(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/SchedMeasRepPerServCell.java b/src/main/java/org.onosproject.xran/codecs/api/SchedMeasRepPerServCell.java
new file mode 100644
index 0000000..a2ed8fb
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/SchedMeasRepPerServCell.java
@@ -0,0 +1,1307 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class SchedMeasRepPerServCell implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class QciVals implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<QCI> seqOf = null;
+
+		public QciVals() {
+			seqOf = new ArrayList<QCI>();
+		}
+
+		public QciVals(byte[] code) {
+			this.code = code;
+		}
+
+		public List<QCI> getQCI() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<QCI>();
+			}
+			return seqOf;
+		}
+
+		public void setQCI(QCI qci) {
+			seqOf.add(qci);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				QCI element = new QCI();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<QCI> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class McsDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public McsDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public McsDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class NumSchedTtisDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public NumSchedTtisDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public NumSchedTtisDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class McsUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public McsUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public McsUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class NumSchedTtisUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public NumSchedTtisUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public NumSchedTtisUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class RankDl1 implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public RankDl1() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public RankDl1(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class RankDl2 implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public RankDl2() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public RankDl2(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private PCIARFCN pciArfcn = null;
+	private QciVals qciVals = null;
+	private PRBUsage prbUsage = null;
+	private McsDl mcsDl = null;
+	private NumSchedTtisDl numSchedTtisDl = null;
+	private McsUl mcsUl = null;
+	private NumSchedTtisUl numSchedTtisUl = null;
+	private RankDl1 rankDl1 = null;
+	private RankDl2 rankDl2 = null;
+	
+	public SchedMeasRepPerServCell() {
+	}
+
+	public SchedMeasRepPerServCell(byte[] code) {
+		this.code = code;
+	}
+
+	public void setPciArfcn(PCIARFCN pciArfcn) {
+		this.pciArfcn = pciArfcn;
+	}
+
+	public PCIARFCN getPciArfcn() {
+		return pciArfcn;
+	}
+
+	public void setQciVals(QciVals qciVals) {
+		this.qciVals = qciVals;
+	}
+
+	public QciVals getQciVals() {
+		return qciVals;
+	}
+
+	public void setPrbUsage(PRBUsage prbUsage) {
+		this.prbUsage = prbUsage;
+	}
+
+	public PRBUsage getPrbUsage() {
+		return prbUsage;
+	}
+
+	public void setMcsDl(McsDl mcsDl) {
+		this.mcsDl = mcsDl;
+	}
+
+	public McsDl getMcsDl() {
+		return mcsDl;
+	}
+
+	public void setNumSchedTtisDl(NumSchedTtisDl numSchedTtisDl) {
+		this.numSchedTtisDl = numSchedTtisDl;
+	}
+
+	public NumSchedTtisDl getNumSchedTtisDl() {
+		return numSchedTtisDl;
+	}
+
+	public void setMcsUl(McsUl mcsUl) {
+		this.mcsUl = mcsUl;
+	}
+
+	public McsUl getMcsUl() {
+		return mcsUl;
+	}
+
+	public void setNumSchedTtisUl(NumSchedTtisUl numSchedTtisUl) {
+		this.numSchedTtisUl = numSchedTtisUl;
+	}
+
+	public NumSchedTtisUl getNumSchedTtisUl() {
+		return numSchedTtisUl;
+	}
+
+	public void setRankDl1(RankDl1 rankDl1) {
+		this.rankDl1 = rankDl1;
+	}
+
+	public RankDl1 getRankDl1() {
+		return rankDl1;
+	}
+
+	public void setRankDl2(RankDl2 rankDl2) {
+		this.rankDl2 = rankDl2;
+	}
+
+	public RankDl2 getRankDl2() {
+		return rankDl2;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += rankDl2.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+		os.write(0xA8);
+		codeLength += 1;
+		
+		codeLength += rankDl1.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+		os.write(0xA7);
+		codeLength += 1;
+		
+		codeLength += numSchedTtisUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+		os.write(0xA6);
+		codeLength += 1;
+		
+		codeLength += mcsUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+		os.write(0xA5);
+		codeLength += 1;
+		
+		codeLength += numSchedTtisDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+		os.write(0xA4);
+		codeLength += 1;
+		
+		codeLength += mcsDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += prbUsage.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += qciVals.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += pciArfcn.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			pciArfcn = new PCIARFCN();
+			subCodeLength += pciArfcn.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			qciVals = new QciVals();
+			subCodeLength += qciVals.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			prbUsage = new PRBUsage();
+			subCodeLength += prbUsage.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			mcsDl = new McsDl();
+			subCodeLength += mcsDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+			numSchedTtisDl = new NumSchedTtisDl();
+			subCodeLength += numSchedTtisDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+			mcsUl = new McsUl();
+			subCodeLength += mcsUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+			numSchedTtisUl = new NumSchedTtisUl();
+			subCodeLength += numSchedTtisUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+			rankDl1 = new RankDl1();
+			subCodeLength += rankDl1.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+			rankDl2 = new RankDl2();
+			subCodeLength += rankDl2.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pciArfcn != null) {
+			sb.append("\"pciArfcn\": ");
+			pciArfcn.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (qciVals != null) {
+			sb.append("\"qciVals\": ");
+			qciVals.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (prbUsage != null) {
+			sb.append("\"prbUsage\": ");
+			prbUsage.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (mcsDl != null) {
+			sb.append("\"mcsDl\": ");
+			mcsDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (numSchedTtisDl != null) {
+			sb.append("\"numSchedTtisDl\": ");
+			numSchedTtisDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (mcsUl != null) {
+			sb.append("\"mcsUl\": ");
+			mcsUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (numSchedTtisUl != null) {
+			sb.append("\"numSchedTtisUl\": ");
+			numSchedTtisUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (rankDl1 != null) {
+			sb.append("\"rankDl1\": ");
+			rankDl1.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (rankDl2 != null) {
+			sb.append("\"rankDl2\": ");
+			rankDl2.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/TrafficSplitPercentage.java b/src/main/java/org.onosproject.xran/codecs/api/TrafficSplitPercentage.java
new file mode 100644
index 0000000..bf3031a
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/TrafficSplitPercentage.java
@@ -0,0 +1,210 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+public class TrafficSplitPercentage implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private BerInteger trafficPercentDl = null;
+	private BerInteger trafficPercentUl = null;
+	
+	public TrafficSplitPercentage() {
+	}
+
+	public TrafficSplitPercentage(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setTrafficPercentDl(BerInteger trafficPercentDl) {
+		this.trafficPercentDl = trafficPercentDl;
+	}
+
+	public BerInteger getTrafficPercentDl() {
+		return trafficPercentDl;
+	}
+
+	public void setTrafficPercentUl(BerInteger trafficPercentUl) {
+		this.trafficPercentUl = trafficPercentUl;
+	}
+
+	public BerInteger getTrafficPercentUl() {
+		return trafficPercentUl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		if (trafficPercentUl != null) {
+			codeLength += trafficPercentUl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+			os.write(0x82);
+			codeLength += 1;
+		}
+		
+		if (trafficPercentDl != null) {
+			codeLength += trafficPercentDl.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+			os.write(0x81);
+			codeLength += 1;
+		}
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			trafficPercentDl = new BerInteger();
+			subCodeLength += trafficPercentDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			trafficPercentUl = new BerInteger();
+			subCodeLength += trafficPercentUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (trafficPercentDl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"trafficPercentDl\": ").append(trafficPercentDl);
+		}
+		
+		if (trafficPercentUl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"trafficPercentUl\": ").append(trafficPercentUl);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/UEAMBR.java b/src/main/java/org.onosproject.xran/codecs/api/UEAMBR.java
new file mode 100644
index 0000000..eeadfa2
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/UEAMBR.java
@@ -0,0 +1,166 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class UEAMBR implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private BitRate ambrDl = null;
+	private BitRate ambrUl = null;
+	
+	public UEAMBR() {
+	}
+
+	public UEAMBR(byte[] code) {
+		this.code = code;
+	}
+
+	public void setAmbrDl(BitRate ambrDl) {
+		this.ambrDl = ambrDl;
+	}
+
+	public BitRate getAmbrDl() {
+		return ambrDl;
+	}
+
+	public void setAmbrUl(BitRate ambrUl) {
+		this.ambrUl = ambrUl;
+	}
+
+	public BitRate getAmbrUl() {
+		return ambrUl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += ambrUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ambrDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			ambrDl = new BitRate();
+			subCodeLength += ambrDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			ambrUl = new BitRate();
+			subCodeLength += ambrUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ambrDl != null) {
+			sb.append("\"ambrDl\": ").append(ambrDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ambrUl != null) {
+			sb.append("\"ambrUl\": ").append(ambrUl);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/api/XICICPA.java b/src/main/java/org.onosproject.xran/codecs/api/XICICPA.java
new file mode 100644
index 0000000..4586eac
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/XICICPA.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.api;
+
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class XICICPA extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public XICICPA() {
+	}
+
+	public XICICPA(byte[] code) {
+		super(code);
+	}
+
+	public XICICPA(BigInteger value) {
+		super(value);
+	}
+
+	public XICICPA(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/api/package-info.java b/src/main/java/org.onosproject.xran/codecs/api/package-info.java
new file mode 100644
index 0000000..e3949c9
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/api/package-info.java
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.codecs.api;
\ No newline at end of file
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionRequest.java b/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionRequest.java
new file mode 100644
index 0000000..7f86f7c
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionRequest.java
@@ -0,0 +1,266 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.ERABParams;
+import org.onosproject.xran.codecs.api.UEAMBR;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BearerAdmissionRequest implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private UEAMBR ueAmbr = null;
+	private BerInteger numErabs = null;
+	private ERABParams erabParams = null;
+	
+	public BearerAdmissionRequest() {
+	}
+
+	public BearerAdmissionRequest(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setUeAmbr(UEAMBR ueAmbr) {
+		this.ueAmbr = ueAmbr;
+	}
+
+	public UEAMBR getUeAmbr() {
+		return ueAmbr;
+	}
+
+	public void setNumErabs(BerInteger numErabs) {
+		this.numErabs = numErabs;
+	}
+
+	public BerInteger getNumErabs() {
+		return numErabs;
+	}
+
+	public void setErabParams(ERABParams erabParams) {
+		this.erabParams = erabParams;
+	}
+
+	public ERABParams getErabParams() {
+		return erabParams;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += erabParams.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+		os.write(0xA4);
+		codeLength += 1;
+		
+		codeLength += numErabs.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += ueAmbr.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			ueAmbr = new UEAMBR();
+			subCodeLength += ueAmbr.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			numErabs = new BerInteger();
+			subCodeLength += numErabs.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+			erabParams = new ERABParams();
+			subCodeLength += erabParams.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ueAmbr != null) {
+			sb.append("\"ueAmbr\": ");
+			ueAmbr.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (numErabs != null) {
+			sb.append("\"numErabs\": ").append(numErabs);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (erabParams != null) {
+			sb.append("\"erabParams\": ");
+			erabParams.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionResponse.java b/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionResponse.java
new file mode 100644
index 0000000..8f6ad01
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionResponse.java
@@ -0,0 +1,233 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.ERABResponse;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BearerAdmissionResponse implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private BerInteger numErabList = null;
+	private ERABResponse erabResponse = null;
+	
+	public BearerAdmissionResponse() {
+	}
+
+	public BearerAdmissionResponse(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setNumErabList(BerInteger numErabList) {
+		this.numErabList = numErabList;
+	}
+
+	public BerInteger getNumErabList() {
+		return numErabList;
+	}
+
+	public void setErabResponse(ERABResponse erabResponse) {
+		this.erabResponse = erabResponse;
+	}
+
+	public ERABResponse getErabResponse() {
+		return erabResponse;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += erabResponse.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += numErabList.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			numErabList = new BerInteger();
+			subCodeLength += numErabList.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			erabResponse = new ERABResponse();
+			subCodeLength += erabResponse.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (numErabList != null) {
+			sb.append("\"numErabList\": ").append(numErabList);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (erabResponse != null) {
+			sb.append("\"erabResponse\": ");
+			erabResponse.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionStatus.java b/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionStatus.java
new file mode 100644
index 0000000..16e85e1
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/BearerAdmissionStatus.java
@@ -0,0 +1,233 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.ERABResponse;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BearerAdmissionStatus implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private BerInteger numErabs = null;
+	private ERABResponse erabResponse = null;
+	
+	public BearerAdmissionStatus() {
+	}
+
+	public BearerAdmissionStatus(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setNumErabs(BerInteger numErabs) {
+		this.numErabs = numErabs;
+	}
+
+	public BerInteger getNumErabs() {
+		return numErabs;
+	}
+
+	public void setErabResponse(ERABResponse erabResponse) {
+		this.erabResponse = erabResponse;
+	}
+
+	public ERABResponse getErabResponse() {
+		return erabResponse;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += erabResponse.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += numErabs.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			numErabs = new BerInteger();
+			subCodeLength += numErabs.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			erabResponse = new ERABResponse();
+			subCodeLength += erabResponse.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (numErabs != null) {
+			sb.append("\"numErabs\": ").append(numErabs);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (erabResponse != null) {
+			sb.append("\"erabResponse\": ");
+			erabResponse.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/BearerReleaseInd.java b/src/main/java/org.onosproject.xran/codecs/pdu/BearerReleaseInd.java
new file mode 100644
index 0000000..89cfa2d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/BearerReleaseInd.java
@@ -0,0 +1,362 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.ERABID;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class BearerReleaseInd implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class ErabIds implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<ERABID> seqOf = null;
+
+		public ErabIds() {
+			seqOf = new ArrayList<ERABID>();
+		}
+
+		public ErabIds(byte[] code) {
+			this.code = code;
+		}
+
+		public List<ERABID> getERABID() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<ERABID>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				ERABID element = new ERABID();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<ERABID> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private BerInteger numErabs = null;
+	private ErabIds erabIds = null;
+	
+	public BearerReleaseInd() {
+	}
+
+	public BearerReleaseInd(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setNumErabs(BerInteger numErabs) {
+		this.numErabs = numErabs;
+	}
+
+	public BerInteger getNumErabs() {
+		return numErabs;
+	}
+
+	public void setErabIds(ErabIds erabIds) {
+		this.erabIds = erabIds;
+	}
+
+	public ErabIds getErabIds() {
+		return erabIds;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += erabIds.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += numErabs.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			numErabs = new BerInteger();
+			subCodeLength += numErabs.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			erabIds = new ErabIds();
+			subCodeLength += erabIds.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (numErabs != null) {
+			sb.append("\"numErabs\": ").append(numErabs);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (erabIds != null) {
+			sb.append("\"erabIds\": ");
+			erabIds.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/CellConfigReport.java b/src/main/java/org.onosproject.xran/codecs/pdu/CellConfigReport.java
new file mode 100644
index 0000000..c858d2e
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/CellConfigReport.java
@@ -0,0 +1,735 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerBoolean;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import org.onosproject.xran.codecs.api.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class CellConfigReport implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class CandScells implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<CandScell> seqOf = null;
+
+		public CandScells() {
+			seqOf = new ArrayList<CandScell>();
+		}
+
+		public CandScells(byte[] code) {
+			this.code = code;
+		}
+
+		public List<CandScell> getCandScells() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<CandScell>();
+			}
+			return seqOf;
+		}
+
+		public void setCandScells(CandScell candScell) {
+			seqOf.add(candScell);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				CandScell element = new CandScell();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<CandScell> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private PhysCellId pci = null;
+	private CandScells candScells = null;
+	private ARFCNValue earfcnDl = null;
+	private ARFCNValue earfcnUl = null;
+	private BerInteger rbsPerTtiDl = null;
+	private BerInteger rbsPerTtiUl = null;
+	private BerInteger numTxAntenna = null;
+	private DuplexMode duplexMode = null;
+	private BerInteger tddConfig = null;
+	private BerInteger tddSplSfConfig = null;
+	private BerInteger maxNumConnectedUes = null;
+	private BerInteger maxNumConnectedBearers = null;
+	private BerInteger maxNumUesSchedPerTtiDl = null;
+	private BerInteger maxNumUesSchedPerTtiUl = null;
+	private BerBoolean dlfsSchedEnable = null;
+	
+	public CellConfigReport() {
+	}
+
+	public CellConfigReport(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setPci(PhysCellId pci) {
+		this.pci = pci;
+	}
+
+	public PhysCellId getPci() {
+		return pci;
+	}
+
+	public void setCandScells(CandScells candScells) {
+		this.candScells = candScells;
+	}
+
+	public CandScells getCandScells() {
+		return candScells;
+	}
+
+	public void setEarfcnDl(ARFCNValue earfcnDl) {
+		this.earfcnDl = earfcnDl;
+	}
+
+	public ARFCNValue getEarfcnDl() {
+		return earfcnDl;
+	}
+
+	public void setEarfcnUl(ARFCNValue earfcnUl) {
+		this.earfcnUl = earfcnUl;
+	}
+
+	public ARFCNValue getEarfcnUl() {
+		return earfcnUl;
+	}
+
+	public void setRbsPerTtiDl(BerInteger rbsPerTtiDl) {
+		this.rbsPerTtiDl = rbsPerTtiDl;
+	}
+
+	public BerInteger getRbsPerTtiDl() {
+		return rbsPerTtiDl;
+	}
+
+	public void setRbsPerTtiUl(BerInteger rbsPerTtiUl) {
+		this.rbsPerTtiUl = rbsPerTtiUl;
+	}
+
+	public BerInteger getRbsPerTtiUl() {
+		return rbsPerTtiUl;
+	}
+
+	public void setNumTxAntenna(BerInteger numTxAntenna) {
+		this.numTxAntenna = numTxAntenna;
+	}
+
+	public BerInteger getNumTxAntenna() {
+		return numTxAntenna;
+	}
+
+	public void setDuplexMode(DuplexMode duplexMode) {
+		this.duplexMode = duplexMode;
+	}
+
+	public DuplexMode getDuplexMode() {
+		return duplexMode;
+	}
+
+	public void setTddConfig(BerInteger tddConfig) {
+		this.tddConfig = tddConfig;
+	}
+
+	public BerInteger getTddConfig() {
+		return tddConfig;
+	}
+
+	public void setTddSplSfConfig(BerInteger tddSplSfConfig) {
+		this.tddSplSfConfig = tddSplSfConfig;
+	}
+
+	public BerInteger getTddSplSfConfig() {
+		return tddSplSfConfig;
+	}
+
+	public void setMaxNumConnectedUes(BerInteger maxNumConnectedUes) {
+		this.maxNumConnectedUes = maxNumConnectedUes;
+	}
+
+	public BerInteger getMaxNumConnectedUes() {
+		return maxNumConnectedUes;
+	}
+
+	public void setMaxNumConnectedBearers(BerInteger maxNumConnectedBearers) {
+		this.maxNumConnectedBearers = maxNumConnectedBearers;
+	}
+
+	public BerInteger getMaxNumConnectedBearers() {
+		return maxNumConnectedBearers;
+	}
+
+	public void setMaxNumUesSchedPerTtiDl(BerInteger maxNumUesSchedPerTtiDl) {
+		this.maxNumUesSchedPerTtiDl = maxNumUesSchedPerTtiDl;
+	}
+
+	public BerInteger getMaxNumUesSchedPerTtiDl() {
+		return maxNumUesSchedPerTtiDl;
+	}
+
+	public void setMaxNumUesSchedPerTtiUl(BerInteger maxNumUesSchedPerTtiUl) {
+		this.maxNumUesSchedPerTtiUl = maxNumUesSchedPerTtiUl;
+	}
+
+	public BerInteger getMaxNumUesSchedPerTtiUl() {
+		return maxNumUesSchedPerTtiUl;
+	}
+
+	public void setDlfsSchedEnable(BerBoolean dlfsSchedEnable) {
+		this.dlfsSchedEnable = dlfsSchedEnable;
+	}
+
+	public BerBoolean getDlfsSchedEnable() {
+		return dlfsSchedEnable;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += dlfsSchedEnable.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 15
+		os.write(0x8F);
+		codeLength += 1;
+		
+		codeLength += maxNumUesSchedPerTtiUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 14
+		os.write(0x8E);
+		codeLength += 1;
+		
+		codeLength += maxNumUesSchedPerTtiDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 13
+		os.write(0x8D);
+		codeLength += 1;
+		
+		codeLength += maxNumConnectedBearers.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 12
+		os.write(0x8C);
+		codeLength += 1;
+		
+		codeLength += maxNumConnectedUes.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 11
+		os.write(0x8B);
+		codeLength += 1;
+		
+		if (tddSplSfConfig != null) {
+			codeLength += tddSplSfConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 10
+			os.write(0x8A);
+			codeLength += 1;
+		}
+		
+		if (tddConfig != null) {
+			codeLength += tddConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, PRIMITIVE, 9
+			os.write(0x89);
+			codeLength += 1;
+		}
+		
+		codeLength += duplexMode.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 8
+		os.write(0x88);
+		codeLength += 1;
+		
+		codeLength += numTxAntenna.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 7
+		os.write(0x87);
+		codeLength += 1;
+		
+		codeLength += rbsPerTtiUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 6
+		os.write(0x86);
+		codeLength += 1;
+		
+		codeLength += rbsPerTtiDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 5
+		os.write(0x85);
+		codeLength += 1;
+		
+		codeLength += earfcnUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 4
+		os.write(0x84);
+		codeLength += 1;
+		
+		codeLength += earfcnDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += candScells.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += pci.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			pci = new PhysCellId();
+			subCodeLength += pci.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			candScells = new CandScells();
+			subCodeLength += candScells.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			earfcnDl = new ARFCNValue();
+			subCodeLength += earfcnDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+			earfcnUl = new ARFCNValue();
+			subCodeLength += earfcnUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
+			rbsPerTtiDl = new BerInteger();
+			subCodeLength += rbsPerTtiDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 6)) {
+			rbsPerTtiUl = new BerInteger();
+			subCodeLength += rbsPerTtiUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 7)) {
+			numTxAntenna = new BerInteger();
+			subCodeLength += numTxAntenna.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 8)) {
+			duplexMode = new DuplexMode();
+			subCodeLength += duplexMode.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 9)) {
+			tddConfig = new BerInteger();
+			subCodeLength += tddConfig.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 10)) {
+			tddSplSfConfig = new BerInteger();
+			subCodeLength += tddSplSfConfig.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 11)) {
+			maxNumConnectedUes = new BerInteger();
+			subCodeLength += maxNumConnectedUes.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 12)) {
+			maxNumConnectedBearers = new BerInteger();
+			subCodeLength += maxNumConnectedBearers.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 13)) {
+			maxNumUesSchedPerTtiDl = new BerInteger();
+			subCodeLength += maxNumUesSchedPerTtiDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 14)) {
+			maxNumUesSchedPerTtiUl = new BerInteger();
+			subCodeLength += maxNumUesSchedPerTtiUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 15)) {
+			dlfsSchedEnable = new BerBoolean();
+			subCodeLength += dlfsSchedEnable.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pci != null) {
+			sb.append("\"pci\": ").append(pci);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (candScells != null) {
+			sb.append("\"candScells\": ");
+			candScells.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (earfcnDl != null) {
+			sb.append("\"earfcnDl\": ").append(earfcnDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (earfcnUl != null) {
+			sb.append("\"earfcnUl\": ").append(earfcnUl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (rbsPerTtiDl != null) {
+			sb.append("\"rbsPerTtiDl\": ").append(rbsPerTtiDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (rbsPerTtiUl != null) {
+			sb.append("\"rbsPerTtiUl\": ").append(rbsPerTtiUl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (numTxAntenna != null) {
+			sb.append("\"numTxAntenna\": ").append(numTxAntenna);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (duplexMode != null) {
+			sb.append("\"duplexMode\": ").append(duplexMode);
+		}
+		
+		if (tddConfig != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"tddConfig\": ").append(tddConfig);
+		}
+		
+		if (tddSplSfConfig != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"tddSplSfConfig\": ").append(tddSplSfConfig);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (maxNumConnectedUes != null) {
+			sb.append("\"maxNumConnectedUes\": ").append(maxNumConnectedUes);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (maxNumConnectedBearers != null) {
+			sb.append("\"maxNumConnectedBearers\": ").append(maxNumConnectedBearers);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (maxNumUesSchedPerTtiDl != null) {
+			sb.append("\"maxNumUesSchedPerTtiDl\": ").append(maxNumUesSchedPerTtiDl);
+		}
+
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (maxNumUesSchedPerTtiUl != null) {
+			sb.append("\"maxNumUesSchedPerTtiUl\": ").append(maxNumUesSchedPerTtiUl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (dlfsSchedEnable != null) {
+			sb.append("\"dlfsSchedEnable\": ").append(dlfsSchedEnable);
+		}
+
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/CellConfigRequest.java b/src/main/java/org.onosproject.xran/codecs/pdu/CellConfigRequest.java
new file mode 100644
index 0000000..9aa3254
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/CellConfigRequest.java
@@ -0,0 +1,136 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.onosproject.xran.codecs.api.ECGI;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class CellConfigRequest implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	
+	public CellConfigRequest() {
+	}
+
+	public CellConfigRequest(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/HOComplete.java b/src/main/java/org.onosproject.xran/codecs/pdu/HOComplete.java
new file mode 100644
index 0000000..7a4290a
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/HOComplete.java
@@ -0,0 +1,201 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class HOComplete implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgiT = null;
+	private ECGI ecgiS = null;
+	private CRNTI crntiNew = null;
+	
+	public HOComplete() {
+	}
+
+	public HOComplete(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgiT(ECGI ecgiT) {
+		this.ecgiT = ecgiT;
+	}
+
+	public ECGI getEcgiT() {
+		return ecgiT;
+	}
+
+	public void setEcgiS(ECGI ecgiS) {
+		this.ecgiS = ecgiS;
+	}
+
+	public ECGI getEcgiS() {
+		return ecgiS;
+	}
+
+	public void setCrntiNew(CRNTI crntiNew) {
+		this.crntiNew = crntiNew;
+	}
+
+	public CRNTI getCrntiNew() {
+		return crntiNew;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += crntiNew.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgiS.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += ecgiT.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgiT = new ECGI();
+			subCodeLength += ecgiT.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgiS = new ECGI();
+			subCodeLength += ecgiS.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			crntiNew = new CRNTI();
+			subCodeLength += crntiNew.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgiT != null) {
+			sb.append("\"ecgiT\": ");
+			ecgiT.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgiS != null) {
+			sb.append("\"ecgiS\": ");
+			ecgiS.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crntiNew != null) {
+			sb.append("\"crntiNew\": ").append(crntiNew);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/HOFailure.java b/src/main/java/org.onosproject.xran/codecs/pdu/HOFailure.java
new file mode 100644
index 0000000..d0d2c90
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/HOFailure.java
@@ -0,0 +1,200 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.HOFailureCause;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class HOFailure implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private HOFailureCause cause = null;
+	
+	public HOFailure() {
+	}
+
+	public HOFailure(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCause(HOFailureCause cause) {
+		this.cause = cause;
+	}
+
+	public HOFailureCause getCause() {
+		return cause;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += cause.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			cause = new HOFailureCause();
+			subCodeLength += cause.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (cause != null) {
+			sb.append("\"cause\": ").append(cause);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/HORequest.java b/src/main/java/org.onosproject.xran/codecs/pdu/HORequest.java
new file mode 100644
index 0000000..7079944
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/HORequest.java
@@ -0,0 +1,200 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class HORequest implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgiS = null;
+	private ECGI ecgiT = null;
+	
+	public HORequest() {
+	}
+
+	public HORequest(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgiS(ECGI ecgiS) {
+		this.ecgiS = ecgiS;
+	}
+
+	public ECGI getEcgiS() {
+		return ecgiS;
+	}
+
+	public void setEcgiT(ECGI ecgiT) {
+		this.ecgiT = ecgiT;
+	}
+
+	public ECGI getEcgiT() {
+		return ecgiT;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += ecgiT.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += ecgiS.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgiS = new ECGI();
+			subCodeLength += ecgiS.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			ecgiT = new ECGI();
+			subCodeLength += ecgiT.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgiS != null) {
+			sb.append("\"ecgiS\": ");
+			ecgiS.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgiT != null) {
+			sb.append("\"ecgiT\": ");
+			ecgiT.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/L2MeasConfig.java b/src/main/java/org.onosproject.xran/codecs/pdu/L2MeasConfig.java
new file mode 100644
index 0000000..a474ec3
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/L2MeasConfig.java
@@ -0,0 +1,168 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class L2MeasConfig implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private BerInteger  reportIntervalMs = null;
+	
+	public L2MeasConfig() {
+	}
+
+	public L2MeasConfig(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setReportIntervalMs(BerInteger reportIntervalMs) {
+		this.reportIntervalMs = reportIntervalMs;
+	}
+
+	public BerInteger getReportIntervalMs() {
+		return reportIntervalMs;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += reportIntervalMs.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			reportIntervalMs = new BerInteger();
+			subCodeLength += reportIntervalMs.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (reportIntervalMs != null) {
+			sb.append("\"reportIntervalMs\": ").append(reportIntervalMs);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/PDCPMeasReportPerUe.java b/src/main/java/org.onosproject.xran/codecs/pdu/PDCPMeasReportPerUe.java
new file mode 100644
index 0000000..d272974
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/PDCPMeasReportPerUe.java
@@ -0,0 +1,1787 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import java.io.IOException;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.io.Serializable;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.QCI;
+import org.openmuc.jasn1.ber.*;
+import org.openmuc.jasn1.ber.types.*;
+import org.openmuc.jasn1.ber.types.string.*;
+
+
+
+public class PDCPMeasReportPerUe implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class QciVals implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<QCI> seqOf = null;
+
+		public QciVals() {
+			seqOf = new ArrayList<QCI>();
+		}
+
+		public QciVals(byte[] code) {
+			this.code = code;
+		}
+
+		public List<QCI> getQCI() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<QCI>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				QCI element = new QCI();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<QCI> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setQCI(QCI qci) {
+			seqOf.add(qci);
+		}
+	}
+
+	public static class DataVolDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public DataVolDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public DataVolDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class DataVolUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public DataVolUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public DataVolUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class PktDelayDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PktDelayDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PktDelayDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class PktDelayUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PktDelayUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PktDelayUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class PktDiscardRateDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PktDiscardRateDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PktDiscardRateDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class PktLossRateDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PktLossRateDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PktLossRateDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class PktLossRateUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PktLossRateUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PktLossRateUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class ThroughputDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public ThroughputDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public ThroughputDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static class ThroughputUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public ThroughputUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public ThroughputUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private CRNTI crnti = null;
+	private QciVals qciVals = null;
+	private DataVolDl dataVolDl = null;
+	private DataVolUl dataVolUl = null;
+	private PktDelayDl pktDelayDl = null;
+	private PktDelayUl pktDelayUl = null;
+	private PktDiscardRateDl pktDiscardRateDl = null;
+	private PktLossRateDl pktLossRateDl = null;
+	private PktLossRateUl pktLossRateUl = null;
+	private ThroughputDl throughputDl = null;
+	private ThroughputUl throughputUl = null;
+	
+	public PDCPMeasReportPerUe() {
+	}
+
+	public PDCPMeasReportPerUe(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setQciVals(QciVals qciVals) {
+		this.qciVals = qciVals;
+	}
+
+	public QciVals getQciVals() {
+		return qciVals;
+	}
+
+	public void setDataVolDl(DataVolDl dataVolDl) {
+		this.dataVolDl = dataVolDl;
+	}
+
+	public DataVolDl getDataVolDl() {
+		return dataVolDl;
+	}
+
+	public void setDataVolUl(DataVolUl dataVolUl) {
+		this.dataVolUl = dataVolUl;
+	}
+
+	public DataVolUl getDataVolUl() {
+		return dataVolUl;
+	}
+
+	public void setPktDelayDl(PktDelayDl pktDelayDl) {
+		this.pktDelayDl = pktDelayDl;
+	}
+
+	public PktDelayDl getPktDelayDl() {
+		return pktDelayDl;
+	}
+
+	public void setPktDelayUl(PktDelayUl pktDelayUl) {
+		this.pktDelayUl = pktDelayUl;
+	}
+
+	public PktDelayUl getPktDelayUl() {
+		return pktDelayUl;
+	}
+
+	public void setPktDiscardRateDl(PktDiscardRateDl pktDiscardRateDl) {
+		this.pktDiscardRateDl = pktDiscardRateDl;
+	}
+
+	public PktDiscardRateDl getPktDiscardRateDl() {
+		return pktDiscardRateDl;
+	}
+
+	public void setPktLossRateDl(PktLossRateDl pktLossRateDl) {
+		this.pktLossRateDl = pktLossRateDl;
+	}
+
+	public PktLossRateDl getPktLossRateDl() {
+		return pktLossRateDl;
+	}
+
+	public void setPktLossRateUl(PktLossRateUl pktLossRateUl) {
+		this.pktLossRateUl = pktLossRateUl;
+	}
+
+	public PktLossRateUl getPktLossRateUl() {
+		return pktLossRateUl;
+	}
+
+	public void setThroughputDl(ThroughputDl throughputDl) {
+		this.throughputDl = throughputDl;
+	}
+
+	public ThroughputDl getThroughputDl() {
+		return throughputDl;
+	}
+
+	public void setThroughputUl(ThroughputUl throughputUl) {
+		this.throughputUl = throughputUl;
+	}
+
+	public ThroughputUl getThroughputUl() {
+		return throughputUl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += throughputUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 11
+		os.write(0xAB);
+		codeLength += 1;
+		
+		codeLength += throughputDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 10
+		os.write(0xAA);
+		codeLength += 1;
+		
+		codeLength += pktLossRateUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 9
+		os.write(0xA9);
+		codeLength += 1;
+		
+		codeLength += pktLossRateDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+		os.write(0xA8);
+		codeLength += 1;
+		
+		codeLength += pktDiscardRateDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+		os.write(0xA7);
+		codeLength += 1;
+		
+		codeLength += pktDelayUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+		os.write(0xA6);
+		codeLength += 1;
+		
+		codeLength += pktDelayDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+		os.write(0xA5);
+		codeLength += 1;
+		
+		codeLength += dataVolUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+		os.write(0xA4);
+		codeLength += 1;
+		
+		codeLength += dataVolDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += qciVals.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			qciVals = new QciVals();
+			subCodeLength += qciVals.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			dataVolDl = new DataVolDl();
+			subCodeLength += dataVolDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+			dataVolUl = new DataVolUl();
+			subCodeLength += dataVolUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+			pktDelayDl = new PktDelayDl();
+			subCodeLength += pktDelayDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+			pktDelayUl = new PktDelayUl();
+			subCodeLength += pktDelayUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+			pktDiscardRateDl = new PktDiscardRateDl();
+			subCodeLength += pktDiscardRateDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+			pktLossRateDl = new PktLossRateDl();
+			subCodeLength += pktLossRateDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 9)) {
+			pktLossRateUl = new PktLossRateUl();
+			subCodeLength += pktLossRateUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 10)) {
+			throughputDl = new ThroughputDl();
+			subCodeLength += throughputDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 11)) {
+			throughputUl = new ThroughputUl();
+			subCodeLength += throughputUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (qciVals != null) {
+			sb.append("\"qciVals\": ");
+			qciVals.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (dataVolDl != null) {
+			sb.append("\"dataVolDl\": ");
+			dataVolDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (dataVolUl != null) {
+			sb.append("\"dataVolUl\": ");
+			dataVolUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pktDelayDl != null) {
+			sb.append("\"pktDelayDl\": ");
+			pktDelayDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pktDelayUl != null) {
+			sb.append("\"pktDelayUl\": ");
+			pktDelayUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pktDiscardRateDl != null) {
+			sb.append("\"pktDiscardRateDl\": ");
+			pktDiscardRateDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pktLossRateDl != null) {
+			sb.append("\"pktLossRateDl\": ");
+			pktLossRateDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pktLossRateUl != null) {
+			sb.append("\"pktLossRateUl\": ");
+			pktLossRateUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (throughputDl != null) {
+			sb.append("\"throughputDl\": ");
+			throughputDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (throughputUl != null) {
+			sb.append("\"throughputUl\": ");
+			throughputUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/RRMConfig.java b/src/main/java/org.onosproject.xran/codecs/pdu/RRMConfig.java
new file mode 100644
index 0000000..4de355d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/RRMConfig.java
@@ -0,0 +1,1585 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.XICICPA;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerBitString;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RRMConfig implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class Crnti implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<CRNTI> seqOf = null;
+
+		public Crnti() {
+			seqOf = new ArrayList<CRNTI>();
+		}
+
+		public Crnti(byte[] code) {
+			this.code = code;
+		}
+
+		public List<CRNTI> getCRNTI() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<CRNTI>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				CRNTI element = new CRNTI();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<CRNTI> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class Pa implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<XICICPA> seqOf = null;
+
+		public Pa() {
+			seqOf = new ArrayList<XICICPA>();
+		}
+
+		public Pa(byte[] code) {
+			this.code = code;
+		}
+
+		public List<XICICPA> getXICICPA() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<XICICPA>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				XICICPA element = new XICICPA();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<XICICPA> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class StartPrbDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public StartPrbDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public StartPrbDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class EndPrbDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public EndPrbDl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public EndPrbDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class SubframeBitmaskDl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerBitString> seqOf = null;
+
+		public SubframeBitmaskDl() {
+			seqOf = new ArrayList<BerBitString>();
+		}
+
+		public SubframeBitmaskDl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerBitString> getBerBitString() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerBitString>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerBitString element = new BerBitString();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerBitString> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class P0UePusch implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public P0UePusch() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public P0UePusch(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class StartPrbUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public StartPrbUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public StartPrbUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class EndPrbUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public EndPrbUl() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public EndPrbUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class SubframeBitmaskUl implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerBitString> seqOf = null;
+
+		public SubframeBitmaskUl() {
+			seqOf = new ArrayList<BerBitString>();
+		}
+
+		public SubframeBitmaskUl(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerBitString> getBerBitString() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerBitString>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerBitString element = new BerBitString();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerBitString> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private Crnti crnti = null;
+	private Pa pa = null;
+	private StartPrbDl startPrbDl = null;
+	private EndPrbDl endPrbDl = null;
+	private SubframeBitmaskDl subframeBitmaskDl = null;
+	private P0UePusch p0UePusch = null;
+	private StartPrbUl startPrbUl = null;
+	private EndPrbUl endPrbUl = null;
+	private SubframeBitmaskUl subframeBitmaskUl = null;
+	
+	public RRMConfig() {
+	}
+
+	public RRMConfig(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCrnti(Crnti crnti) {
+		this.crnti = crnti;
+	}
+
+	public Crnti getCrnti() {
+		return crnti;
+	}
+
+	public void setPa(Pa pa) {
+		this.pa = pa;
+	}
+
+	public Pa getPa() {
+		return pa;
+	}
+
+	public void setStartPrbDl(StartPrbDl startPrbDl) {
+		this.startPrbDl = startPrbDl;
+	}
+
+	public StartPrbDl getStartPrbDl() {
+		return startPrbDl;
+	}
+
+	public void setEndPrbDl(EndPrbDl endPrbDl) {
+		this.endPrbDl = endPrbDl;
+	}
+
+	public EndPrbDl getEndPrbDl() {
+		return endPrbDl;
+	}
+
+	public void setSubframeBitmaskDl(SubframeBitmaskDl subframeBitmaskDl) {
+		this.subframeBitmaskDl = subframeBitmaskDl;
+	}
+
+	public SubframeBitmaskDl getSubframeBitmaskDl() {
+		return subframeBitmaskDl;
+	}
+
+	public void setP0UePusch(P0UePusch p0UePusch) {
+		this.p0UePusch = p0UePusch;
+	}
+
+	public P0UePusch getP0UePusch() {
+		return p0UePusch;
+	}
+
+	public void setStartPrbUl(StartPrbUl startPrbUl) {
+		this.startPrbUl = startPrbUl;
+	}
+
+	public StartPrbUl getStartPrbUl() {
+		return startPrbUl;
+	}
+
+	public void setEndPrbUl(EndPrbUl endPrbUl) {
+		this.endPrbUl = endPrbUl;
+	}
+
+	public EndPrbUl getEndPrbUl() {
+		return endPrbUl;
+	}
+
+	public void setSubframeBitmaskUl(SubframeBitmaskUl subframeBitmaskUl) {
+		this.subframeBitmaskUl = subframeBitmaskUl;
+	}
+
+	public SubframeBitmaskUl getSubframeBitmaskUl() {
+		return subframeBitmaskUl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		if (subframeBitmaskUl != null) {
+			codeLength += subframeBitmaskUl.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 9
+			os.write(0xA9);
+			codeLength += 1;
+		}
+		
+		if (endPrbUl != null) {
+			codeLength += endPrbUl.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+			os.write(0xA8);
+			codeLength += 1;
+		}
+		
+		if (startPrbUl != null) {
+			codeLength += startPrbUl.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+			os.write(0xA7);
+			codeLength += 1;
+		}
+		
+		if (p0UePusch != null) {
+			codeLength += p0UePusch.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+			os.write(0xA6);
+			codeLength += 1;
+		}
+		
+		if (subframeBitmaskDl != null) {
+			codeLength += subframeBitmaskDl.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+			os.write(0xA5);
+			codeLength += 1;
+		}
+		
+		if (endPrbDl != null) {
+			codeLength += endPrbDl.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+			os.write(0xA4);
+			codeLength += 1;
+		}
+		
+		if (startPrbDl != null) {
+			codeLength += startPrbDl.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+			os.write(0xA3);
+			codeLength += 1;
+		}
+		
+		if (pa != null) {
+			codeLength += pa.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+			os.write(0xA2);
+			codeLength += 1;
+		}
+		
+		if (crnti != null) {
+			codeLength += crnti.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+			os.write(0xA1);
+			codeLength += 1;
+		}
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			crnti = new Crnti();
+			subCodeLength += crnti.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			pa = new Pa();
+			subCodeLength += pa.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			startPrbDl = new StartPrbDl();
+			subCodeLength += startPrbDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+			endPrbDl = new EndPrbDl();
+			subCodeLength += endPrbDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+			subframeBitmaskDl = new SubframeBitmaskDl();
+			subCodeLength += subframeBitmaskDl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+			p0UePusch = new P0UePusch();
+			subCodeLength += p0UePusch.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+			startPrbUl = new StartPrbUl();
+			subCodeLength += startPrbUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+			endPrbUl = new EndPrbUl();
+			subCodeLength += endPrbUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 9)) {
+			subframeBitmaskUl = new SubframeBitmaskUl();
+			subCodeLength += subframeBitmaskUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (crnti != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"crnti\": ");
+			crnti.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (pa != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"pa\": ");
+			pa.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (startPrbDl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"startPrbDl\": ");
+			startPrbDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (endPrbDl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"endPrbDl\": ");
+			endPrbDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (subframeBitmaskDl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"subframeBitmaskDl\": ");
+			subframeBitmaskDl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (p0UePusch != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"p0UePusch\": ");
+			p0UePusch.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (startPrbUl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"startPrbUl\": ");
+			startPrbUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (endPrbUl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"endPrbUl\": ");
+			endPrbUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (subframeBitmaskUl != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"subframeBitmaskUl\": ");
+			subframeBitmaskUl.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/RRMConfigStatus.java b/src/main/java/org.onosproject.xran/codecs/pdu/RRMConfigStatus.java
new file mode 100644
index 0000000..ab88a6d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/RRMConfigStatus.java
@@ -0,0 +1,457 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class RRMConfigStatus implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class Crnti implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<CRNTI> seqOf = null;
+
+		public Crnti() {
+			seqOf = new ArrayList<CRNTI>();
+		}
+
+		public Crnti(byte[] code) {
+			this.code = code;
+		}
+
+		public List<CRNTI> getCRNTI() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<CRNTI>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				CRNTI element = new CRNTI();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<CRNTI> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class Status implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerEnum> seqOf = null;
+
+		public Status() {
+			seqOf = new ArrayList<BerEnum>();
+		}
+
+		public Status(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerEnum> getBerEnum() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerEnum>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerEnum element = new BerEnum();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerEnum> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private Crnti crnti = null;
+	private Status status = null;
+	
+	public RRMConfigStatus() {
+	}
+
+	public RRMConfigStatus(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCrnti(Crnti crnti) {
+		this.crnti = crnti;
+	}
+
+	public Crnti getCrnti() {
+		return crnti;
+	}
+
+	public void setStatus(Status status) {
+		this.status = status;
+	}
+
+	public Status getStatus() {
+		return status;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += status.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		if (crnti != null) {
+			codeLength += crnti.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+			os.write(0xA1);
+			codeLength += 1;
+		}
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			crnti = new Crnti();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			status = new Status();
+			subCodeLength += status.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (crnti != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"crnti\": ");
+			crnti.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (status != null) {
+			sb.append("\"status\": ");
+			status.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/RXSigMeasConfig.java b/src/main/java/org.onosproject.xran/codecs/pdu/RXSigMeasConfig.java
new file mode 100644
index 0000000..c6704ce
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/RXSigMeasConfig.java
@@ -0,0 +1,393 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.*;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RXSigMeasConfig implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class MeasCells implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<PCIARFCN> seqOf = null;
+
+		public MeasCells() {
+			seqOf = new ArrayList<PCIARFCN>();
+		}
+
+		public MeasCells(byte[] code) {
+			this.code = code;
+		}
+
+		public List<PCIARFCN> getPCIARFCN() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<PCIARFCN>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				PCIARFCN element = new PCIARFCN();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<PCIARFCN> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+        public void setPCIARFCN(PCIARFCN pciarfcn) {
+			seqOf.add(pciarfcn);
+        }
+    }
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private CRNTI crnti = null;
+	private RXSigRepQty reportQty = null;
+	private MeasCells measCells = null;
+	private RXSigMeasRepInterval reportInterval = null;
+	
+	public RXSigMeasConfig() {
+	}
+
+	public RXSigMeasConfig(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setReportQty(RXSigRepQty reportQty) {
+		this.reportQty = reportQty;
+	}
+
+	public RXSigRepQty getReportQty() {
+		return reportQty;
+	}
+
+	public void setMeasCells(MeasCells measCells) {
+		this.measCells = measCells;
+	}
+
+	public MeasCells getMeasCells() {
+		return measCells;
+	}
+
+	public void setReportInterval(RXSigMeasRepInterval reportInterval) {
+		this.reportInterval = reportInterval;
+	}
+
+	public RXSigMeasRepInterval getReportInterval() {
+		return reportInterval;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += reportInterval.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 4
+		os.write(0x84);
+		codeLength += 1;
+		
+		codeLength += measCells.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += reportQty.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			reportQty = new RXSigRepQty();
+			subCodeLength += reportQty.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			measCells = new MeasCells();
+			subCodeLength += measCells.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+			reportInterval = new RXSigMeasRepInterval();
+			subCodeLength += reportInterval.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (reportQty != null) {
+			sb.append("\"reportQty\": ").append(reportQty);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (measCells != null) {
+			sb.append("\"measCells\": ");
+			measCells.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (reportInterval != null) {
+			sb.append("\"reportInterval\": ").append(reportInterval);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/RXSigMeasReport.java b/src/main/java/org.onosproject.xran/codecs/pdu/RXSigMeasReport.java
new file mode 100644
index 0000000..bee7bdd
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/RXSigMeasReport.java
@@ -0,0 +1,333 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.RXSigReport;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RXSigMeasReport implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class CellMeasReports implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<RXSigReport> seqOf = null;
+
+		public CellMeasReports() {
+			seqOf = new ArrayList<RXSigReport>();
+		}
+
+		public CellMeasReports(byte[] code) {
+			this.code = code;
+		}
+
+		public List<RXSigReport> getRXSigReport() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<RXSigReport>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				RXSigReport element = new RXSigReport();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<RXSigReport> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setRXSigReport(RXSigReport rxSigReport) {
+			seqOf.add(rxSigReport);
+		}
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private CellMeasReports cellMeasReports = null;
+	
+	public RXSigMeasReport() {
+	}
+
+	public RXSigMeasReport(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCellMeasReports(CellMeasReports cellMeasReports) {
+		this.cellMeasReports = cellMeasReports;
+	}
+
+	public CellMeasReports getCellMeasReports() {
+		return cellMeasReports;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += cellMeasReports.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			cellMeasReports = new CellMeasReports();
+			subCodeLength += cellMeasReports.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (cellMeasReports != null) {
+			sb.append("\"cellMeasReports\": ");
+			cellMeasReports.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/RadioMeasReportPerCell.java b/src/main/java/org.onosproject.xran/codecs/pdu/RadioMeasReportPerCell.java
new file mode 100644
index 0000000..ac138c6
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/RadioMeasReportPerCell.java
@@ -0,0 +1,464 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class RadioMeasReportPerCell implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class PuschIntfPowerHist implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PuschIntfPowerHist() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PuschIntfPowerHist(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class PucchIntfPowerHist implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerInteger> seqOf = null;
+
+		public PucchIntfPowerHist() {
+			seqOf = new ArrayList<BerInteger>();
+		}
+
+		public PucchIntfPowerHist(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerInteger> getBerInteger() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerInteger>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerInteger element = new BerInteger();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerInteger> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setBerInteger(BerInteger berInteger) {
+			seqOf.add(berInteger);
+		}
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private PuschIntfPowerHist puschIntfPowerHist = null;
+	private PucchIntfPowerHist pucchIntfPowerHist = null;
+	
+	public RadioMeasReportPerCell() {
+	}
+
+	public RadioMeasReportPerCell(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setPuschIntfPowerHist(PuschIntfPowerHist puschIntfPowerHist) {
+		this.puschIntfPowerHist = puschIntfPowerHist;
+	}
+
+	public PuschIntfPowerHist getPuschIntfPowerHist() {
+		return puschIntfPowerHist;
+	}
+
+	public void setPucchIntfPowerHist(PucchIntfPowerHist pucchIntfPowerHist) {
+		this.pucchIntfPowerHist = pucchIntfPowerHist;
+	}
+
+	public PucchIntfPowerHist getPucchIntfPowerHist() {
+		return pucchIntfPowerHist;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += pucchIntfPowerHist.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += puschIntfPowerHist.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			puschIntfPowerHist = new PuschIntfPowerHist();
+			subCodeLength += puschIntfPowerHist.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			pucchIntfPowerHist = new PucchIntfPowerHist();
+			subCodeLength += pucchIntfPowerHist.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (puschIntfPowerHist != null) {
+			sb.append("\"puschIntfPowerHist\": ");
+			puschIntfPowerHist.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pucchIntfPowerHist != null) {
+			sb.append("\"pucchIntfPowerHist\": ");
+			pucchIntfPowerHist.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/RadioMeasReportPerUE.java b/src/main/java/org.onosproject.xran/codecs/pdu/RadioMeasReportPerUE.java
new file mode 100644
index 0000000..15f1ea9
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/RadioMeasReportPerUE.java
@@ -0,0 +1,333 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.RadioRepPerServCell;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RadioMeasReportPerUE implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class RadioReportServCells implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<RadioRepPerServCell> seqOf = null;
+
+		public RadioReportServCells() {
+			seqOf = new ArrayList<RadioRepPerServCell>();
+		}
+
+		public RadioReportServCells(byte[] code) {
+			this.code = code;
+		}
+
+		public List<RadioRepPerServCell> getRadioRepPerServCell() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<RadioRepPerServCell>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				RadioRepPerServCell element = new RadioRepPerServCell();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<RadioRepPerServCell> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+		public void setRadioRepPerServCell(RadioRepPerServCell radioRepPerServCell) {
+			seqOf.add(radioRepPerServCell);
+		}
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private CRNTI crnti = null;
+	private RadioReportServCells radioReportServCells = null;
+	
+	public RadioMeasReportPerUE() {
+	}
+
+	public RadioMeasReportPerUE(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setRadioReportServCells(RadioReportServCells radioReportServCells) {
+		this.radioReportServCells = radioReportServCells;
+	}
+
+	public RadioReportServCells getRadioReportServCells() {
+		return radioReportServCells;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += radioReportServCells.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			radioReportServCells = new RadioReportServCells();
+			subCodeLength += radioReportServCells.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (radioReportServCells != null) {
+			sb.append("\"radioReportServCells\": ");
+			radioReportServCells.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/ScellAdd.java b/src/main/java/org.onosproject.xran/codecs/pdu/ScellAdd.java
new file mode 100644
index 0000000..a1d6c8f
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/ScellAdd.java
@@ -0,0 +1,330 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.PropScell;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ScellAdd implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class ScellsProp implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<PropScell> seqOf = null;
+
+		public ScellsProp() {
+			seqOf = new ArrayList<PropScell>();
+		}
+
+		public ScellsProp(byte[] code) {
+			this.code = code;
+		}
+
+		public List<PropScell> getPropScell() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<PropScell>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				PropScell element = new PropScell();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<PropScell> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private ScellsProp scellsProp = null;
+	
+	public ScellAdd() {
+	}
+
+	public ScellAdd(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setScellsProp(ScellsProp scellsProp) {
+		this.scellsProp = scellsProp;
+	}
+
+	public ScellsProp getScellsProp() {
+		return scellsProp;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += scellsProp.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			scellsProp = new ScellsProp();
+			subCodeLength += scellsProp.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (scellsProp != null) {
+			sb.append("\"scellsProp\": ");
+			scellsProp.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/ScellAddStatus.java b/src/main/java/org.onosproject.xran/codecs/pdu/ScellAddStatus.java
new file mode 100644
index 0000000..99ddadd
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/ScellAddStatus.java
@@ -0,0 +1,489 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.PCIARFCN;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ScellAddStatus implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class ScellsInd implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<PCIARFCN> seqOf = null;
+
+		public ScellsInd() {
+			seqOf = new ArrayList<PCIARFCN>();
+		}
+
+		public ScellsInd(byte[] code) {
+			this.code = code;
+		}
+
+		public List<PCIARFCN> getPCIARFCN() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<PCIARFCN>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				PCIARFCN element = new PCIARFCN();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<PCIARFCN> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static class Status implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<BerEnum> seqOf = null;
+
+		public Status() {
+			seqOf = new ArrayList<BerEnum>();
+		}
+
+		public Status(byte[] code) {
+			this.code = code;
+		}
+
+		public List<BerEnum> getBerEnum() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<BerEnum>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				BerEnum element = new BerEnum();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<BerEnum> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private ScellsInd scellsInd = null;
+	private Status status = null;
+	
+	public ScellAddStatus() {
+	}
+
+	public ScellAddStatus(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setScellsInd(ScellsInd scellsInd) {
+		this.scellsInd = scellsInd;
+	}
+
+	public ScellsInd getScellsInd() {
+		return scellsInd;
+	}
+
+	public void setStatus(Status status) {
+		this.status = status;
+	}
+
+	public Status getStatus() {
+		return status;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += status.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += scellsInd.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			scellsInd = new ScellsInd();
+			subCodeLength += scellsInd.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			status = new Status();
+			subCodeLength += status.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (scellsInd != null) {
+			sb.append("\"scellsInd\": ");
+			scellsInd.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (status != null) {
+			sb.append("\"status\": ");
+			status.appendAsString(sb, indentLevel + 1);
+		}
+
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/ScellDelete.java b/src/main/java/org.onosproject.xran/codecs/pdu/ScellDelete.java
new file mode 100644
index 0000000..278c7f6
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/ScellDelete.java
@@ -0,0 +1,330 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.PCIARFCN;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ScellDelete implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class ScellsInd implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<PCIARFCN> seqOf = null;
+
+		public ScellsInd() {
+			seqOf = new ArrayList<PCIARFCN>();
+		}
+
+		public ScellsInd(byte[] code) {
+			this.code = code;
+		}
+
+		public List<PCIARFCN> getPCIARFCN() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<PCIARFCN>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				PCIARFCN element = new PCIARFCN();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<PCIARFCN> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private ScellsInd scellsInd = null;
+	
+	public ScellDelete() {
+	}
+
+	public ScellDelete(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setScellsInd(ScellsInd scellsInd) {
+		this.scellsInd = scellsInd;
+	}
+
+	public ScellsInd getScellsInd() {
+		return scellsInd;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += scellsInd.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			scellsInd = new ScellsInd();
+			subCodeLength += scellsInd.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (scellsInd != null) {
+			sb.append("\"scellsInd\": ");
+			scellsInd.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/SchedMeasReportPerCell.java b/src/main/java/org.onosproject.xran/codecs/pdu/SchedMeasReportPerCell.java
new file mode 100644
index 0000000..1493c63
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/SchedMeasReportPerCell.java
@@ -0,0 +1,365 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.PRBUsage;
+import org.onosproject.xran.codecs.api.QCI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class SchedMeasReportPerCell implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class QciVals implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<QCI> seqOf = null;
+
+		public QciVals() {
+			seqOf = new ArrayList<QCI>();
+		}
+
+		public QciVals(byte[] code) {
+			this.code = code;
+		}
+
+		public List<QCI> getQCI() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<QCI>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				QCI element = new QCI();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<QCI> it = seqOf.iterator();
+				if (it.hasNext()) {
+					sb.append(it.next());
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						sb.append(it.next());
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+        public void setQCI(QCI qci) {
+			seqOf.add(qci);
+        }
+    }
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private QciVals qciVals = null;
+	private PRBUsage prbUsagePcell = null;
+	private PRBUsage prbUsageScell = null;
+	
+	public SchedMeasReportPerCell() {
+	}
+
+	public SchedMeasReportPerCell(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setQciVals(QciVals qciVals) {
+		this.qciVals = qciVals;
+	}
+
+	public QciVals getQciVals() {
+		return qciVals;
+	}
+
+	public void setPrbUsagePcell(PRBUsage prbUsagePcell) {
+		this.prbUsagePcell = prbUsagePcell;
+	}
+
+	public PRBUsage getPrbUsagePcell() {
+		return prbUsagePcell;
+	}
+
+	public void setPrbUsageScell(PRBUsage prbUsageScell) {
+		this.prbUsageScell = prbUsageScell;
+	}
+
+	public PRBUsage getPrbUsageScell() {
+		return prbUsageScell;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += prbUsageScell.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+		os.write(0xA3);
+		codeLength += 1;
+		
+		codeLength += prbUsagePcell.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += qciVals.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			qciVals = new QciVals();
+			subCodeLength += qciVals.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			prbUsagePcell = new PRBUsage();
+			subCodeLength += prbUsagePcell.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			prbUsageScell = new PRBUsage();
+			subCodeLength += prbUsageScell.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (qciVals != null) {
+			sb.append("\"qciVals\": ");
+			qciVals.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (prbUsagePcell != null) {
+			sb.append("\"prbUsagePcell\": ");
+			prbUsagePcell.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (prbUsageScell != null) {
+			sb.append("\"prbUsageScell\": ");
+			prbUsageScell.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/SchedMeasReportPerUE.java b/src/main/java/org.onosproject.xran/codecs/pdu/SchedMeasReportPerUE.java
new file mode 100644
index 0000000..3205e88
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/SchedMeasReportPerUE.java
@@ -0,0 +1,332 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.SchedMeasRepPerServCell;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class SchedMeasReportPerUE implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class SchedReportServCells implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<SchedMeasRepPerServCell> seqOf = null;
+
+		public SchedReportServCells() {
+			seqOf = new ArrayList<SchedMeasRepPerServCell>();
+		}
+
+		public SchedReportServCells(byte[] code) {
+			this.code = code;
+		}
+
+		public List<SchedMeasRepPerServCell> getSchedMeasRepPerServCell() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<SchedMeasRepPerServCell>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				SchedMeasRepPerServCell element = new SchedMeasRepPerServCell();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<SchedMeasRepPerServCell> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+        public void setSchedMeasRepPerServCell(SchedMeasRepPerServCell schedMeasRepPerServCell) {
+			seqOf.add(schedMeasRepPerServCell);
+        }
+    }
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private CRNTI crnti = null;
+	private SchedReportServCells schedReportServCells = null;
+	
+	public SchedMeasReportPerUE() {
+	}
+
+	public SchedMeasReportPerUE(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setSchedReportServCells(SchedReportServCells schedReportServCells) {
+		this.schedReportServCells = schedReportServCells;
+	}
+
+	public SchedReportServCells getSchedReportServCells() {
+		return schedReportServCells;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += schedReportServCells.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			schedReportServCells = new SchedReportServCells();
+			subCodeLength += schedReportServCells.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (schedReportServCells != null) {
+			sb.append("\"schedReportServCells\": ");
+			schedReportServCells.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/SeNBAdd.java b/src/main/java/org.onosproject.xran/codecs/pdu/SeNBAdd.java
new file mode 100644
index 0000000..d86cf6d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/SeNBAdd.java
@@ -0,0 +1,199 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class SeNBAdd implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI mEcgi = null;
+	private ECGI sEcgi = null;
+	
+	public SeNBAdd() {
+	}
+
+	public SeNBAdd(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setMEcgi(ECGI mEcgi) {
+		this.mEcgi = mEcgi;
+	}
+
+	public ECGI getMEcgi() {
+		return mEcgi;
+	}
+
+	public void setSEcgi(ECGI sEcgi) {
+		this.sEcgi = sEcgi;
+	}
+
+	public ECGI getSEcgi() {
+		return sEcgi;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += sEcgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += mEcgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			mEcgi = new ECGI();
+			subCodeLength += mEcgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			sEcgi = new ECGI();
+			subCodeLength += sEcgi.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (mEcgi != null) {
+			sb.append("\"mEcgi\": ");
+			mEcgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (sEcgi != null) {
+			sb.append("\"sEcgi\": ");
+			sEcgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/SeNBAddStatus.java b/src/main/java/org.onosproject.xran/codecs/pdu/SeNBAddStatus.java
new file mode 100644
index 0000000..e09c110
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/SeNBAddStatus.java
@@ -0,0 +1,200 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class SeNBAddStatus implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private BerEnum status = null;
+	
+	public SeNBAddStatus() {
+	}
+
+	public SeNBAddStatus(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setStatus(BerEnum status) {
+		this.status = status;
+	}
+
+	public BerEnum getStatus() {
+		return status;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += status.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			status = new BerEnum();
+			subCodeLength += status.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (status != null) {
+			sb.append("\"status\": ").append(status);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/SeNBDelete.java b/src/main/java/org.onosproject.xran/codecs/pdu/SeNBDelete.java
new file mode 100644
index 0000000..8441c3f
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/SeNBDelete.java
@@ -0,0 +1,200 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class SeNBDelete implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI mEcgi = null;
+	private ECGI sEcgi = null;
+	
+	public SeNBDelete() {
+	}
+
+	public SeNBDelete(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setMEcgi(ECGI mEcgi) {
+		this.mEcgi = mEcgi;
+	}
+
+	public ECGI getMEcgi() {
+		return mEcgi;
+	}
+
+	public void setSEcgi(ECGI sEcgi) {
+		this.sEcgi = sEcgi;
+	}
+
+	public ECGI getSEcgi() {
+		return sEcgi;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += sEcgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += mEcgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			mEcgi = new ECGI();
+			subCodeLength += mEcgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			sEcgi = new ECGI();
+			subCodeLength += sEcgi.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (mEcgi != null) {
+			sb.append("\"mEcgi\": ");
+			mEcgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (sEcgi != null) {
+			sb.append("\"sEcgi\": ");
+			sEcgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/TrafficSplitConfig.java b/src/main/java/org.onosproject.xran/codecs/pdu/TrafficSplitConfig.java
new file mode 100644
index 0000000..408b722
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/TrafficSplitConfig.java
@@ -0,0 +1,329 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.TrafficSplitPercentage;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class TrafficSplitConfig implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static class TrafficSplitPercent implements Serializable {
+
+		private static final long serialVersionUID = 1L;
+
+		public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+		public byte[] code = null;
+		private List<TrafficSplitPercentage> seqOf = null;
+
+		public TrafficSplitPercent() {
+			seqOf = new ArrayList<TrafficSplitPercentage>();
+		}
+
+		public TrafficSplitPercent(byte[] code) {
+			this.code = code;
+		}
+
+		public List<TrafficSplitPercentage> getTrafficSplitPercentage() {
+			if (seqOf == null) {
+				seqOf = new ArrayList<TrafficSplitPercentage>();
+			}
+			return seqOf;
+		}
+
+		public int encode(BerByteArrayOutputStream os) throws IOException {
+			return encode(os, true);
+		}
+
+		public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+			if (code != null) {
+				for (int i = code.length - 1; i >= 0; i--) {
+					os.write(code[i]);
+				}
+				if (withTag) {
+					return tag.encode(os) + code.length;
+				}
+				return code.length;
+			}
+
+			int codeLength = 0;
+			for (int i = (seqOf.size() - 1); i >= 0; i--) {
+				codeLength += seqOf.get(i).encode(os, true);
+			}
+
+			codeLength += BerLength.encodeLength(os, codeLength);
+
+			if (withTag) {
+				codeLength += tag.encode(os);
+			}
+
+			return codeLength;
+		}
+
+		public int decode(InputStream is) throws IOException {
+			return decode(is, true);
+		}
+
+		public int decode(InputStream is, boolean withTag) throws IOException {
+			int codeLength = 0;
+			int subCodeLength = 0;
+			if (withTag) {
+				codeLength += tag.decodeAndCheck(is);
+			}
+
+			BerLength length = new BerLength();
+			codeLength += length.decode(is);
+			int totalLength = length.val;
+
+			while (subCodeLength < totalLength) {
+				TrafficSplitPercentage element = new TrafficSplitPercentage();
+				subCodeLength += element.decode(is, true);
+				seqOf.add(element);
+			}
+			if (subCodeLength != totalLength) {
+				throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+			}
+			codeLength += subCodeLength;
+
+			return codeLength;
+		}
+
+		public void encodeAndSave(int encodingSizeGuess) throws IOException {
+			BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+			encode(os, false);
+			code = os.getArray();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			appendAsString(sb, 0);
+			return sb.toString();
+		}
+
+		public void appendAsString(StringBuilder sb, int indentLevel) {
+
+			sb.append("[\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			if (seqOf == null) {
+//				sb.append("null");
+			}
+			else {
+				Iterator<TrafficSplitPercentage> it = seqOf.iterator();
+				if (it.hasNext()) {
+					it.next().appendAsString(sb, indentLevel + 1);
+					while (it.hasNext()) {
+						sb.append(",\n");
+						for (int i = 0; i < indentLevel + 1; i++) {
+							sb.append("\t");
+						}
+						it.next().appendAsString(sb, indentLevel + 1);
+					}
+				}
+			}
+
+			sb.append("\n");
+			for (int i = 0; i < indentLevel; i++) {
+				sb.append("\t");
+			}
+			sb.append("]");
+		}
+
+	}
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private TrafficSplitPercent trafficSplitPercent = null;
+	
+	public TrafficSplitConfig() {
+	}
+
+	public TrafficSplitConfig(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setTrafficSplitPercent(TrafficSplitPercent trafficSplitPercent) {
+		this.trafficSplitPercent = trafficSplitPercent;
+	}
+
+	public TrafficSplitPercent getTrafficSplitPercent() {
+		return trafficSplitPercent;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += trafficSplitPercent.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+		os.write(0xA2);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			trafficSplitPercent = new TrafficSplitPercent();
+			subCodeLength += trafficSplitPercent.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (trafficSplitPercent != null) {
+			sb.append("\"trafficSplitPercent\": ");
+			trafficSplitPercent.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionRequest.java b/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionRequest.java
new file mode 100644
index 0000000..3eb4b9e
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionRequest.java
@@ -0,0 +1,200 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.onosproject.xran.codecs.api.AdmEstCause;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEAdmissionRequest implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private AdmEstCause admEstCause = null;
+	
+	public UEAdmissionRequest() {
+	}
+
+	public UEAdmissionRequest(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setAdmEstCause(AdmEstCause admEstCause) {
+		this.admEstCause = admEstCause;
+	}
+
+	public AdmEstCause getAdmEstCause() {
+		return admEstCause;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += admEstCause.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			admEstCause = new AdmEstCause();
+			subCodeLength += admEstCause.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (admEstCause != null) {
+			sb.append("\"admEstCause\": ").append(admEstCause);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionResponse.java b/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionResponse.java
new file mode 100644
index 0000000..db6ed32
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionResponse.java
@@ -0,0 +1,200 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.onosproject.xran.codecs.api.AdmEstResponse;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEAdmissionResponse implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private AdmEstResponse admEstResponse = null;
+	
+	public UEAdmissionResponse() {
+	}
+
+	public UEAdmissionResponse(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setAdmEstResponse(AdmEstResponse admEstResponse) {
+		this.admEstResponse = admEstResponse;
+	}
+
+	public AdmEstResponse getAdmEstResponse() {
+		return admEstResponse;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += admEstResponse.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			admEstResponse = new AdmEstResponse();
+			subCodeLength += admEstResponse.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (admEstResponse != null) {
+			sb.append("\"admEstResponse\": ").append(admEstResponse);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionStatus.java b/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionStatus.java
new file mode 100644
index 0000000..edfd056
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UEAdmissionStatus.java
@@ -0,0 +1,200 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.onosproject.xran.codecs.api.AdmEstStatus;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEAdmissionStatus implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private AdmEstStatus admEstStatus = null;
+	
+	public UEAdmissionStatus() {
+	}
+
+	public UEAdmissionStatus(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setAdmEstStatus(AdmEstStatus admEstStatus) {
+		this.admEstStatus = admEstStatus;
+	}
+
+	public AdmEstStatus getAdmEstStatus() {
+		return admEstStatus;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += admEstStatus.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			admEstStatus = new AdmEstStatus();
+			subCodeLength += admEstStatus.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (admEstStatus != null) {
+			sb.append("\"admEstStatus\": ").append(admEstStatus);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UEAttachComplete.java b/src/main/java/org.onosproject.xran/codecs/pdu/UEAttachComplete.java
new file mode 100644
index 0000000..74050d7
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UEAttachComplete.java
@@ -0,0 +1,232 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.ENBUES1APID;
+import org.onosproject.xran.codecs.api.MMEUES1APID;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEAttachComplete implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private MMEUES1APID mMEUES1APID = null;
+	private ENBUES1APID eNBUES1APID = null;
+	
+	public UEAttachComplete() {
+	}
+
+	public UEAttachComplete(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setMMEUES1APID(MMEUES1APID mMEUES1APID) {
+		this.mMEUES1APID = mMEUES1APID;
+	}
+
+	public MMEUES1APID getMMEUES1APID() {
+		return mMEUES1APID;
+	}
+
+	public void setENBUES1APID(ENBUES1APID eNBUES1APID) {
+		this.eNBUES1APID = eNBUES1APID;
+	}
+
+	public ENBUES1APID getENBUES1APID() {
+		return eNBUES1APID;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += eNBUES1APID.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += mMEUES1APID.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			mMEUES1APID = new MMEUES1APID();
+			subCodeLength += mMEUES1APID.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			eNBUES1APID = new ENBUES1APID();
+			subCodeLength += eNBUES1APID.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (mMEUES1APID != null) {
+			sb.append("\"mMEUES1APID\": ").append(mMEUES1APID);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (eNBUES1APID != null) {
+			sb.append("\"eNBUES1APID\": ").append(eNBUES1APID);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UECapabilityEnquiry.java b/src/main/java/org.onosproject.xran/codecs/pdu/UECapabilityEnquiry.java
new file mode 100644
index 0000000..84758d1
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UECapabilityEnquiry.java
@@ -0,0 +1,169 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class UECapabilityEnquiry implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	
+	public UECapabilityEnquiry() {
+	}
+
+	public UECapabilityEnquiry(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UECapabilityInfo.java b/src/main/java/org.onosproject.xran/codecs/pdu/UECapabilityInfo.java
new file mode 100644
index 0000000..a2c017e
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UECapabilityInfo.java
@@ -0,0 +1,241 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CACap;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.DCCap;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class UECapabilityInfo implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private CACap caCap = null;
+	private DCCap dcCap = null;
+	
+	public UECapabilityInfo() {
+	}
+
+	public UECapabilityInfo(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCaCap(CACap caCap) {
+		this.caCap = caCap;
+	}
+
+	public CACap getCaCap() {
+		return caCap;
+	}
+
+	public void setDcCap(DCCap dcCap) {
+		this.dcCap = dcCap;
+	}
+
+	public DCCap getDcCap() {
+		return dcCap;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		if (dcCap != null) {
+			codeLength += dcCap.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+			os.write(0xA3);
+			codeLength += 1;
+		}
+		
+		if (caCap != null) {
+			codeLength += caCap.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+			os.write(0xA2);
+			codeLength += 1;
+		}
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			caCap = new CACap();
+			subCodeLength += caCap.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+			subCodeLength += berTag.decode(is);
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			dcCap = new DCCap();
+			subCodeLength += dcCap.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (caCap != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"caCap\": ");
+			caCap.appendAsString(sb, indentLevel + 1);
+		}
+		
+		if (dcCap != null) {
+			sb.append(",\n");
+			for (int i = 0; i < indentLevel + 1; i++) {
+				sb.append("\t");
+			}
+			sb.append("\"dcCap\": ");
+			dcCap.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UEReconfigInd.java b/src/main/java/org.onosproject.xran/codecs/pdu/UEReconfigInd.java
new file mode 100644
index 0000000..4a5fd3d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UEReconfigInd.java
@@ -0,0 +1,231 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.ReconfIndReason;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEReconfigInd implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crntiOld = null;
+	private ECGI ecgi = null;
+	private CRNTI crntiNew = null;
+	private ReconfIndReason reconfigCause = null;
+	
+	public UEReconfigInd() {
+	}
+
+	public UEReconfigInd(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrntiOld(CRNTI crntiOld) {
+		this.crntiOld = crntiOld;
+	}
+
+	public CRNTI getCrntiOld() {
+		return crntiOld;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setCrntiNew(CRNTI crntiNew) {
+		this.crntiNew = crntiNew;
+	}
+
+	public CRNTI getCrntiNew() {
+		return crntiNew;
+	}
+
+	public void setReconfigCause(ReconfIndReason reconfigCause) {
+		this.reconfigCause = reconfigCause;
+	}
+
+	public ReconfIndReason getReconfigCause() {
+		return reconfigCause;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += reconfigCause.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += crntiNew.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crntiOld.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crntiOld = new CRNTI();
+			subCodeLength += crntiOld.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			crntiNew = new CRNTI();
+			subCodeLength += crntiNew.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			reconfigCause = new ReconfIndReason();
+			subCodeLength += reconfigCause.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crntiOld != null) {
+			sb.append("\"crntiOld\": ").append(crntiOld);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crntiNew != null) {
+			sb.append("\"crntiNew\": ").append(crntiNew);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (reconfigCause != null) {
+			sb.append("\"reconfigCause\": ").append(reconfigCause);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/UEReleaseInd.java b/src/main/java/org.onosproject.xran/codecs/pdu/UEReleaseInd.java
new file mode 100644
index 0000000..9b601ad
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/UEReleaseInd.java
@@ -0,0 +1,199 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.RelCause;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEReleaseInd implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private RelCause releaseCause = null;
+	
+	public UEReleaseInd() {
+	}
+
+	public UEReleaseInd(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setReleaseCause(RelCause releaseCause) {
+		this.releaseCause = releaseCause;
+	}
+
+	public RelCause getReleaseCause() {
+		return releaseCause;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += releaseCause.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			releaseCause = new RelCause();
+			subCodeLength += releaseCause.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (releaseCause != null) {
+			sb.append("\"releaseCause\": ").append(releaseCause);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/XICICConfig.java b/src/main/java/org.onosproject.xran/codecs/pdu/XICICConfig.java
new file mode 100644
index 0000000..f02d36a
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/XICICConfig.java
@@ -0,0 +1,450 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+package org.onosproject.xran.codecs.pdu;
+
+import org.onosproject.xran.codecs.api.CRNTI;
+import org.onosproject.xran.codecs.api.ECGI;
+import org.onosproject.xran.codecs.api.PCIARFCN;
+import org.onosproject.xran.codecs.api.XICICPA;
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.BerBitString;
+import org.openmuc.jasn1.ber.types.BerInteger;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class XICICConfig implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private ECGI ecgi = null;
+	private PCIARFCN pciArfcn = null;
+	private CRNTI crnti = null;
+	private XICICPA pa = null;
+	private BerInteger startPrbDl = null;
+	private BerInteger endPrbDl = null;
+	private BerBitString subframeBitmaskDl = null;
+	private BerInteger p0UePusch = null;
+	private BerInteger startPrbUl = null;
+	private BerInteger endPrbUl = null;
+	private BerBitString subframeBitmaskUl = null;
+	
+	public XICICConfig() {
+	}
+
+	public XICICConfig(byte[] code) {
+		this.code = code;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setPciArfcn(PCIARFCN pciArfcn) {
+		this.pciArfcn = pciArfcn;
+	}
+
+	public PCIARFCN getPciArfcn() {
+		return pciArfcn;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setPa(XICICPA pa) {
+		this.pa = pa;
+	}
+
+	public XICICPA getPa() {
+		return pa;
+	}
+
+	public void setStartPrbDl(BerInteger startPrbDl) {
+		this.startPrbDl = startPrbDl;
+	}
+
+	public BerInteger getStartPrbDl() {
+		return startPrbDl;
+	}
+
+	public void setEndPrbDl(BerInteger endPrbDl) {
+		this.endPrbDl = endPrbDl;
+	}
+
+	public BerInteger getEndPrbDl() {
+		return endPrbDl;
+	}
+
+	public void setSubframeBitmaskDl(BerBitString subframeBitmaskDl) {
+		this.subframeBitmaskDl = subframeBitmaskDl;
+	}
+
+	public BerBitString getSubframeBitmaskDl() {
+		return subframeBitmaskDl;
+	}
+
+	public void setP0UePusch(BerInteger p0UePusch) {
+		this.p0UePusch = p0UePusch;
+	}
+
+	public BerInteger getP0UePusch() {
+		return p0UePusch;
+	}
+
+	public void setStartPrbUl(BerInteger startPrbUl) {
+		this.startPrbUl = startPrbUl;
+	}
+
+	public BerInteger getStartPrbUl() {
+		return startPrbUl;
+	}
+
+	public void setEndPrbUl(BerInteger endPrbUl) {
+		this.endPrbUl = endPrbUl;
+	}
+
+	public BerInteger getEndPrbUl() {
+		return endPrbUl;
+	}
+
+	public void setSubframeBitmaskUl(BerBitString subframeBitmaskUl) {
+		this.subframeBitmaskUl = subframeBitmaskUl;
+	}
+
+	public BerBitString getSubframeBitmaskUl() {
+		return subframeBitmaskUl;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += subframeBitmaskUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 10
+		os.write(0x8A);
+		codeLength += 1;
+		
+		codeLength += endPrbUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 9
+		os.write(0x89);
+		codeLength += 1;
+		
+		codeLength += startPrbUl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 8
+		os.write(0x88);
+		codeLength += 1;
+		
+		codeLength += p0UePusch.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 7
+		os.write(0x87);
+		codeLength += 1;
+		
+		codeLength += subframeBitmaskDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 6
+		os.write(0x86);
+		codeLength += 1;
+		
+		codeLength += endPrbDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 5
+		os.write(0x85);
+		codeLength += 1;
+		
+		codeLength += startPrbDl.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 4
+		os.write(0x84);
+		codeLength += 1;
+		
+		codeLength += pa.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 3
+		os.write(0x83);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += pciArfcn.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			pciArfcn = new PCIARFCN();
+			subCodeLength += pciArfcn.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+			pa = new XICICPA();
+			subCodeLength += pa.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+			startPrbDl = new BerInteger();
+			subCodeLength += startPrbDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
+			endPrbDl = new BerInteger();
+			subCodeLength += endPrbDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 6)) {
+			subframeBitmaskDl = new BerBitString();
+			subCodeLength += subframeBitmaskDl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 7)) {
+			p0UePusch = new BerInteger();
+			subCodeLength += p0UePusch.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 8)) {
+			startPrbUl = new BerInteger();
+			subCodeLength += startPrbUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 9)) {
+			endPrbUl = new BerInteger();
+			subCodeLength += endPrbUl.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 10)) {
+			subframeBitmaskUl = new BerBitString();
+			subCodeLength += subframeBitmaskUl.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("\"ecgi\": ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pciArfcn != null) {
+			sb.append("\"pciArfcn\": ");
+			pciArfcn.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("\"crnti\": ").append(crnti);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (pa != null) {
+			sb.append("\"pa\": ").append(pa);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (startPrbDl != null) {
+			sb.append("\"startPrbDl\": ").append(startPrbDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (endPrbDl != null) {
+			sb.append("\"endPrbDl\": ").append(endPrbDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (subframeBitmaskDl != null) {
+			sb.append("\"subframeBitmaskDl\": ").append(subframeBitmaskDl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (p0UePusch != null) {
+			sb.append("\"p0UePusch\": ").append(p0UePusch);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (startPrbUl != null) {
+			sb.append("\"startPrbUl\": ").append(startPrbUl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (endPrbUl != null) {
+			sb.append("\"endPrbUl\": ").append(endPrbUl);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (subframeBitmaskUl != null) {
+			sb.append("\"subframeBitmaskUl\": ").append(subframeBitmaskUl);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/XrancApiID.java b/src/main/java/org.onosproject.xran/codecs/pdu/XrancApiID.java
new file mode 100644
index 0000000..341b70f
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/XrancApiID.java
@@ -0,0 +1,30 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+public class XrancApiID extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public XrancApiID() {
+	}
+
+	public XrancApiID(byte[] code) {
+		super(code);
+	}
+
+	public XrancApiID(BigInteger value) {
+		super(value);
+	}
+
+	public XrancApiID(long value) {
+		super(value);
+	}
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/XrancPdu.java b/src/main/java/org.onosproject.xran/codecs/pdu/XrancPdu.java
new file mode 100644
index 0000000..d365a39
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/XrancPdu.java
@@ -0,0 +1,172 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class XrancPdu implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private XrancPduHdr hdr = null;
+	private XrancPduBody body = null;
+	
+	public XrancPdu() {
+	}
+
+	public XrancPdu(byte[] code) {
+		this.code = code;
+	}
+
+	public void setHdr(XrancPduHdr hdr) {
+		this.hdr = hdr;
+	}
+
+	public XrancPduHdr getHdr() {
+		return hdr;
+	}
+
+	public void setBody(XrancPduBody body) {
+		this.body = body;
+	}
+
+	public XrancPduBody getBody() {
+		return body;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		int sublength;
+
+		sublength = body.encode(os);
+		codeLength += sublength;
+		codeLength += BerLength.encodeLength(os, sublength);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += hdr.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			hdr = new XrancPduHdr();
+			subCodeLength += hdr.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			subCodeLength += length.decode(is);
+			body = new XrancPduBody();
+			subCodeLength += body.decode(is, null);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (hdr != null) {
+			sb.append("\"hdr\": ");
+			hdr.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (body != null) {
+			sb.append("\"body\": ");
+			body.appendAsString(sb, indentLevel + 1);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/XrancPduBody.java b/src/main/java/org.onosproject.xran/codecs/pdu/XrancPduBody.java
new file mode 100644
index 0000000..c0a38fc
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/XrancPduBody.java
@@ -0,0 +1,1098 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class XrancPduBody implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public byte[] code = null;
+	private CellConfigRequest cellConfigRequest = null;
+	private CellConfigReport cellConfigReport = null;
+	private UEAdmissionRequest uEAdmissionRequest = null;
+	private UEAdmissionResponse uEAdmissionResponse = null;
+	private UEAttachComplete uEAttachComplete = null;
+	private UEAdmissionStatus uEAdmissionStatus = null;
+	private UEReconfigInd uEReconfigInd = null;
+	private UEReleaseInd uEReleaseInd = null;
+	private BearerAdmissionRequest bearerAdmissionRequest = null;
+	private BearerAdmissionResponse bearerAdmissionResponse = null;
+	private BearerAdmissionStatus bearerAdmissionStatus = null;
+	private BearerReleaseInd bearerReleaseInd = null;
+	private UECapabilityEnquiry uECapabilityEnquiry = null;
+	private UECapabilityInfo uECapabilityInfo = null;
+	private HORequest hORequest = null;
+	private HOFailure hOFailure = null;
+	private HOComplete hOComplete = null;
+	private RXSigMeasConfig rXSigMeasConfig = null;
+	private RXSigMeasReport rXSigMeasReport = null;
+	private L2MeasConfig l2MeasConfig = null;
+	private RadioMeasReportPerUE radioMeasReportPerUE = null;
+	private RadioMeasReportPerCell radioMeasReportPerCell = null;
+	private SchedMeasReportPerUE schedMeasReportPerUE = null;
+	private SchedMeasReportPerCell schedMeasReportPerCell = null;
+	private PDCPMeasReportPerUe pDCPMeasReportPerUe = null;
+	private XICICConfig xICICConfig = null;
+	private RRMConfig rRMConfig = null;
+	private RRMConfigStatus rRMConfigStatus = null;
+	private ScellAdd scellAdd = null;
+	private ScellAddStatus scellAddStatus = null;
+	private ScellDelete scellDelete = null;
+	private SeNBAdd seNBAdd = null;
+	private SeNBAddStatus seNBAddStatus = null;
+	private SeNBDelete seNBDelete = null;
+	private TrafficSplitConfig trafficSplitConfig = null;
+	
+	public XrancPduBody() {
+	}
+
+	public XrancPduBody(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCellConfigRequest(CellConfigRequest cellConfigRequest) {
+		this.cellConfigRequest = cellConfigRequest;
+	}
+
+	public CellConfigRequest getCellConfigRequest() {
+		return cellConfigRequest;
+	}
+
+	public void setCellConfigReport(CellConfigReport cellConfigReport) {
+		this.cellConfigReport = cellConfigReport;
+	}
+
+	public CellConfigReport getCellConfigReport() {
+		return cellConfigReport;
+	}
+
+	public void setUEAdmissionRequest(UEAdmissionRequest uEAdmissionRequest) {
+		this.uEAdmissionRequest = uEAdmissionRequest;
+	}
+
+	public UEAdmissionRequest getUEAdmissionRequest() {
+		return uEAdmissionRequest;
+	}
+
+	public void setUEAdmissionResponse(UEAdmissionResponse uEAdmissionResponse) {
+		this.uEAdmissionResponse = uEAdmissionResponse;
+	}
+
+	public UEAdmissionResponse getUEAdmissionResponse() {
+		return uEAdmissionResponse;
+	}
+
+	public void setUEAttachComplete(UEAttachComplete uEAttachComplete) {
+		this.uEAttachComplete = uEAttachComplete;
+	}
+
+	public UEAttachComplete getUEAttachComplete() {
+		return uEAttachComplete;
+	}
+
+	public void setUEAdmissionStatus(UEAdmissionStatus uEAdmissionStatus) {
+		this.uEAdmissionStatus = uEAdmissionStatus;
+	}
+
+	public UEAdmissionStatus getUEAdmissionStatus() {
+		return uEAdmissionStatus;
+	}
+
+	public void setUEReconfigInd(UEReconfigInd uEReconfigInd) {
+		this.uEReconfigInd = uEReconfigInd;
+	}
+
+	public UEReconfigInd getUEReconfigInd() {
+		return uEReconfigInd;
+	}
+
+	public void setUEReleaseInd(UEReleaseInd uEReleaseInd) {
+		this.uEReleaseInd = uEReleaseInd;
+	}
+
+	public UEReleaseInd getUEReleaseInd() {
+		return uEReleaseInd;
+	}
+
+	public void setBearerAdmissionRequest(BearerAdmissionRequest bearerAdmissionRequest) {
+		this.bearerAdmissionRequest = bearerAdmissionRequest;
+	}
+
+	public BearerAdmissionRequest getBearerAdmissionRequest() {
+		return bearerAdmissionRequest;
+	}
+
+	public void setBearerAdmissionResponse(BearerAdmissionResponse bearerAdmissionResponse) {
+		this.bearerAdmissionResponse = bearerAdmissionResponse;
+	}
+
+	public BearerAdmissionResponse getBearerAdmissionResponse() {
+		return bearerAdmissionResponse;
+	}
+
+	public void setBearerAdmissionStatus(BearerAdmissionStatus bearerAdmissionStatus) {
+		this.bearerAdmissionStatus = bearerAdmissionStatus;
+	}
+
+	public BearerAdmissionStatus getBearerAdmissionStatus() {
+		return bearerAdmissionStatus;
+	}
+
+	public void setBearerReleaseInd(BearerReleaseInd bearerReleaseInd) {
+		this.bearerReleaseInd = bearerReleaseInd;
+	}
+
+	public BearerReleaseInd getBearerReleaseInd() {
+		return bearerReleaseInd;
+	}
+
+	public void setUECapabilityEnquiry(UECapabilityEnquiry uECapabilityEnquiry) {
+		this.uECapabilityEnquiry = uECapabilityEnquiry;
+	}
+
+	public UECapabilityEnquiry getUECapabilityEnquiry() {
+		return uECapabilityEnquiry;
+	}
+
+	public void setUECapabilityInfo(UECapabilityInfo uECapabilityInfo) {
+		this.uECapabilityInfo = uECapabilityInfo;
+	}
+
+	public UECapabilityInfo getUECapabilityInfo() {
+		return uECapabilityInfo;
+	}
+
+	public void setHORequest(HORequest hORequest) {
+		this.hORequest = hORequest;
+	}
+
+	public HORequest getHORequest() {
+		return hORequest;
+	}
+
+	public void setHOFailure(HOFailure hOFailure) {
+		this.hOFailure = hOFailure;
+	}
+
+	public HOFailure getHOFailure() {
+		return hOFailure;
+	}
+
+	public void setHOComplete(HOComplete hOComplete) {
+		this.hOComplete = hOComplete;
+	}
+
+	public HOComplete getHOComplete() {
+		return hOComplete;
+	}
+
+	public void setRXSigMeasConfig(RXSigMeasConfig rXSigMeasConfig) {
+		this.rXSigMeasConfig = rXSigMeasConfig;
+	}
+
+	public RXSigMeasConfig getRXSigMeasConfig() {
+		return rXSigMeasConfig;
+	}
+
+	public void setRXSigMeasReport(RXSigMeasReport rXSigMeasReport) {
+		this.rXSigMeasReport = rXSigMeasReport;
+	}
+
+	public RXSigMeasReport getRXSigMeasReport() {
+		return rXSigMeasReport;
+	}
+
+	public void setL2MeasConfig(L2MeasConfig l2MeasConfig) {
+		this.l2MeasConfig = l2MeasConfig;
+	}
+
+	public L2MeasConfig getL2MeasConfig() {
+		return l2MeasConfig;
+	}
+
+	public void setRadioMeasReportPerUE(RadioMeasReportPerUE radioMeasReportPerUE) {
+		this.radioMeasReportPerUE = radioMeasReportPerUE;
+	}
+
+	public RadioMeasReportPerUE getRadioMeasReportPerUE() {
+		return radioMeasReportPerUE;
+	}
+
+	public void setRadioMeasReportPerCell(RadioMeasReportPerCell radioMeasReportPerCell) {
+		this.radioMeasReportPerCell = radioMeasReportPerCell;
+	}
+
+	public RadioMeasReportPerCell getRadioMeasReportPerCell() {
+		return radioMeasReportPerCell;
+	}
+
+	public void setSchedMeasReportPerUE(SchedMeasReportPerUE schedMeasReportPerUE) {
+		this.schedMeasReportPerUE = schedMeasReportPerUE;
+	}
+
+	public SchedMeasReportPerUE getSchedMeasReportPerUE() {
+		return schedMeasReportPerUE;
+	}
+
+	public void setSchedMeasReportPerCell(SchedMeasReportPerCell schedMeasReportPerCell) {
+		this.schedMeasReportPerCell = schedMeasReportPerCell;
+	}
+
+	public SchedMeasReportPerCell getSchedMeasReportPerCell() {
+		return schedMeasReportPerCell;
+	}
+
+	public void setPDCPMeasReportPerUe(PDCPMeasReportPerUe pDCPMeasReportPerUe) {
+		this.pDCPMeasReportPerUe = pDCPMeasReportPerUe;
+	}
+
+	public PDCPMeasReportPerUe getPDCPMeasReportPerUe() {
+		return pDCPMeasReportPerUe;
+	}
+
+	public void setXICICConfig(XICICConfig xICICConfig) {
+		this.xICICConfig = xICICConfig;
+	}
+
+	public XICICConfig getXICICConfig() {
+		return xICICConfig;
+	}
+
+	public void setRRMConfig(RRMConfig rRMConfig) {
+		this.rRMConfig = rRMConfig;
+	}
+
+	public RRMConfig getRRMConfig() {
+		return rRMConfig;
+	}
+
+	public void setRRMConfigStatus(RRMConfigStatus rRMConfigStatus) {
+		this.rRMConfigStatus = rRMConfigStatus;
+	}
+
+	public RRMConfigStatus getRRMConfigStatus() {
+		return rRMConfigStatus;
+	}
+
+	public void setScellAdd(ScellAdd scellAdd) {
+		this.scellAdd = scellAdd;
+	}
+
+	public ScellAdd getScellAdd() {
+		return scellAdd;
+	}
+
+	public void setScellAddStatus(ScellAddStatus scellAddStatus) {
+		this.scellAddStatus = scellAddStatus;
+	}
+
+	public ScellAddStatus getScellAddStatus() {
+		return scellAddStatus;
+	}
+
+	public void setScellDelete(ScellDelete scellDelete) {
+		this.scellDelete = scellDelete;
+	}
+
+	public ScellDelete getScellDelete() {
+		return scellDelete;
+	}
+
+	public void setSeNBAdd(SeNBAdd seNBAdd) {
+		this.seNBAdd = seNBAdd;
+	}
+
+	public SeNBAdd getSeNBAdd() {
+		return seNBAdd;
+	}
+
+	public void setSeNBAddStatus(SeNBAddStatus seNBAddStatus) {
+		this.seNBAddStatus = seNBAddStatus;
+	}
+
+	public SeNBAddStatus getSeNBAddStatus() {
+		return seNBAddStatus;
+	}
+
+	public void setSeNBDelete(SeNBDelete seNBDelete) {
+		this.seNBDelete = seNBDelete;
+	}
+
+	public SeNBDelete getSeNBDelete() {
+		return seNBDelete;
+	}
+
+	public void setTrafficSplitConfig(TrafficSplitConfig trafficSplitConfig) {
+		this.trafficSplitConfig = trafficSplitConfig;
+	}
+
+	public TrafficSplitConfig getTrafficSplitConfig() {
+		return trafficSplitConfig;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		if (trafficSplitConfig != null) {
+			codeLength += trafficSplitConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 34
+			os.write(0x22);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (seNBDelete != null) {
+			codeLength += seNBDelete.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 33
+			os.write(0x21);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (seNBAddStatus != null) {
+			codeLength += seNBAddStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 32
+			os.write(0x20);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (seNBAdd != null) {
+			codeLength += seNBAdd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 31
+			os.write(0x1F);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (scellDelete != null) {
+			codeLength += scellDelete.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 30
+			os.write(0xBE);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (scellAddStatus != null) {
+			codeLength += scellAddStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 29
+			os.write(0xBD);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (scellAdd != null) {
+			codeLength += scellAdd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 28
+			os.write(0xBC);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (rRMConfigStatus != null) {
+			codeLength += rRMConfigStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 27
+			os.write(0xBB);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (rRMConfig != null) {
+			codeLength += rRMConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 26
+			os.write(0xBA);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (xICICConfig != null) {
+			codeLength += xICICConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 25
+			os.write(0xB9);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (pDCPMeasReportPerUe != null) {
+			codeLength += pDCPMeasReportPerUe.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 24
+			os.write(0xB8);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (schedMeasReportPerCell != null) {
+			codeLength += schedMeasReportPerCell.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 23
+			os.write(0xB7);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (schedMeasReportPerUE != null) {
+			codeLength += schedMeasReportPerUE.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 22
+			os.write(0xB6);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (radioMeasReportPerCell != null) {
+			codeLength += radioMeasReportPerCell.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 21
+			os.write(0xB5);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (radioMeasReportPerUE != null) {
+			codeLength += radioMeasReportPerUE.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 20
+			os.write(0xB4);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (l2MeasConfig != null) {
+			codeLength += l2MeasConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 19
+			os.write(0xB3);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (rXSigMeasReport != null) {
+			codeLength += rXSigMeasReport.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 18
+			os.write(0xB2);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (rXSigMeasConfig != null) {
+			codeLength += rXSigMeasConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 17
+			os.write(0xB1);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (hOComplete != null) {
+			codeLength += hOComplete.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 16
+			os.write(0xB0);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (hOFailure != null) {
+			codeLength += hOFailure.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 15
+			os.write(0xAF);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (hORequest != null) {
+			codeLength += hORequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 14
+			os.write(0xAE);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uECapabilityInfo != null) {
+			codeLength += uECapabilityInfo.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 13
+			os.write(0xAD);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uECapabilityEnquiry != null) {
+			codeLength += uECapabilityEnquiry.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 12
+			os.write(0xAC);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerReleaseInd != null) {
+			codeLength += bearerReleaseInd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 11
+			os.write(0xAB);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerAdmissionStatus != null) {
+			codeLength += bearerAdmissionStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 10
+			os.write(0xAA);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerAdmissionResponse != null) {
+			codeLength += bearerAdmissionResponse.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 9
+			os.write(0xA9);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerAdmissionRequest != null) {
+			codeLength += bearerAdmissionRequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+			os.write(0xA8);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEReleaseInd != null) {
+			codeLength += uEReleaseInd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+			os.write(0xA7);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEReconfigInd != null) {
+			codeLength += uEReconfigInd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+			os.write(0xA6);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEAdmissionStatus != null) {
+			codeLength += uEAdmissionStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+			os.write(0xA5);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEAttachComplete != null) {
+			codeLength += uEAttachComplete.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+			os.write(0xA4);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEAdmissionResponse != null) {
+			codeLength += uEAdmissionResponse.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+			os.write(0xA3);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEAdmissionRequest != null) {
+			codeLength += uEAdmissionRequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+			os.write(0xA2);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (cellConfigReport != null) {
+			codeLength += cellConfigReport.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+			os.write(0xA1);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (cellConfigRequest != null) {
+			codeLength += cellConfigRequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+			os.write(0xA0);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		throw new IOException("Error encoding CHOICE: No element of CHOICE was selected.");
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, null);
+	}
+
+	public int decode(InputStream is, BerTag berTag) throws IOException {
+
+		int codeLength = 0;
+		BerTag passedTag = berTag;
+
+		if (berTag == null) {
+			berTag = new BerTag();
+			codeLength += berTag.decode(is);
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			cellConfigRequest = new CellConfigRequest();
+			codeLength += cellConfigRequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			cellConfigReport = new CellConfigReport();
+			codeLength += cellConfigReport.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			uEAdmissionRequest = new UEAdmissionRequest();
+			codeLength += uEAdmissionRequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			uEAdmissionResponse = new UEAdmissionResponse();
+			codeLength += uEAdmissionResponse.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+			uEAttachComplete = new UEAttachComplete();
+			codeLength += uEAttachComplete.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+			uEAdmissionStatus = new UEAdmissionStatus();
+			codeLength += uEAdmissionStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+			uEReconfigInd = new UEReconfigInd();
+			codeLength += uEReconfigInd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+			uEReleaseInd = new UEReleaseInd();
+			codeLength += uEReleaseInd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+			bearerAdmissionRequest = new BearerAdmissionRequest();
+			codeLength += bearerAdmissionRequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 9)) {
+			bearerAdmissionResponse = new BearerAdmissionResponse();
+			codeLength += bearerAdmissionResponse.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 10)) {
+			bearerAdmissionStatus = new BearerAdmissionStatus();
+			codeLength += bearerAdmissionStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 11)) {
+			bearerReleaseInd = new BearerReleaseInd();
+			codeLength += bearerReleaseInd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 12)) {
+			uECapabilityEnquiry = new UECapabilityEnquiry();
+			codeLength += uECapabilityEnquiry.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 13)) {
+			uECapabilityInfo = new UECapabilityInfo();
+			codeLength += uECapabilityInfo.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 14)) {
+			hORequest = new HORequest();
+			codeLength += hORequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 15)) {
+			hOFailure = new HOFailure();
+			codeLength += hOFailure.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 16)) {
+			hOComplete = new HOComplete();
+			codeLength += hOComplete.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 17)) {
+			rXSigMeasConfig = new RXSigMeasConfig();
+			codeLength += rXSigMeasConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 18)) {
+			rXSigMeasReport = new RXSigMeasReport();
+			codeLength += rXSigMeasReport.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 19)) {
+			l2MeasConfig = new L2MeasConfig();
+			codeLength += l2MeasConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 20)) {
+			radioMeasReportPerUE = new RadioMeasReportPerUE();
+			codeLength += radioMeasReportPerUE.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 21)) {
+			radioMeasReportPerCell = new RadioMeasReportPerCell();
+			codeLength += radioMeasReportPerCell.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 22)) {
+			schedMeasReportPerUE = new SchedMeasReportPerUE();
+			codeLength += schedMeasReportPerUE.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 23)) {
+			schedMeasReportPerCell = new SchedMeasReportPerCell();
+			codeLength += schedMeasReportPerCell.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 24)) {
+			pDCPMeasReportPerUe = new PDCPMeasReportPerUe();
+			codeLength += pDCPMeasReportPerUe.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 25)) {
+			xICICConfig = new XICICConfig();
+			codeLength += xICICConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 26)) {
+			rRMConfig = new RRMConfig();
+			codeLength += rRMConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 27)) {
+			rRMConfigStatus = new RRMConfigStatus();
+			codeLength += rRMConfigStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 28)) {
+			scellAdd = new ScellAdd();
+			codeLength += scellAdd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 29)) {
+			scellAddStatus = new ScellAddStatus();
+			codeLength += scellAddStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 30)) {
+			scellDelete = new ScellDelete();
+			codeLength += scellDelete.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 31)) {
+			seNBAdd = new SeNBAdd();
+			codeLength += seNBAdd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 32)) {
+			seNBAddStatus = new SeNBAddStatus();
+			codeLength += seNBAddStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 33)) {
+			seNBDelete = new SeNBDelete();
+			codeLength += seNBDelete.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 34)) {
+			trafficSplitConfig = new TrafficSplitConfig();
+			codeLength += trafficSplitConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (passedTag != null) {
+			return 0;
+		}
+
+		throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		if (cellConfigRequest != null) {
+			sb.append("\"cellConfigRequest\": ");
+			cellConfigRequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (cellConfigReport != null) {
+			sb.append("\"cellConfigReport\": ");
+			cellConfigReport.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEAdmissionRequest != null) {
+			sb.append("\"uEAdmissionRequest\": ");
+			uEAdmissionRequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEAdmissionResponse != null) {
+			sb.append("\"uEAdmissionResponse\": ");
+			uEAdmissionResponse.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEAttachComplete != null) {
+			sb.append("\"uEAttachComplete\": ");
+			uEAttachComplete.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEAdmissionStatus != null) {
+			sb.append("\"uEAdmissionStatus\": ");
+			uEAdmissionStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEReconfigInd != null) {
+			sb.append("\"uEReconfigInd\": ");
+			uEReconfigInd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEReleaseInd != null) {
+			sb.append("\"uEReleaseInd\": ");
+			uEReleaseInd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerAdmissionRequest != null) {
+			sb.append("\"bearerAdmissionRequest\": ");
+			bearerAdmissionRequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerAdmissionResponse != null) {
+			sb.append("\"bearerAdmissionResponse\": ");
+			bearerAdmissionResponse.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerAdmissionStatus != null) {
+			sb.append("\"bearerAdmissionStatus\": ");
+			bearerAdmissionStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerReleaseInd != null) {
+			sb.append("\"bearerReleaseInd\": ");
+			bearerReleaseInd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uECapabilityEnquiry != null) {
+			sb.append("\"uECapabilityEnquiry\": ");
+			uECapabilityEnquiry.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uECapabilityInfo != null) {
+			sb.append("\"uECapabilityInfo\": ");
+			uECapabilityInfo.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (hORequest != null) {
+			sb.append("\"hORequest\": ");
+			hORequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (hOFailure != null) {
+			sb.append("\"hOFailure\": ");
+			hOFailure.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (hOComplete != null) {
+			sb.append("\"hOComplete\": ");
+			hOComplete.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rXSigMeasConfig != null) {
+			sb.append("\"rXSigMeasConfig\": ");
+			rXSigMeasConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rXSigMeasReport != null) {
+			sb.append("\"rXSigMeasReport\": ");
+			rXSigMeasReport.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (l2MeasConfig != null) {
+			sb.append("\"l2MeasConfig\": ");
+			l2MeasConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (radioMeasReportPerUE != null) {
+			sb.append("\"radioMeasReportPerUE\": ");
+			radioMeasReportPerUE.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (radioMeasReportPerCell != null) {
+			sb.append("\"radioMeasReportPerCell\": ");
+			radioMeasReportPerCell.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (schedMeasReportPerUE != null) {
+			sb.append("\"schedMeasReportPerUE\": ");
+			schedMeasReportPerUE.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (schedMeasReportPerCell != null) {
+			sb.append("\"schedMeasReportPerCell\": ");
+			schedMeasReportPerCell.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (pDCPMeasReportPerUe != null) {
+			sb.append("\"pDCPMeasReportPerUe\": ");
+			pDCPMeasReportPerUe.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (xICICConfig != null) {
+			sb.append("\"xICICConfig\": ");
+			xICICConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rRMConfig != null) {
+			sb.append("\"rRMConfig\": ");
+			rRMConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rRMConfigStatus != null) {
+			sb.append("\"rRMConfigStatus\": ");
+			rRMConfigStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (scellAdd != null) {
+			sb.append("\"scellAdd\": ");
+			scellAdd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (scellAddStatus != null) {
+			sb.append("\"scellAddStatus\": ");
+			scellAddStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (scellDelete != null) {
+			sb.append("\"scellDelete\": ");
+			scellDelete.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (seNBAdd != null) {
+			sb.append("\"seNBAdd\": ");
+			seNBAdd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (seNBAddStatus != null) {
+			sb.append("\"seNBAddStatus\": ");
+			seNBAddStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (seNBDelete != null) {
+			sb.append("\"seNBDelete\": ");
+			seNBDelete.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (trafficSplitConfig != null) {
+			sb.append("\"trafficSplitConfig\": ");
+			trafficSplitConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		sb.append("<none>");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/XrancPduHdr.java b/src/main/java/org.onosproject.xran/codecs/pdu/XrancPduHdr.java
new file mode 100644
index 0000000..63480d4
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/XrancPduHdr.java
@@ -0,0 +1,166 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.0 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.pdu;
+
+import org.openmuc.jasn1.ber.BerByteArrayOutputStream;
+import org.openmuc.jasn1.ber.BerLength;
+import org.openmuc.jasn1.ber.BerTag;
+import org.openmuc.jasn1.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class XrancPduHdr implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private BerUTF8String ver = null;
+	private XrancApiID apiId = null;
+	
+	public XrancPduHdr() {
+	}
+
+	public XrancPduHdr(byte[] code) {
+		this.code = code;
+	}
+
+	public void setVer(BerUTF8String ver) {
+		this.ver = ver;
+	}
+
+	public BerUTF8String getVer() {
+		return ver;
+	}
+
+	public void setApiId(XrancApiID apiId) {
+		this.apiId = apiId;
+	}
+
+	public XrancApiID getApiId() {
+		return apiId;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += apiId.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ver.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			ver = new BerUTF8String();
+			subCodeLength += ver.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			apiId = new XrancApiID();
+			subCodeLength += apiId.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ver != null) {
+			sb.append("\"ver\": ").append(ver);
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (apiId != null) {
+			sb.append("\"apiId\": ").append(apiId);
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/src/main/java/org.onosproject.xran/codecs/pdu/package-info.java b/src/main/java/org.onosproject.xran/codecs/pdu/package-info.java
new file mode 100644
index 0000000..570aae0
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/pdu/package-info.java
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2015-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.codecs.pdu;
\ No newline at end of file
