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("}");
+	}
+
+}
+
