jackson, HTTP codes and JSON responses, xICIC/RRMConfig fix
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/BerByteArrayOutputStream.java b/src/main/java/org.onosproject.xran/codecs/ber/BerByteArrayOutputStream.java
new file mode 100644
index 0000000..e32f381
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/BerByteArrayOutputStream.java
@@ -0,0 +1,115 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+
+public class BerByteArrayOutputStream extends OutputStream {
+
+    private final boolean automaticResize;
+    public byte[] buffer;
+    public int index;
+
+    /**
+     * Creates a <code>BerByteArrayOutputStream</code> with a byte array of size <code>bufferSize</code>. The buffer
+     * will not be resized automatically. Use {@link #BerByteArrayOutputStream(int, boolean)} instead if you want the
+     * buffer to be dynamically resized.
+     *
+     * @param bufferSize the size of the underlying buffer
+     */
+    public BerByteArrayOutputStream(int bufferSize) {
+        this(new byte[bufferSize], bufferSize - 1, false);
+    }
+
+    public BerByteArrayOutputStream(int bufferSize, boolean automaticResize) {
+        this(new byte[bufferSize], bufferSize - 1, automaticResize);
+    }
+
+    public BerByteArrayOutputStream(byte[] buffer) {
+        this(buffer, buffer.length - 1, false);
+    }
+
+    public BerByteArrayOutputStream(byte[] buffer, int startingIndex) {
+        this(buffer, startingIndex, false);
+    }
+
+    public BerByteArrayOutputStream(byte[] buffer, int startingIndex, boolean automaticResize) {
+        if (buffer.length <= 0) {
+            throw new IllegalArgumentException("buffer size may not be <= 0");
+        }
+        this.buffer = buffer;
+        index = startingIndex;
+        this.automaticResize = automaticResize;
+    }
+
+    @Override
+    public void write(int arg0) throws IOException {
+        write((byte) arg0);
+    }
+
+    public void write(byte arg0) throws IOException {
+        try {
+            buffer[index] = arg0;
+        } catch (ArrayIndexOutOfBoundsException e) {
+            if (automaticResize) {
+                resize();
+                buffer[index] = arg0;
+            } else {
+                throw new ArrayIndexOutOfBoundsException("buffer.length = " + buffer.length);
+            }
+        }
+        index--;
+    }
+
+    private void resize() {
+        byte[] newBuffer = new byte[buffer.length * 2];
+        System.arraycopy(buffer, index + 1, newBuffer, buffer.length + index + 1, buffer.length - index - 1);
+        index += buffer.length;
+        buffer = newBuffer;
+
+    }
+
+    @Override
+    public void write(byte[] byteArray) throws IOException {
+        for (int i = byteArray.length - 1; i >= 0; i--) {
+            try {
+                buffer[index] = byteArray[i];
+            } catch (ArrayIndexOutOfBoundsException e) {
+                if (automaticResize) {
+                    resize();
+                    buffer[index] = byteArray[i];
+                } else {
+                    throw new ArrayIndexOutOfBoundsException("buffer.length = " + buffer.length);
+                }
+            }
+            index--;
+        }
+    }
+
+    /**
+     * Returns a new array containing the subarray of the stream array that contains the coded content.
+     *
+     * @return a new array containing the subarray of the stream array
+     */
+    public byte[] getArray() {
+        if (index == -1) {
+            return buffer;
+        }
+        int subBufferLength = buffer.length - index - 1;
+        byte[] subBuffer = new byte[subBufferLength];
+        System.arraycopy(buffer, index + 1, subBuffer, 0, subBufferLength);
+        return subBuffer;
+
+    }
+
+    public ByteBuffer getByteBuffer() {
+        return ByteBuffer.wrap(buffer, index + 1, buffer.length - (index + 1));
+    }
+
+    public void reset() {
+        index = buffer.length - 1;
+    }
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/BerLength.java b/src/main/java/org.onosproject.xran/codecs/ber/BerLength.java
new file mode 100644
index 0000000..8057a58
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/BerLength.java
@@ -0,0 +1,115 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerLength implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    public int val;
+
+    public BerLength() {
+    }
+
+    public static int skip(InputStream is) throws IOException {
+
+        int val = is.read();
+        if (val == -1) {
+            throw new EOFException("Unexpected end of input stream.");
+        }
+
+        if ((val & 0x80) == 0) {
+            return 1;
+        }
+
+        int lengthLength = val & 0x7f;
+
+        // check for indefinite length
+        if (lengthLength == 0) {
+            val = -1;
+            return 1;
+        }
+
+        if (lengthLength > 4) {
+            throw new IOException("Length is out of bound!");
+        }
+
+        for (int i = 0; i < lengthLength; i++) {
+            int nextByte = is.read();
+            if (nextByte == -1) {
+                throw new EOFException("Unexpected end of input stream.");
+            }
+        }
+
+        return lengthLength + 1;
+    }
+
+    public static int encodeLength(BerByteArrayOutputStream os, int length) throws IOException {
+        // the indefinite form is ignored for now
+
+        if (length <= 127) {
+            // this is the short form, it is coded differently than the long
+            // form for values > 127
+            os.write((byte) length);
+            return 1;
+        } else {
+            int numLengthBytes = 1;
+
+            while (((int) (Math.pow(2, 8 * numLengthBytes) - 1)) < length) {
+                numLengthBytes++;
+            }
+
+            for (int i = 0; i < numLengthBytes; i++) {
+                os.write((length >> 8 * i) & 0xff);
+            }
+
+            os.write(0x80 | numLengthBytes);
+
+            return 1 + numLengthBytes;
+        }
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+
+        val = is.read();
+        if (val == -1) {
+            throw new EOFException("Unexpected end of input stream.");
+        }
+
+        if ((val & 0x80) == 0) {
+            return 1;
+        }
+
+        int lengthLength = val & 0x7f;
+
+        // check for indefinite length
+        if (lengthLength == 0) {
+            val = -1;
+            return 1;
+        }
+
+        if (lengthLength > 4) {
+            throw new IOException("Length is out of bound!");
+        }
+
+        val = 0;
+
+        for (int i = 0; i < lengthLength; i++) {
+            int nextByte = is.read();
+            if (nextByte == -1) {
+                throw new EOFException("Unexpected end of input stream.");
+            }
+            val |= nextByte << (8 * (lengthLength - i - 1));
+        }
+
+        return lengthLength + 1;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/BerTag.java b/src/main/java/org.onosproject.xran/codecs/ber/BerTag.java
new file mode 100644
index 0000000..5d5df85
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/BerTag.java
@@ -0,0 +1,186 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerTag implements Serializable {
+
+    public static final int UNIVERSAL_CLASS = 0x00;
+    public static final int APPLICATION_CLASS = 0x40;
+    public static final int CONTEXT_CLASS = 0x80;
+    public static final int PRIVATE_CLASS = 0xc0;
+    public static final int PRIMITIVE = 0x00;
+    public static final int CONSTRUCTED = 0x20;
+    public static final int BOOLEAN_TAG = 1;
+    public static final int INTEGER_TAG = 2;
+    public static final int BIT_STRING_TAG = 3;
+    public static final int OCTET_STRING_TAG = 4;
+    public static final int NULL_TAG = 5;
+    public static final int OBJECT_IDENTIFIER_TAG = 6;
+    public static final int OBJECT_DESCRIPTOR_TAG = 7;
+    public static final int REAL_TAG = 9;
+    public static final int ENUMERATED_TAG = 10;
+    public static final int EMBEDDED_PDV_TAG = 11;
+    public static final int UTF8_STRING_TAG = 12;
+    public static final int TIME_TAG = 14;
+    public static final int NUMERIC_STRING_TAG = 18;
+    public static final int PRINTABLE_STRING_TAG = 19;
+    public static final int TELETEX_STRING_TAG = 20;
+    public static final int VIDEOTEX_STRING_TAG = 21;
+    public static final int IA5_STRING_TAG = 22;
+    public static final int UTC_TIME_TAG = 23;
+    public static final int GENERALIZED_TIME_TAG = 24;
+    public static final int GRAPHIC_STRING_TAG = 25;
+    public static final int VISIBLE_STRING_TAG = 26;
+    public static final int GENERAL_STRING_TAG = 27;
+    public static final int UNIVERSAL_STRING_TAG = 28;
+    public static final int BMP_STRING_TAG = 30;
+    public static final int DATE_TAG = 31;
+    public static final int TIME_OF_DAY_TAG = 32;
+    public static final int DATE_TIME_TAG = 33;
+    public static final int DURATION_TAG = 34;
+    private static final long serialVersionUID = 1L;
+    public byte[] tagBytes = null;
+    public int tagClass;
+    public int primitive;
+    public int tagNumber;
+
+    public BerTag(int identifierClass, int primitive, int tagNumber) {
+        this.tagClass = identifierClass;
+        this.primitive = primitive;
+        this.tagNumber = tagNumber;
+        code();
+    }
+
+    public BerTag() {
+    }
+
+    private void code() {
+        if (tagNumber < 31) {
+            tagBytes = new byte[1];
+            tagBytes[0] = (byte) (tagClass | primitive | tagNumber);
+        } else {
+            int tagLength = 1;
+            while (tagNumber > (Math.pow(2, (7 * tagLength)) - 1)) {
+                tagLength++;
+            }
+
+            tagBytes = new byte[1 + tagLength];
+            tagBytes[0] = (byte) (tagClass | primitive | 31);
+
+            for (int j = 1; j <= (tagLength - 1); j++) {
+                tagBytes[j] = (byte) (((tagNumber >> (7 * (tagLength - j))) & 0xff) | 0x80);
+            }
+
+            tagBytes[tagLength] = (byte) (tagNumber & 0x7f);
+
+        }
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        if (tagBytes == null) {
+            code();
+        }
+        for (int i = (tagBytes.length - 1); i >= 0; i--) {
+            os.write(tagBytes[i]);
+        }
+        return tagBytes.length;
+    }
+
+    public int decode(InputStream is) throws IOException {
+        int nextByte = is.read();
+        if (nextByte == -1) {
+            throw new EOFException("Unexpected end of input stream.");
+        }
+
+        tagClass = nextByte & 0xC0;
+        primitive = nextByte & 0x20;
+        tagNumber = nextByte & 0x1f;
+
+        int codeLength = 1;
+
+        if (tagNumber == 0x1f) {
+            tagNumber = 0;
+
+            int counter = 0;
+
+            do {
+                nextByte = is.read();
+                if (nextByte == -1) {
+                    throw new EOFException("Unexpected end of input stream.");
+                }
+
+                codeLength++;
+                if (counter >= 6) {
+                    throw new IOException("Invalid Tag");
+                }
+                tagNumber = tagNumber << 7;
+                tagNumber |= (nextByte & 0x7f);
+                counter++;
+            } while ((nextByte & 0x80) == 0x80);
+
+        }
+
+        return codeLength;
+    }
+
+    /**
+     * Decodes the Identifier from the ByteArrayInputStream and throws an Exception if it is not equal to itself.
+     * Returns the number of bytes read from the InputStream.
+     *
+     * @param is the input stream to read the identifier from.
+     * @return the length of the identifier read.
+     * @throws IOException if an exception occurs reading the identifier from the stream.
+     */
+    public int decodeAndCheck(InputStream is) throws IOException {
+
+        for (Byte identifierByte : tagBytes) {
+            int nextByte = is.read();
+            if (nextByte == -1) {
+                throw new EOFException("Unexpected end of input stream.");
+            }
+
+            if (nextByte != (identifierByte & 0xff)) {
+                throw new IOException("Identifier does not match!");
+            }
+        }
+        return tagBytes.length;
+    }
+
+    public boolean equals(int identifierClass, int primitive, int tagNumber) {
+        return (this.tagNumber == tagNumber && this.tagClass == identifierClass && this.primitive == primitive);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof BerTag)) {
+            return false;
+        }
+        if (obj == this) {
+            return true;
+        }
+        BerTag berIdentifier = (BerTag) obj;
+        return (tagNumber == berIdentifier.tagNumber && tagClass == berIdentifier.tagClass
+                && primitive == berIdentifier.primitive);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 17;
+        hash = hash * 31 + tagNumber;
+        hash = hash * 31 + tagClass;
+        hash = hash * 31 + primitive;
+        return hash;
+    }
+
+    @Override
+    public String toString() {
+        return "identifier class: " + tagClass + ", primitive: " + primitive + ", tag number: " + tagNumber;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/internal/Util.java b/src/main/java/org.onosproject.xran/codecs/ber/internal/Util.java
new file mode 100644
index 0000000..c2d64cc
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/internal/Util.java
@@ -0,0 +1,28 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.internal;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class Util {
+
+    public static void readFully(InputStream is, byte[] buffer) throws IOException {
+        readFully(is, buffer, 0, buffer.length);
+    }
+
+    public static void readFully(InputStream is, byte[] buffer, int off, int len) throws IOException {
+        do {
+            int bytesRead = is.read(buffer, off, len);
+            if (bytesRead == -1) {
+                throw new EOFException("Unexpected end of input stream.");
+            }
+
+            len -= bytesRead;
+            off += bytesRead;
+        } while (len > 0);
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerAny.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerAny.java
new file mode 100644
index 0000000..db5daee
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerAny.java
@@ -0,0 +1,75 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.internal.Util;
+import org.onosproject.xran.codecs.util.HexConverter;
+
+import javax.xml.bind.DatatypeConverter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerAny implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    public byte[] value;
+
+    public BerAny() {
+    }
+
+    public BerAny(byte[] value) {
+        this.value = value;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        os.write(value);
+        return value.length;
+    }
+
+    public int decode(InputStream is) throws IOException {
+
+        return decode(is, null);
+    }
+
+    public int decode(InputStream is, BerTag tag) throws IOException {
+
+        int decodedLength = 0;
+
+        int tagLength;
+
+        if (tag == null) {
+            tag = new BerTag();
+            tagLength = tag.decode(is);
+            decodedLength += tagLength;
+        } else {
+            tagLength = tag.encode(new BerByteArrayOutputStream(10));
+        }
+
+        BerLength lengthField = new BerLength();
+        int lengthLength = lengthField.decode(is);
+        decodedLength += lengthLength + lengthField.val;
+
+        value = new byte[tagLength + lengthLength + lengthField.val];
+
+        Util.readFully(is, value, tagLength + lengthLength, lengthField.val);
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(value, tagLength + lengthLength - 1);
+        BerLength.encodeLength(os, lengthField.val);
+        tag.encode(os);
+
+        return decodedLength;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return DatatypeConverter.printHexBinary(value);
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerBitString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerBitString.java
new file mode 100644
index 0000000..9ebfe14
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerBitString.java
@@ -0,0 +1,131 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.internal.Util;
+import org.onosproject.xran.codecs.util.HexConverter;
+
+import javax.xml.bind.DatatypeConverter;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerBitString implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BIT_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+    @JsonIgnore
+    public byte[] code = null;
+
+    public byte[] value;
+    public int numBits;
+
+    public BerBitString() {
+    }
+
+    public BerBitString(byte[] value, int numBits) {
+
+        if (value == null) {
+            throw new NullPointerException("value cannot be null");
+        }
+        if (numBits < 0) {
+            throw new IllegalArgumentException("numBits cannot be negative.");
+        }
+        if (numBits > (value.length * 8)) {
+            throw new IllegalArgumentException("'value' is too short to hold all bits.");
+        }
+
+        this.value = value;
+        this.numBits = numBits;
+
+    }
+
+    public BerBitString(byte[] code) {
+        this.code = code;
+    }
+
+    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;
+        }
+
+        for (int i = (value.length - 1); i >= 0; i--) {
+            os.write(value[i]);
+        }
+        os.write(value.length * 8 - numBits);
+
+        int codeLength = value.length + 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 {
+        // could be encoded in primitiv and constructed mode
+        // only primitiv mode is implemented
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        value = new byte[length.val - 1];
+
+        int unusedBits = is.read();
+        if (unusedBits == -1) {
+            throw new EOFException("Unexpected end of input stream.");
+        }
+        if (unusedBits > 7) {
+            throw new IOException(
+                    "Number of unused bits in bit string expected to be less than 8 but is: " + unusedBits);
+        }
+
+        numBits = (value.length * 8) - unusedBits;
+
+        if (value.length > 0) {
+            Util.readFully(is, value);
+        }
+
+        codeLength += value.length + 1;
+
+        return codeLength;
+
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return DatatypeConverter.printHexBinary(value);
+    }
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerBoolean.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerBoolean.java
new file mode 100644
index 0000000..14e4e5b
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerBoolean.java
@@ -0,0 +1,115 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerBoolean implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BOOLEAN_TAG);
+    private static final long serialVersionUID = 1L;
+    @JsonIgnore
+    public byte[] code = null;
+
+    public boolean value;
+
+    public BerBoolean() {
+    }
+
+    public BerBoolean(byte[] code) {
+        this.code = code;
+    }
+
+    public BerBoolean(boolean value) {
+        this.value = value;
+    }
+
+    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 = 1;
+
+        if (value) {
+            os.write(0xff);
+        } else {
+            os.write(0);
+        }
+
+        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;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        if (length.val != 1) {
+            throw new IOException("Decoded length of BerBoolean is not correct");
+        }
+
+        int nextByte = is.read();
+        if (nextByte == -1) {
+            throw new EOFException("Unexpected end of input stream.");
+        }
+
+        codeLength++;
+        if (nextByte == 0) {
+            value = false;
+        } else {
+            value = true;
+        }
+
+        return codeLength;
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return "" + value;
+    }
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerDate.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerDate.java
new file mode 100644
index 0000000..e6c3362
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerDate.java
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+public class BerDate extends BerTime {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DATE_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerDate() {
+    }
+
+    public BerDate(byte[] value) {
+        super(value);
+    }
+
+    public BerDate(String valueAsString) throws UnsupportedEncodingException {
+        super(valueAsString);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerDateTime.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerDateTime.java
new file mode 100644
index 0000000..7196707
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerDateTime.java
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+public class BerDateTime extends BerTime {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DATE_TIME_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerDateTime() {
+    }
+
+    public BerDateTime(byte[] value) {
+        super(value);
+    }
+
+    public BerDateTime(String valueAsString) throws UnsupportedEncodingException {
+        super(valueAsString);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerDuration.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerDuration.java
new file mode 100644
index 0000000..6203472
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerDuration.java
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+public class BerDuration extends BerTime {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.DURATION_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerDuration() {
+    }
+
+    public BerDuration(byte[] value) {
+        super(value);
+    }
+
+    public BerDuration(String valueAsString) throws UnsupportedEncodingException {
+        super(valueAsString);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerEmbeddedPdv.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerEmbeddedPdv.java
new file mode 100644
index 0000000..e9bc9af
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerEmbeddedPdv.java
@@ -0,0 +1,747 @@
+/**
+ * This class file was automatically generated by jASN1 v1.7.2-SNAPSHOT (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.string.BerObjectDescriptor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerEmbeddedPdv implements Serializable {
+
+    public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 11);
+    private static final long serialVersionUID = 1L;
+    @JsonIgnore public byte[] code = null;
+    private Identification identification = null;
+    private BerObjectDescriptor dataValueDescriptor = null;
+    private BerOctetString dataValue = null;
+    public BerEmbeddedPdv() {
+    }
+
+    public BerEmbeddedPdv(byte[] code) {
+        this.code = code;
+    }
+
+    public Identification getIdentification() {
+        return identification;
+    }
+
+    public void setIdentification(Identification identification) {
+        this.identification = identification;
+    }
+
+    public BerObjectDescriptor getDataValueDescriptor() {
+        return dataValueDescriptor;
+    }
+
+    public void setDataValueDescriptor(BerObjectDescriptor dataValueDescriptor) {
+        this.dataValueDescriptor = dataValueDescriptor;
+    }
+
+    public BerOctetString getDataValue() {
+        return dataValue;
+    }
+
+    public void setDataValue(BerOctetString dataValue) {
+        this.dataValue = dataValue;
+    }
+
+    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;
+
+        codeLength += dataValue.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        if (dataValueDescriptor != null) {
+            codeLength += dataValueDescriptor.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+            os.write(0x81);
+            codeLength += 1;
+        }
+
+        sublength = identification.encode(os);
+        codeLength += sublength;
+        codeLength += BerLength.encodeLength(os, sublength);
+        // 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)) {
+            subCodeLength += length.decode(is);
+            identification = new Identification();
+            subCodeLength += identification.decode(is, null);
+            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)) {
+            dataValueDescriptor = new BerObjectDescriptor();
+            subCodeLength += dataValueDescriptor.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            dataValue = new BerOctetString();
+            subCodeLength += dataValue.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();
+    }
+
+    @JsonValue
+    @Override
+    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 (identification != null) {
+            sb.append("identification: ");
+            identification.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("identification: <empty-required-field>");
+        }
+
+        if (dataValueDescriptor != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("dataValueDescriptor: ").append(dataValueDescriptor);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (dataValue != null) {
+            sb.append("dataValue: ").append(dataValue);
+        } else {
+            sb.append("dataValue: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class Identification implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        @JsonIgnore
+        public byte[] code = null;
+        private Syntaxes syntaxes = null;
+        private BerObjectIdentifier syntax = null;
+        private BerInteger presentationContextId = null;
+        private ContextNegotiation contextNegotiation = null;
+        private BerObjectIdentifier transferSyntax = null;
+        private BerNull fixed = null;
+        public Identification() {
+        }
+        public Identification(byte[] code) {
+            this.code = code;
+        }
+
+        public Syntaxes getSyntaxes() {
+            return syntaxes;
+        }
+
+        public void setSyntaxes(Syntaxes syntaxes) {
+            this.syntaxes = syntaxes;
+        }
+
+        public BerObjectIdentifier getSyntax() {
+            return syntax;
+        }
+
+        public void setSyntax(BerObjectIdentifier syntax) {
+            this.syntax = syntax;
+        }
+
+        public BerInteger getPresentationContextId() {
+            return presentationContextId;
+        }
+
+        public void setPresentationContextId(BerInteger presentationContextId) {
+            this.presentationContextId = presentationContextId;
+        }
+
+        public ContextNegotiation getContextNegotiation() {
+            return contextNegotiation;
+        }
+
+        public void setContextNegotiation(ContextNegotiation contextNegotiation) {
+            this.contextNegotiation = contextNegotiation;
+        }
+
+        public BerObjectIdentifier getTransferSyntax() {
+            return transferSyntax;
+        }
+
+        public void setTransferSyntax(BerObjectIdentifier transferSyntax) {
+            this.transferSyntax = transferSyntax;
+        }
+
+        public BerNull getFixed() {
+            return fixed;
+        }
+
+        public void setFixed(BerNull fixed) {
+            this.fixed = fixed;
+        }
+
+        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 (fixed != null) {
+                codeLength += fixed.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 5
+                os.write(0x85);
+                codeLength += 1;
+                return codeLength;
+            }
+
+            if (transferSyntax != null) {
+                codeLength += transferSyntax.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 4
+                os.write(0x84);
+                codeLength += 1;
+                return codeLength;
+            }
+
+            if (contextNegotiation != null) {
+                codeLength += contextNegotiation.encode(os, false);
+                // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+                os.write(0xA3);
+                codeLength += 1;
+                return codeLength;
+            }
+
+            if (presentationContextId != null) {
+                codeLength += presentationContextId.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+                os.write(0x82);
+                codeLength += 1;
+                return codeLength;
+            }
+
+            if (syntax != null) {
+                codeLength += syntax.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+                os.write(0x81);
+                codeLength += 1;
+                return codeLength;
+            }
+
+            if (syntaxes != null) {
+                codeLength += syntaxes.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)) {
+                syntaxes = new Syntaxes();
+                codeLength += syntaxes.decode(is, false);
+                return codeLength;
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+                syntax = new BerObjectIdentifier();
+                codeLength += syntax.decode(is, false);
+                return codeLength;
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+                presentationContextId = new BerInteger();
+                codeLength += presentationContextId.decode(is, false);
+                return codeLength;
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+                contextNegotiation = new ContextNegotiation();
+                codeLength += contextNegotiation.decode(is, false);
+                return codeLength;
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+                transferSyntax = new BerObjectIdentifier();
+                codeLength += transferSyntax.decode(is, false);
+                return codeLength;
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
+                fixed = new BerNull();
+                codeLength += fixed.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();
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            if (syntaxes != null) {
+                sb.append("syntaxes: ");
+                syntaxes.appendAsString(sb, indentLevel + 1);
+                return;
+            }
+
+            if (syntax != null) {
+                sb.append("syntax: ").append(syntax);
+                return;
+            }
+
+            if (presentationContextId != null) {
+                sb.append("presentationContextId: ").append(presentationContextId);
+                return;
+            }
+
+            if (contextNegotiation != null) {
+                sb.append("contextNegotiation: ");
+                contextNegotiation.appendAsString(sb, indentLevel + 1);
+                return;
+            }
+
+            if (transferSyntax != null) {
+                sb.append("transferSyntax: ").append(transferSyntax);
+                return;
+            }
+
+            if (fixed != null) {
+                sb.append("fixed: ").append(fixed);
+                return;
+            }
+
+            sb.append("<none>");
+        }
+
+        public static class Syntaxes implements Serializable {
+
+            public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+            private static final long serialVersionUID = 1L;
+            @JsonIgnore public byte[] code = null;
+            private BerObjectIdentifier abstract_ = null;
+            private BerObjectIdentifier transfer = null;
+
+            public Syntaxes() {
+            }
+
+            public Syntaxes(byte[] code) {
+                this.code = code;
+            }
+
+            public BerObjectIdentifier getAbstract() {
+                return abstract_;
+            }
+
+            public void setAbstract(BerObjectIdentifier abstract_) {
+                this.abstract_ = abstract_;
+            }
+
+            public BerObjectIdentifier getTransfer() {
+                return transfer;
+            }
+
+            public void setTransfer(BerObjectIdentifier transfer) {
+                this.transfer = transfer;
+            }
+
+            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 += transfer.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+                os.write(0x81);
+                codeLength += 1;
+
+                codeLength += abstract_.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)) {
+                    abstract_ = new BerObjectIdentifier();
+                    subCodeLength += abstract_.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)) {
+                    transfer = new BerObjectIdentifier();
+                    subCodeLength += transfer.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();
+            }
+
+            @Override
+            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 (abstract_ != null) {
+                    sb.append("abstract_: ").append(abstract_);
+                } else {
+                    sb.append("abstract_: <empty-required-field>");
+                }
+
+                sb.append(",\n");
+                for (int i = 0; i < indentLevel + 1; i++) {
+                    sb.append("\t");
+                }
+                if (transfer != null) {
+                    sb.append("transfer: ").append(transfer);
+                } else {
+                    sb.append("transfer: <empty-required-field>");
+                }
+
+                sb.append("\n");
+                for (int i = 0; i < indentLevel; i++) {
+                    sb.append("\t");
+                }
+                sb.append("}");
+            }
+
+        }
+
+        public static class ContextNegotiation implements Serializable {
+
+            public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+            private static final long serialVersionUID = 1L;
+            @JsonIgnore public byte[] code = null;
+            private BerInteger presentationContextId = null;
+            private BerObjectIdentifier transferSyntax = null;
+
+            public ContextNegotiation() {
+            }
+
+            public ContextNegotiation(byte[] code) {
+                this.code = code;
+            }
+
+            public BerInteger getPresentationContextId() {
+                return presentationContextId;
+            }
+
+            public void setPresentationContextId(BerInteger presentationContextId) {
+                this.presentationContextId = presentationContextId;
+            }
+
+            public BerObjectIdentifier getTransferSyntax() {
+                return transferSyntax;
+            }
+
+            public void setTransferSyntax(BerObjectIdentifier transferSyntax) {
+                this.transferSyntax = transferSyntax;
+            }
+
+            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 += transferSyntax.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+                os.write(0x81);
+                codeLength += 1;
+
+                codeLength += presentationContextId.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)) {
+                    presentationContextId = new BerInteger();
+                    subCodeLength += presentationContextId.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)) {
+                    transferSyntax = new BerObjectIdentifier();
+                    subCodeLength += transferSyntax.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();
+            }
+
+            @Override
+            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 (presentationContextId != null) {
+                    sb.append("presentationContextId: ").append(presentationContextId);
+                } else {
+                    sb.append("presentationContextId: <empty-required-field>");
+                }
+
+                sb.append(",\n");
+                for (int i = 0; i < indentLevel + 1; i++) {
+                    sb.append("\t");
+                }
+                if (transferSyntax != null) {
+                    sb.append("transferSyntax: ").append(transferSyntax);
+                } else {
+                    sb.append("transferSyntax: <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/ber/types/BerEnum.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerEnum.java
new file mode 100644
index 0000000..ea97be5
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerEnum.java
@@ -0,0 +1,59 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+
+public class BerEnum extends BerInteger {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.ENUMERATED_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerEnum() {
+    }
+
+    public BerEnum(byte[] code) {
+        this.code = code;
+    }
+
+    public BerEnum(BigInteger val) {
+        this.value = val;
+    }
+
+    public BerEnum(long val) {
+        this.value = BigInteger.valueOf(val);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerGeneralizedTime.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerGeneralizedTime.java
new file mode 100644
index 0000000..00f3340
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerGeneralizedTime.java
@@ -0,0 +1,133 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.string.BerVisibleString;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class BerGeneralizedTime extends BerVisibleString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GENERALIZED_TIME_TAG);
+    private static final long serialVersionUID = 1L;
+    /*
+     * Generalized time is one of the following (ITU-T X.680 08/2015): YYYYMMDDHH[MM[SS]][.fff] LocalTime
+     * YYYYMMDDHH[MM[SS]][.fff]Z UTC YYYYMMDDHH[MM[SS]][.fff]+-HH[MM] local time with time zone
+     *
+     * Regexp: ^ (?<year>\\d{4}) YYYY (?<month>\\d{2}) MM (?<day>\\d{2}) DD (?<hour>\\d{2}) HH ( [MM[SS]]
+     * (?<minute>\\d{2}) MM (?<second>\\d{2})? [SS] )? ([.,](?<frac>\\d+))? [.fff] (or [,fff]) (?<timezone> "" or "Z" or
+     * "+-HH[MM]" Z | ( "+-HH[MM]" [+-] "+-" \\d{2}(?<tzmin>\\d{2})? HH[MM] ) )? $
+     */
+    private final static String GENERALIZED_TIME_PATTERN = "^(?<year>\\d{4})(?<month>\\d{2})(?<day>\\d{2})(?<hour>\\d{2})((?<minute>\\d{2})(?<second>\\d{2})?)?([.,](?<frac>\\d+))?(?<timezone>Z|([+-]\\d{2}(?<tzmin>\\d{2})?))?$";
+    private final static Pattern generalizedTimePattern = Pattern.compile(GENERALIZED_TIME_PATTERN);
+
+    public BerGeneralizedTime() {
+    }
+
+    public BerGeneralizedTime(byte[] value) {
+        super(value);
+    }
+
+    public BerGeneralizedTime(String valueAsString) {
+        super(valueAsString);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+    Calendar asCalendar() throws ParseException {
+
+        Matcher matcher = generalizedTimePattern.matcher(toString());
+
+        if (!matcher.find()) {
+            throw new ParseException("", 0);
+        }
+
+        String mg, mgf;
+        int year = Integer.valueOf(matcher.group("year"));
+        int month = Integer.valueOf(matcher.group("month"));
+        month -= 1; // java.util.Calendar's month goes from 0 to 11
+        int day = Integer.valueOf(matcher.group("day"));
+        int hour = Integer.valueOf(matcher.group("hour"));
+
+        mg = matcher.group("minute");
+        mgf = matcher.group("frac");
+        int minute = 0, second = 0, millisec = 0;
+        double frac = mgf == null ? 0 : Double.valueOf("0." + mgf);
+        if (mg == null) {
+            // Missing minutes and seconds
+            if (mgf != null) {
+                // frac is a fraction of a hour
+                millisec = (int) Math.round(1000 * 60 * 60 * frac);
+            }
+        } else {
+            minute = Integer.valueOf(mg);
+            mg = matcher.group("second");
+            if (mg == null) {
+                // Missing seconds
+                if (mgf != null) {
+                    // frac is a fraction of a minute
+                    millisec = (int) Math.round(1000 * 60 * frac);
+                }
+            } else {
+                second = Integer.valueOf(mg);
+                if (mgf != null) {
+                    // frac is a fraction of a second
+                    millisec = (int) Math.round(1000 * frac);
+                }
+            }
+        }
+
+        mg = matcher.group("timezone");
+        String mgt = matcher.group("tzmin");
+        String timeZoneStr = mg == null ? TimeZone.getDefault().getID()
+                : (mg.equals("Z") ? "UTC" : (mgt == null ? "GMT" + mg + "00" : "GMT" + mg));
+        TimeZone timeZone = TimeZone.getTimeZone(timeZoneStr);
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.setLenient(true); // accept millisec greater than 999
+        calendar.set(year, month, day, hour, minute, second);
+        calendar.set(Calendar.MILLISECOND, millisec);
+        calendar.setTimeZone(timeZone);
+
+        return calendar;
+    }
+
+    Date asDate() throws ParseException {
+        return asCalendar().getTime();
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerInteger.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerInteger.java
new file mode 100644
index 0000000..c22cd4d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerInteger.java
@@ -0,0 +1,128 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.internal.Util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+
+public class BerInteger implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.INTEGER_TAG);
+    private static final long serialVersionUID = 1L;
+    @JsonIgnore
+    public byte[] code = null;
+
+    public BigInteger value;
+
+    public BerInteger() {
+    }
+
+    public BerInteger(byte[] code) {
+        this.code = code;
+    }
+
+    public BerInteger(BigInteger val) {
+        this.value = val;
+    }
+
+    public BerInteger(long val) {
+        this.value = BigInteger.valueOf(val);
+    }
+
+    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;
+        }
+
+        byte[] encoded = value.toByteArray();
+        int codeLength = encoded.length;
+        os.write(encoded);
+
+        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;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        if (length.val < 1) {
+            throw new IOException("Decoded length of BerInteger is not correct");
+        }
+
+        byte[] byteCode = new byte[length.val];
+        Util.readFully(is, byteCode);
+
+        codeLength += length.val;
+
+        value = new BigInteger(byteCode);
+
+        return codeLength;
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return "" + value;
+    }
+
+    public byte byteValue() {
+        return value.byteValue();
+    }
+
+    public short shortValue() {
+        return value.shortValue();
+    }
+
+    public int intValue() {
+        return value.intValue();
+    }
+
+    public long longValue() {
+        return value.longValue();
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerNull.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerNull.java
new file mode 100644
index 0000000..6437d0b
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerNull.java
@@ -0,0 +1,72 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerNull implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.NULL_TAG);
+    private static final long serialVersionUID = 1L;
+    @JsonIgnore
+    public byte[] code = null;
+
+    public BerNull() {
+    }
+
+    public BerNull(byte[] code) {
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = BerLength.encodeLength(os, 0);
+
+        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;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        if (length.val != 0) {
+            throw new IOException("Decoded length of BerNull is not correct");
+        }
+
+        return codeLength;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return "ASN1_NULL";
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerObjectIdentifier.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerObjectIdentifier.java
new file mode 100644
index 0000000..d1cf4ba
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerObjectIdentifier.java
@@ -0,0 +1,209 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.internal.Util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+public class BerObjectIdentifier implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OBJECT_IDENTIFIER_TAG);
+    private static final long serialVersionUID = 1L;
+    @JsonIgnore
+    public byte[] code = null;
+
+    public int[] value;
+
+    public BerObjectIdentifier() {
+    }
+
+    public BerObjectIdentifier(byte[] code) {
+        this.code = code;
+    }
+
+    public BerObjectIdentifier(int[] value) {
+        if ((value.length < 2) || ((value[0] == 0 || value[0] == 1) && (value[1] > 39)) || value[0] > 2) {
+            throw new IllegalArgumentException("invalid object identifier components");
+        }
+        for (int objectIdentifierComponent : value) {
+            if (objectIdentifierComponent < 0) {
+                throw new IllegalArgumentException("invalid object identifier components");
+            }
+        }
+
+        this.value = value;
+
+    }
+
+    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 firstSubidentifier = 40 * value[0] + value[1];
+
+        int subidentifier;
+
+        int codeLength = 0;
+
+        for (int i = (value.length - 1); i > 0; i--) {
+
+            if (i == 1) {
+                subidentifier = firstSubidentifier;
+            } else {
+                subidentifier = value[i];
+            }
+
+            // get length of subidentifier
+            int subIDLength = 1;
+            while (subidentifier > (Math.pow(2, (7 * subIDLength)) - 1)) {
+                subIDLength++;
+            }
+
+            os.write(subidentifier & 0x7f);
+
+            for (int j = 1; j <= (subIDLength - 1); j++) {
+                os.write(((subidentifier >> (7 * j)) & 0xff) | 0x80);
+            }
+
+            codeLength += subIDLength;
+        }
+
+        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;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        if (length.val == 0) {
+            value = new int[0];
+            return codeLength;
+        }
+
+        byte[] byteCode = new byte[length.val];
+        Util.readFully(is, byteCode);
+
+        codeLength += length.val;
+
+        List<Integer> objectIdentifierComponentsList = new ArrayList<>();
+
+        int subIDEndIndex = 0;
+        while ((byteCode[subIDEndIndex] & 0x80) == 0x80) {
+            if (subIDEndIndex >= (length.val - 1)) {
+                throw new IOException("Invalid Object Identifier");
+            }
+            subIDEndIndex++;
+        }
+
+        int subidentifier = 0;
+        for (int i = 0; i <= subIDEndIndex; i++) {
+            subidentifier |= (byteCode[i] << ((subIDEndIndex - i) * 7));
+        }
+
+        if (subidentifier < 40) {
+            objectIdentifierComponentsList.add(0);
+            objectIdentifierComponentsList.add(subidentifier);
+        } else if (subidentifier < 80) {
+            objectIdentifierComponentsList.add(1);
+            objectIdentifierComponentsList.add(subidentifier - 40);
+        } else {
+            objectIdentifierComponentsList.add(2);
+            objectIdentifierComponentsList.add(subidentifier - 80);
+        }
+
+        subIDEndIndex++;
+
+        while (subIDEndIndex < length.val) {
+            int subIDStartIndex = subIDEndIndex;
+
+            while ((byteCode[subIDEndIndex] & 0x80) == 0x80) {
+                if (subIDEndIndex == (length.val - 1)) {
+                    throw new IOException("Invalid Object Identifier");
+                }
+                subIDEndIndex++;
+            }
+            subidentifier = 0;
+            for (int j = subIDStartIndex; j <= subIDEndIndex; j++) {
+                subidentifier |= ((byteCode[j] & 0x7f) << ((subIDEndIndex - j) * 7));
+            }
+            objectIdentifierComponentsList.add(subidentifier);
+            subIDEndIndex++;
+        }
+
+        value = new int[objectIdentifierComponentsList.size()];
+        for (int i = 0; i < objectIdentifierComponentsList.size(); i++) {
+            value[i] = objectIdentifierComponentsList.get(i);
+        }
+
+        return codeLength;
+
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        if (value == null || value.length == 0) {
+            return "";
+        }
+
+        String objIDString = "";
+        objIDString += value[0];
+        for (int i = 1; i < value.length; i++) {
+            objIDString += "." + value[i];
+        }
+        return objIDString;
+    }
+
+    public BerObjectIdentifier append(int value) {
+        if (this.value == null) {
+            return new BerObjectIdentifier(new int[]{value});
+        }
+        int[] values = new int[this.value.length + 1];
+        for (int i = 0; i < this.value.length; ++i) {
+            values[i] = this.value[i];
+        }
+        values[values.length - 1] = value;
+        return new BerObjectIdentifier(values);
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerOctetString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerOctetString.java
new file mode 100644
index 0000000..906e060
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerOctetString.java
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.internal.Util;
+import org.onosproject.xran.codecs.util.HexConverter;
+
+import javax.xml.bind.DatatypeConverter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerOctetString implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OCTET_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+    public byte[] value;
+
+    public BerOctetString() {
+    }
+
+    public BerOctetString(byte[] value) {
+        this.value = value;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        os.write(value);
+        int codeLength = value.length;
+
+        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;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        value = new byte[length.val];
+
+        if (length.val != 0) {
+            Util.readFully(is, value);
+            codeLength += length.val;
+        }
+
+        return codeLength;
+
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return DatatypeConverter.printHexBinary(value);
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerReal.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerReal.java
new file mode 100644
index 0000000..08f8d06
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerReal.java
@@ -0,0 +1,233 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.internal.Util;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.math.BigInteger;
+
+public class BerReal implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.REAL_TAG);
+    private static final long serialVersionUID = 1L;
+    @JsonIgnore
+    public byte[] code = null;
+
+    public double value;
+
+    public BerReal() {
+    }
+
+    public BerReal(byte[] code) {
+        this.code = code;
+    }
+
+    public BerReal(double value) {
+        this.value = value;
+    }
+
+    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 = encodeValue(os);
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    private int encodeValue(BerByteArrayOutputStream os) throws IOException {
+
+        // explained in Annex C and Ch. 8.5 of X.690
+
+        // we use binary encoding, with base 2 and F==0
+        // F is only needed when encoding with base 8 or 16
+
+        long longBits = Double.doubleToLongBits(value);
+
+        boolean isNegative = (longBits & 0x8000000000000000L) == 0x8000000000000000L;
+
+        int exponent = ((int) (longBits >> 52)) & 0x7ff;
+
+        long mantissa = (longBits & 0x000fffffffffffffL) | 0x0010000000000000L;
+
+        if (exponent == 0x7ff) {
+            if (mantissa == 0x0010000000000000L) {
+                if (isNegative) {
+                    // - infinity
+                    os.write(0x41);
+                } else {
+                    // + infinity
+                    os.write(0x40);
+                }
+                return 1;
+            } else {
+                throw new IOException("NAN not supported");
+            }
+        }
+
+        if ((exponent == 0 && mantissa == 0x0010000000000000L)) {
+            // zero
+            return 0;
+        }
+
+        // because IEEE double-precision format is (-1)^sign * 1.b51b50..b0 * 2^(e-1023) we need to subtract 1023 and 52
+        // from the exponent to get an exponent corresponding to an integer matissa as need here.
+        exponent -= 1075; // 1023 + 52 = 1075
+
+        // trailing zeros of the mantissa should be removed. Therefor find out how much the mantissa can be shifted and
+        // the exponent can be increased
+        int exponentIncr = 0;
+        while (((mantissa >> exponentIncr) & 0xff) == 0x00) {
+            exponentIncr += 8;
+        }
+        while (((mantissa >> exponentIncr) & 0x01) == 0x00) {
+            exponentIncr++;
+        }
+
+        exponent += exponentIncr;
+        mantissa >>= exponentIncr;
+
+        int mantissaLength = (Long.SIZE - Long.numberOfLeadingZeros(mantissa) + 7) / 8;
+
+        for (int i = 0; i < mantissaLength; i++) {
+            os.write((int) (mantissa >> (8 * i)));
+        }
+        int codeLength = mantissaLength;
+
+        byte[] exponentBytes = BigInteger.valueOf(exponent).toByteArray();
+        os.write(exponentBytes);
+        codeLength += exponentBytes.length;
+
+        byte exponentFormat = 0;
+        if (exponentBytes.length < 4) {
+            exponentFormat = (byte) (exponentBytes.length - 1);
+        } else {
+            os.write(exponentBytes.length);
+            codeLength++;
+            exponentFormat = 0x03;
+        }
+
+        if (isNegative) {
+            os.write(0x80 | 0x40 | exponentFormat);
+        } else {
+            os.write(0x80 | exponentFormat);
+        }
+
+        codeLength++;
+
+        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;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        if (length.val == 0) {
+            value = 0;
+            return codeLength;
+        }
+
+        if (length.val == 1) {
+            int nextByte = is.read();
+            if (nextByte == -1) {
+                throw new EOFException("Unexpected end of input stream.");
+            }
+            if (nextByte == 0x40) {
+                value = Double.POSITIVE_INFINITY;
+            } else if (nextByte == 0x41) {
+                value = Double.NEGATIVE_INFINITY;
+            } else {
+                throw new IOException("invalid real encoding");
+            }
+            return codeLength + 1;
+        }
+
+        byte[] byteCode = new byte[length.val];
+        Util.readFully(is, byteCode);
+
+        if ((byteCode[0] & 0x80) != 0x80) {
+            throw new IOException("Only binary REAL encoding is supported");
+        }
+
+        codeLength += length.val;
+        int tempLength = 1;
+
+        int sign = 1;
+        if ((byteCode[0] & 0x40) == 0x40) {
+            sign = -1;
+        }
+
+        int exponentLength = (byteCode[0] & 0x03) + 1;
+        if (exponentLength == 4) {
+            exponentLength = byteCode[1];
+            tempLength++;
+        }
+
+        tempLength += exponentLength;
+
+        int exponent = 0;
+        for (int i = 0; i < exponentLength; i++) {
+            exponent |= byteCode[1 + i] << (8 * (exponentLength - i - 1));
+        }
+
+        long mantissa = 0;
+        for (int i = 0; i < length.val - tempLength; i++) {
+            mantissa |= (byteCode[i + tempLength] & 0xffL) << (8 * (length.val - tempLength - i - 1));
+        }
+
+        value = sign * mantissa * Math.pow(2, exponent);
+
+        return codeLength;
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return "" + value;
+    }
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerTime.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerTime.java
new file mode 100644
index 0000000..cfd8d65
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerTime.java
@@ -0,0 +1,56 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.string.BerVisibleString;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+public class BerTime extends BerVisibleString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TIME_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerTime() {
+    }
+
+    public BerTime(byte[] value) {
+        super(value);
+    }
+
+    public BerTime(String valueAsString) throws UnsupportedEncodingException {
+        super(valueAsString);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerTimeOfDay.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerTimeOfDay.java
new file mode 100644
index 0000000..d592a72
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerTimeOfDay.java
@@ -0,0 +1,55 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+public class BerTimeOfDay extends BerTime {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TIME_OF_DAY_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerTimeOfDay() {
+    }
+
+    public BerTimeOfDay(byte[] value) {
+        super(value);
+    }
+
+    public BerTimeOfDay(String valueAsString) throws UnsupportedEncodingException {
+        super(valueAsString);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/BerUtcTime.java b/src/main/java/org.onosproject.xran/codecs/ber/types/BerUtcTime.java
new file mode 100644
index 0000000..2cfc6b5
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/BerUtcTime.java
@@ -0,0 +1,107 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.string.BerVisibleString;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class BerUtcTime extends BerVisibleString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UTC_TIME_TAG);
+    private static final long serialVersionUID = 1L;
+    /*
+     * UTC time is one of the following (ITU-T X.680 08/2015): YYMMDDhhmm[ss]Z YYMMDDhhmm[ss](+|-)hhmm Regexp: ^
+     * (?<year>\\d{2}) YY (?<month>\\d{2}) MM (?<day>\\d{2}) DD (?<hour>\\d{2}) hh (?<minute>\\d{2}) mm
+     * (?<second>\\d{2})? ss (?<timezone> Z | Z or (+|-)hhmm ( [+-]\\d{4} (+|-)hhmm ) ) $
+     */
+    private final static String UTC_TIME_PATTERN = "^(?<year>\\d{2})(?<month>\\d{2})(?<day>\\d{2})(?<hour>\\d{2})(?<minute>\\d{2})(?<second>\\d{2})?(?<timezone>Z|([+-]\\d{4}))$";
+    private final static Pattern utcTimePattern = Pattern.compile(UTC_TIME_PATTERN);
+
+    public BerUtcTime() {
+    }
+
+    public BerUtcTime(byte[] value) {
+        this.value = value;
+    }
+
+    public BerUtcTime(String valueAsString) {
+        super(valueAsString);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+    @SuppressWarnings("WeakerAccess")
+    Calendar asCalendar() throws ParseException {
+
+        Matcher matcher = utcTimePattern.matcher(toString());
+
+        if (!matcher.find())
+            throw new ParseException("", 0);
+
+        String mg;
+        int year = Integer.valueOf(matcher.group("year"));
+        int month = Integer.valueOf(matcher.group("month"));
+        month -= 1; // java.util.Calendar's month goes from 0 to 11
+        int day = Integer.valueOf(matcher.group("day"));
+        int hour = Integer.valueOf(matcher.group("hour"));
+        int minute = Integer.valueOf(matcher.group("minute"));
+        mg = matcher.group("second");
+        int second = mg == null ? 0 : Integer.valueOf(mg);
+
+        mg = matcher.group("timezone");
+        String timeZoneStr = mg.equals("Z") ? "UTC" : "GMT" + mg;
+        TimeZone timeZone = TimeZone.getTimeZone(timeZoneStr);
+
+        Calendar calendar = Calendar.getInstance(timeZone);
+
+        // Add 2000 to the year
+        int century = (calendar.get(Calendar.YEAR) / 100) * 100;
+        year += century;
+
+        // noinspection MagicConstant
+        calendar.set(year, month, day, hour, minute, second);
+        calendar.set(Calendar.MILLISECOND, 0);
+
+        return calendar;
+    }
+
+    Date asDate() throws ParseException {
+        return asCalendar().getTime();
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerBMPString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerBMPString.java
new file mode 100644
index 0000000..5f36c5a
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerBMPString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerBMPString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.BMP_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerBMPString() {
+    }
+
+    public BerBMPString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerGeneralString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerGeneralString.java
new file mode 100644
index 0000000..1c89db5
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerGeneralString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerGeneralString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GENERAL_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerGeneralString() {
+    }
+
+    public BerGeneralString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerGraphicString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerGraphicString.java
new file mode 100644
index 0000000..ef70e72
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerGraphicString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerGraphicString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.GRAPHIC_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerGraphicString() {
+    }
+
+    public BerGraphicString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerIA5String.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerIA5String.java
new file mode 100644
index 0000000..a56240e
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerIA5String.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerIA5String extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.IA5_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerIA5String() {
+    }
+
+    public BerIA5String(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerNumericString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerNumericString.java
new file mode 100644
index 0000000..944b66d
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerNumericString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerNumericString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.NUMERIC_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerNumericString() {
+    }
+
+    public BerNumericString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerObjectDescriptor.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerObjectDescriptor.java
new file mode 100644
index 0000000..2b80cb0
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerObjectDescriptor.java
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerObjectDescriptor extends BerGraphicString {
+
+    public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.OBJECT_DESCRIPTOR_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerObjectDescriptor() {
+    }
+
+    public BerObjectDescriptor(byte[] value) {
+        super(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength;
+
+        codeLength = super.encode(os, false);
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerPrintableString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerPrintableString.java
new file mode 100644
index 0000000..d865dcb
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerPrintableString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerPrintableString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.PRINTABLE_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerPrintableString() {
+    }
+
+    public BerPrintableString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerTeletexString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerTeletexString.java
new file mode 100644
index 0000000..78e483b
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerTeletexString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerTeletexString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.TELETEX_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerTeletexString() {
+    }
+
+    public BerTeletexString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerUTF8String.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerUTF8String.java
new file mode 100644
index 0000000..7b107a4
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerUTF8String.java
@@ -0,0 +1,67 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+public class BerUTF8String extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UTF8_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerUTF8String() {
+    }
+
+    public BerUTF8String(byte[] value) {
+        this.value = value;
+    }
+
+    public BerUTF8String(String valueAsString) throws UnsupportedEncodingException {
+        value = valueAsString.getBytes("UTF-8");
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        try {
+            return new String(value, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            return "Unsupported Encoding";
+        }
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerUniversalString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerUniversalString.java
new file mode 100644
index 0000000..06be21c
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerUniversalString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerUniversalString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.UNIVERSAL_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerUniversalString() {
+    }
+
+    public BerUniversalString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerVideotexString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerVideotexString.java
new file mode 100644
index 0000000..e67d8ca
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerVideotexString.java
@@ -0,0 +1,58 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.types.BerOctetString;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BerVideotexString extends BerOctetString {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.VIDEOTEX_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+
+    public BerVideotexString() {
+    }
+
+    public BerVideotexString(byte[] value) {
+        this.value = value;
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+    @Override
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        int codeLength = super.encode(os, false);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    @Override
+    public int decode(InputStream is, boolean withTag) throws IOException {
+
+        int codeLength = 0;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        codeLength += super.decode(is, false);
+
+        return codeLength;
+    }
+
+}
diff --git a/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerVisibleString.java b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerVisibleString.java
new file mode 100644
index 0000000..ca7bfb3
--- /dev/null
+++ b/src/main/java/org.onosproject.xran/codecs/ber/types/string/BerVisibleString.java
@@ -0,0 +1,83 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.onosproject.xran.codecs.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.codecs.ber.BerLength;
+import org.onosproject.xran.codecs.ber.BerTag;
+import org.onosproject.xran.codecs.ber.internal.Util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BerVisibleString implements Serializable {
+
+    public final static BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.PRIMITIVE, BerTag.VISIBLE_STRING_TAG);
+    private static final long serialVersionUID = 1L;
+    public byte[] value;
+
+    public BerVisibleString() {
+    }
+
+    public BerVisibleString(byte[] value) {
+        this.value = value;
+    }
+
+    public BerVisibleString(String valueAsString) {
+        value = valueAsString.getBytes();
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        os.write(value);
+        int codeLength = value.length;
+
+        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;
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        value = new byte[length.val];
+
+        if (length.val != 0) {
+            Util.readFully(is, value);
+            codeLength += length.val;
+        }
+
+        return codeLength;
+
+    }
+
+    @JsonValue
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+}