v5 initial commit
diff --git a/apps/xran/.gitignore b/apps/xran/.gitignore
new file mode 100644
index 0000000..e43b0f9
--- /dev/null
+++ b/apps/xran/.gitignore
@@ -0,0 +1 @@
+.DS_Store
diff --git a/apps/xran/BUCK b/apps/xran/BUCK
new file mode 100644
index 0000000..0c41439
--- /dev/null
+++ b/apps/xran/BUCK
@@ -0,0 +1,60 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//lib:COMPILE',
+    '//lib:netty-handler',
+    '//lib:javax.ws.rs-api',
+    '//lib:org.apache.karaf.shell.console',
+    '//lib:netty-buffer',
+    '//utils/rest:onlab-rest',
+    '//core/store/serializers:onos-core-serializers',
+    '//cli:onos-cli',
+    '//lib:netty-transport',
+    '//core/common:onos-core-common',
+    ':netty-transport-sctp',
+    '//lib:swagger-annotations',
+    '//lib:JACKSON',
+    '//lib:NETTY'
+]
+
+BUNDLES = [
+    '//apps/xran:onos-apps-xran',
+]
+
+TEST_DEPS = [
+    '//lib:TEST',
+    '//lib:TEST_ADAPTERS',
+]
+
+EXCLUDED_BUNDLES = [
+    ':netty-transport-sctp',
+    '//lib:swagger-annotations'
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+    web_context = '/onos/xran',
+    api_title = 'XRAN REST API',
+    api_package = 'org.onosproject.xran.impl.rest',
+    api_version = '1.0',
+    api_description = 'XRAN REST API',
+)
+
+onos_app (
+    app_name = 'org.onosproject.xran',
+    title = 'XRAN REST API',
+    category = 'Utilities',
+    url = 'http://onosproject.org',
+    description = 'XRAN REST API.',
+    included_bundles = BUNDLES,
+    excluded_bundles = EXCLUDED_BUNDLES,
+)
+
+remote_jar (
+    name = 'netty-transport-sctp',
+    out = 'netty-transport-sctp-4.1.13.Final.jar',
+    url = 'mvn:io.netty:netty-transport-sctp:jar:4.1.13.Final',
+    sha1 = '41e4ab1dc14cae445f93cef6421ce08f82804c1d',
+    maven_coords = 'io.netty:netty-transport-sctp:4.1.13.Final',
+    visibility = [ 'PUBLIC' ],
+)
diff --git a/apps/xran/apps_xran.iml b/apps/xran/apps_xran.iml
new file mode 100644
index 0000000..80f02c3
--- /dev/null
+++ b/apps/xran/apps_xran.iml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.git" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java/org.onosproject.xran" isTestSource="false"  packagePrefix="org.onosproject.xran"/>
+      <sourceFolder url="file://$MODULE_DIR$/src/main/webapp" isTestSource="false"  packagePrefix="apps.xran.src.main.webapp"/>
+      <sourceFolder url="file://$MODULE_DIR$/src/test/java/org.onosproject.xran" isTestSource="true" />
+
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="cli" scope="COMPILE"  />
+    <orderEntry type="module" module-name="core_api" scope="COMPILE"  />
+    <orderEntry type="module" module-name="core_common" scope="COMPILE"  />
+    <orderEntry type="module" module-name="core_store_serializers" scope="COMPILE"  />
+    <orderEntry type="module" module-name="lib" scope="COMPILE"  />
+    <orderEntry type="module" module-name="utils_junit" scope="TEST"  />
+    <orderEntry type="module" module-name="utils_misc" scope="COMPILE"  />
+    <orderEntry type="module" module-name="utils_osgi" scope="COMPILE"  />
+    <orderEntry type="module" module-name="utils_rest" scope="COMPILE"  />
+    <orderEntry type="library" name="library_apps_xran_netty_transport_sctp" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_commons_collections" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_commons_configuration" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_commons_io" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_commons_lang" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_commons_lang3" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_commons_logging" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_commons_pool" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_easymock" scope="TEST" level="project"  />
+    <orderEntry type="library" name="library_lib_guava" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_guava_testlib" scope="TEST" level="project"  />
+    <orderEntry type="library" name="library_lib_hamcrest_all" scope="TEST" level="project"  />
+    <orderEntry type="library" name="library_lib_hamcrest_optional" scope="TEST" level="project"  />
+    <orderEntry type="library" name="library_lib_jackson_annotations" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_jackson_core" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_jackson_databind" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_javax_ws_rs_api" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_jsr305" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_junit" scope="TEST" level="project"  />
+    <orderEntry type="library" name="library_lib_netty_buffer" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_netty_common" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_netty_handler" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_netty_transport" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_org_apache_felix_scr" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_org_apache_felix_scr_annotations" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_org_apache_karaf_features_core" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_org_apache_karaf_shell_console" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_org_apache_karaf_system_core" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_org_apache_servicemix_bundles_dom4j" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_org_osgi_compendium" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_osgi_core" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_slf4j_api" scope="COMPILE" level="project"  />
+    <orderEntry type="library" name="library_lib_swagger_annotations" scope="COMPILE" level="project"  />
+
+  </component>
+</module>
diff --git a/apps/xran/src/main/java/org.onosproject.xran/XranDeviceAgent.java b/apps/xran/src/main/java/org.onosproject.xran/XranDeviceAgent.java
new file mode 100644
index 0000000..812d6fc
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/XranDeviceAgent.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran;
+
+import io.netty.channel.ChannelHandlerContext;
+
+/**
+ * Xran device agent interface.
+ */
+public interface XranDeviceAgent {
+
+    /**
+     * Add connected CELL.
+     *
+     * @param host IP of host trying to connect
+     * @param ctx  channel of CELL speaking to
+     * @return true if succeeded
+     */
+    boolean addConnectedCell(String host, ChannelHandlerContext ctx);
+
+    /**
+     * Remove disconnected CELL.
+     *
+     * @param host IP of host disconnected
+     * @return true if remove succeeded
+     */
+    boolean removeConnectedCell(String host);
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/XranDeviceListener.java b/apps/xran/src/main/java/org.onosproject.xran/XranDeviceListener.java
new file mode 100644
index 0000000..cfb4783
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/XranDeviceListener.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.xran.impl.entities.RnibCell;
+
+/**
+ * Xran Device Listener.
+ */
+public interface XranDeviceListener {
+
+    /**
+     * Add new CELL as a device.
+     *
+     * @param id CELL entity
+     */
+    void deviceAdded(RnibCell id);
+
+    /**
+     * Remove CELL.
+     *
+     * @param id CELL ECGI as device id
+     */
+    void deviceRemoved(DeviceId id);
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/XranHostAgent.java b/apps/xran/src/main/java/org.onosproject.xran/XranHostAgent.java
new file mode 100644
index 0000000..852ea6b
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/XranHostAgent.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran;
+
+import io.netty.channel.ChannelHandlerContext;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.onosproject.xran.impl.entities.RnibUe;
+
+/**
+ * Xran host agent interface.
+ */
+public interface XranHostAgent {
+
+    /**
+     * Add connected host.
+     *
+     * @param ue   UE entity
+     * @param cell CELL entity
+     * @param ctx  channel of CELL
+     * @return true if succeeded
+     */
+    boolean addConnectedHost(RnibUe ue, RnibCell cell, ChannelHandlerContext ctx);
+
+    /**
+     * Remove disconnected host.
+     *
+     * @param ue UE entity
+     * @return true if remove succeeded
+     */
+    boolean removeConnectedHost(RnibUe ue);
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/XranHostListener.java b/apps/xran/src/main/java/org.onosproject.xran/XranHostListener.java
new file mode 100644
index 0000000..b33b17c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/XranHostListener.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran;
+
+import org.onosproject.net.HostId;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.impl.entities.RnibUe;
+
+import java.util.Set;
+
+/**
+ * Xran Host Listener.
+ */
+public interface XranHostListener {
+
+    /**
+     * Add UE as a host with location the primary link.
+     *
+     * @param ue      UE entity
+     * @param ecgiSet All connected CELLs to this UE
+     */
+    void hostAdded(RnibUe ue, Set<ECGI> ecgiSet);
+
+    /**
+     * Remove UE based on Host Id.
+     *
+     * @param id Host Id generated from UE id
+     */
+    void hostRemoved(HostId id);
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/XranPacketProcessor.java b/apps/xran/src/main/java/org.onosproject.xran/XranPacketProcessor.java
new file mode 100644
index 0000000..e9f8cb0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/XranPacketProcessor.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran;
+
+import io.netty.channel.ChannelHandlerContext;
+import org.onosproject.xran.asn1lib.pdu.XrancPdu;
+
+import java.io.IOException;
+
+/**
+ * Xran packet processor interface.
+ */
+public interface XranPacketProcessor {
+    /**
+     * Handle an incoming packet.
+     *
+     * @param pdu pdu of incoming packet
+     * @param ctx channel received the packet
+     * @throws IOException io exception
+     * @throws InterruptedException interrupted exception
+     */
+    void handlePacket(XrancPdu pdu, ChannelHandlerContext ctx) throws IOException, InterruptedException;
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/XranService.java b/apps/xran/src/main/java/org.onosproject.xran/XranService.java
new file mode 100644
index 0000000..c9b89fe
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/XranService.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran;
+
+import org.onosproject.xran.asn1lib.pdu.RRMConfig;
+import org.onosproject.xran.impl.entities.RnibLink;
+
+import java.util.Optional;
+import java.util.concurrent.SynchronousQueue;
+
+/**
+ * Created by dimitris on 7/27/17.
+ */
+public interface XranService {
+
+    /**
+     * Send a HandOff request from one link to another.
+     *
+     * @param newLink target LINK entity
+     * @param oldLink source LINK entity
+     * @return blocking queue for RESPONSE
+     * @throws InterruptedException interrupted exception
+     */
+    Optional<SynchronousQueue<String>> sendHoRequest(RnibLink newLink, RnibLink oldLink);
+
+    /**
+     * Add a device listener for CELL connections.
+     *
+     * @param listener listener
+     */
+    void addListener(XranDeviceListener listener);
+
+    /**
+     * Add a host listener for UE connections.
+     *
+     * @param listener listener
+     */
+    void addListener(XranHostListener listener);
+
+    /**
+     * Remove a CELL device listener.
+     *
+     * @param listener listener
+     */
+    void removeListener(XranDeviceListener listener);
+
+    /**
+     * Remove a UE host listener.
+     *
+     * @param listener listener
+     */
+    void removeListener(XranHostListener listener);
+
+    /**
+     * Send modified RRM configuration.
+     *
+     * @param rrmConfig configuration fields to send
+     * @return blocking queue for RESPONSE
+     */
+    Optional<SynchronousQueue<String>> sendModifiedRrm(RRMConfig rrmConfig);
+
+    /**
+     * Send scell add packet for specified LINK.
+     *
+     * @param link LINK entity
+     * @return blocking queue for RESPONSE
+     */
+    Optional<SynchronousQueue<String>> sendScellAdd(RnibLink link);
+
+    /**
+     * Send scell delete for specified LINK.
+     *
+     * @param link LINK entity
+     * @return true if sent correctly
+     */
+    boolean sendScellDelete(RnibLink link);
+
+    /**
+     * Get northbound timeout.
+     *
+     * @return interval in milliseconds
+     */
+    int getNorthboundTimeout();
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/XranStore.java b/apps/xran/src/main/java/org.onosproject.xran/XranStore.java
new file mode 100644
index 0000000..6c9c8fc
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/XranStore.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.BiMap;
+import io.netty.channel.ChannelHandlerContext;
+import org.onosproject.store.Store;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.PCIARFCN;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.onosproject.xran.impl.entities.RnibLink;
+import org.onosproject.xran.impl.entities.RnibSlice;
+import org.onosproject.xran.impl.entities.RnibUe;
+import org.onosproject.xran.impl.identifiers.EcgiCrntiPair;
+import org.onosproject.xran.impl.identifiers.LinkId;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Created by dimitris on 7/22/17.
+ */
+public interface XranStore extends Store {
+
+    // LINKS STORE
+
+    /**
+     * Get all active links.
+     *
+     * @return list of links
+     */
+    List<RnibLink> getLinks();
+
+    /**
+     * Get all links for that CELL based on ECGI.
+     *
+     * @param ecgi CELL ECGI
+     *
+     * @return list of links
+     */
+    List<RnibLink> getLinks(ECGI ecgi);
+
+    /**
+     * Get all links for that CELL based on ECI.
+     *
+     * @param eciHex HEX string of ECI
+     *
+     * @return list of links
+     */
+    List<RnibLink> getLinks(String eciHex);
+
+    /**
+     * Get all links for the UE based on UE ID.
+     *
+     * @param ueId UE ID
+     *
+     * @return list of links
+     */
+    List<RnibLink> getLinks(long ueId);
+
+    /**
+     * Get a link between a CELL and UE.
+     *
+     * @param cellId HEX string ECI
+     * @param ueId   UE id
+     *
+     * @return link
+     */
+    Optional<RnibLink> getLink(String cellId, long ueId);
+
+    /**
+     * Get a link between a CELL's ECGI and UE's id.
+     *
+     * @param ecgi CELL ECGI
+     * @param ueId UE id
+     *
+     * @return link
+     */
+    Optional<RnibLink> getLink(ECGI ecgi, Long ueId);
+
+    /**
+     * Get link based on ECGI and CRNTI.
+     *
+     * @param src CELL ECGI
+     * @param dst CELL unique CRNTI
+     * @return link if found
+     */
+    Optional<RnibLink> getLink(ECGI src, CRNTI dst);
+
+    /**
+     * Modify specified link's RRM Configuration.
+     *
+     * @param link    LINK entity
+     * @param rrmConf json node of RRM Configuration
+     */
+    void modifyLinkRrmConf(RnibLink link, JsonNode rrmConf);
+
+    /**
+     * Put new link to store.
+     *
+     * @param link LINK entity
+     */
+    void storeLink(RnibLink link);
+
+    /**
+     * Remove link from store.
+     *
+     * @param link LINK entity
+     *
+     * @return true if remove succeeded
+     */
+    boolean removeLink(LinkId link);
+
+    // NODES
+
+    /**
+     * Get all CELLs and UEs.
+     *
+     * @return list of UEs and CELLs
+     */
+    List<Object> getNodes();
+
+    /**
+     * Get all CELLs.
+     *
+     * @return list of CELLs
+     */
+    List<RnibCell> getCellNodes();
+
+    /**
+     * Get all UEs.
+     *
+     * @return list of UEs
+     */
+    List<RnibUe> getUeNodes();
+
+    /**
+     * Get node by node id.
+     *
+     * @param nodeId HEX string ECI or UE id
+     *
+     * @return CELL or UE
+     */
+    Optional<Object> getNode(String nodeId);
+
+    // CELL
+
+    /**
+     * Get cell based on HEX string ECI.
+     *
+     * @param eci HEX string ECI
+     *
+     * @return CELL if found
+     */
+    Optional<RnibCell> getCell(String eci);
+
+    /**
+     * Get cell based on ECGI.
+     *
+     * @param cellId CELL ECGI
+     *
+     * @return CELL if found
+     */
+    Optional<RnibCell> getCell(ECGI cellId);
+
+    /**
+     * Get cell based on PCI-ARFCN.
+     *
+     * @param id PCI-ARFCN
+     *
+     * @return CELL entity if found
+     */
+    Optional<RnibCell> getCell(PCIARFCN id);
+
+    /**
+     * Modify CELL's RRM Configuration.
+     *
+     * @param cell    CELL entity
+     * @param rrmConf json node of RRM Configuration
+     *
+     * @throws Exception exception
+     */
+    void modifyCellRrmConf(RnibCell cell, JsonNode rrmConf) throws Exception;
+
+    /**
+     * Put new CELL to the store.
+     *
+     * @param cell CELL entity
+     */
+    void storeCell(RnibCell cell);
+
+    /**
+     * Remove CELL from the store.
+     *
+     * @param ecgi CELL's ECGI
+     *
+     * @return ture if remove succeeded
+     */
+    boolean removeCell(ECGI ecgi);
+
+    /**
+     * Remove cell from three maps based on PCI-ARFCN.
+     *
+     * @param pciarfcn pci-arfcn of cell to remove
+     *
+     * @return true if remove succeeded
+     */
+    boolean removeCell(PCIARFCN pciarfcn);
+
+    // SLICE
+
+    /**
+     * Get SLICE based on SLICE id.
+     *
+     * @param sliceId SLICE id
+     * @return SLICE
+     */
+    Optional<RnibSlice> getSlice(long sliceId);
+
+    /**
+     * Put new SLICE to the store.
+     *
+     * @param attributes json node of SLICE attributes
+     *
+     * @return true if put succeeded
+     */
+    boolean createSlice(ObjectNode attributes);
+
+    /**
+     * Remove SLICE based on SLICE id.
+     *
+     * @param sliceId SLICE id
+     *
+     * @return true if remove succeeded
+     */
+    boolean removeCell(long sliceId);
+
+    // CONTROLLER
+
+    /**
+     * Get the xran xranServer instance.
+     *
+     * @return xran xranServer
+     */
+    Optional<XranService> getController();
+
+    /**
+     * Set the xran xranServer instance.
+     *
+     * @param controller xran xranServer
+     */
+    void setController(XranService controller);
+
+    // UE
+
+    /**
+     * Get UE based on UE id.
+     *
+     * @param euId UE id
+     *
+     * @return UE entity
+     */
+    Optional<RnibUe> getUe(long euId);
+
+    /**
+     * Get UE based on ECGI and CRNTI.
+     *
+     * @param ecgi  CELL ECGI
+     * @param crnti CELL unique CRNTI
+     *
+     * @return UE entity if found
+     */
+    Optional<RnibUe> getUe(ECGI ecgi, CRNTI crnti);
+
+    /**
+     * Put new UE to store.
+     *
+     * @param ue UE entity
+     */
+    void storeUe(RnibUe ue);
+
+    /**
+     * Put new UE to the store and update the ECGI, CRNTI pair.
+     *
+     * @param cell new primary CELL
+     * @param ue   UE
+     */
+    void storeUe(RnibCell cell, RnibUe ue);
+
+    /**
+     * Remove UE from store.
+     *
+     * @param ueId UE id
+     *
+     * @return true if remove succeeded
+     */
+    boolean removeUe(long ueId);
+
+    /**
+     * Put the PCI-ARFCN to ECGI map from new cell.
+     *
+     * @param value CELL entity
+     */
+    void storePciArfcn(RnibCell value);
+
+
+    /**
+     * Put inside ECGI to CTX map.
+     *
+     * @param value CELL entity to get ECGI from
+     * @param ctx   context channel
+     */
+    void storeCtx(RnibCell value, ChannelHandlerContext ctx);
+
+    /**
+     * Get context handler for specified ECGI.
+     *
+     * @param ecgi CELL ECGI
+     * @return context handler if found
+     */
+    Optional<ChannelHandlerContext> getCtx(ECGI ecgi);
+
+    /**
+     * Get the ECGI, CRNTI to UE bimap.
+     *
+     * @return BiMap of EcgiCrntiPair to Long
+     */
+    BiMap<EcgiCrntiPair, Long> getCrnti();
+
+    /**
+     * Put new ECGI, CRNTI pair of primary link to UE and remove old one.
+     *
+     * @param cell new primary CELL
+     * @param ue   UE
+     */
+    void storeCrnti(RnibCell cell, RnibUe ue);
+
+    /**
+     * Put a new primary link between a CELL and a UE.
+     *
+     * @param cell CELL entity
+     * @param ue   UE entity
+     */
+    void putPrimaryLink(RnibCell cell, RnibUe ue);
+
+    /**
+     * Put non-serving link based on CELL and CRNTI.
+     *
+     * @param cell  CELL entity
+     * @param crnti CRNTI
+     * @return new link after creation
+     */
+    Optional<RnibLink> putNonServingLink(RnibCell cell, CRNTI crnti);
+
+    /**
+     * Put non-serving link based on CELL and UE id.
+     *
+     * @param cell CELL entity
+     * @param ueId UE id
+     * @return new link after creation
+     */
+    Optional<RnibLink> putNonServingLink(RnibCell cell, Long ueId);
+
+    /**
+     * Get CRNTI based on UE id.
+     *
+     * @param ueId UE id
+     * @return UE if found
+     */
+    Optional<CRNTI> getCrnti(Long ueId);
+
+    /**
+     * Get primary CELL for specified UE.
+     *
+     * @param ue UE entity
+     * @return primary CELL if found
+     */
+    Optional<RnibCell> getPrimaryCell(RnibUe ue);
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A1Param.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A1Param.java
new file mode 100644
index 0000000..fbfbce8
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A1Param.java
@@ -0,0 +1,143 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class A1Param 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 ThresholdEUTRA a1Threshold = null;
+
+    public A1Param() {
+    }
+
+    public A1Param(byte[] code) {
+        this.code = code;
+    }
+
+    public ThresholdEUTRA getA1Threshold() {
+        return a1Threshold;
+    }
+
+    public void setA1Threshold(ThresholdEUTRA a1Threshold) {
+        this.a1Threshold = a1Threshold;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        int sublength;
+
+        sublength = a1Threshold.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);
+            a1Threshold = new ThresholdEUTRA();
+            subCodeLength += a1Threshold.decode(is, null);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (a1Threshold != null) {
+            sb.append("a1Threshold: ");
+            a1Threshold.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("a1Threshold: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A2Param.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A2Param.java
new file mode 100644
index 0000000..4a269f7
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A2Param.java
@@ -0,0 +1,143 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class A2Param 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 ThresholdEUTRA a2Threshold = null;
+
+    public A2Param() {
+    }
+
+    public A2Param(byte[] code) {
+        this.code = code;
+    }
+
+    public ThresholdEUTRA getA2Threshold() {
+        return a2Threshold;
+    }
+
+    public void setA2Threshold(ThresholdEUTRA a2Threshold) {
+        this.a2Threshold = a2Threshold;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        int sublength;
+
+        sublength = a2Threshold.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);
+            a2Threshold = new ThresholdEUTRA();
+            subCodeLength += a2Threshold.decode(is, null);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (a2Threshold != null) {
+            sb.append("a2Threshold: ");
+            a2Threshold.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("a2Threshold: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A3Param.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A3Param.java
new file mode 100644
index 0000000..4d1e9ea
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A3Param.java
@@ -0,0 +1,138 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class A3Param 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 a3Offset = null;
+
+    public A3Param() {
+    }
+
+    public A3Param(byte[] code) {
+        this.code = code;
+    }
+
+    public BerInteger getA3Offset() {
+        return a3Offset;
+    }
+
+    public void setA3Offset(BerInteger a3Offset) {
+        this.a3Offset = a3Offset;
+    }
+
+    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 += a3Offset.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)) {
+            a3Offset = new BerInteger();
+            subCodeLength += a3Offset.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (a3Offset != null) {
+            sb.append("a3Offset: ").append(a3Offset);
+        } else {
+            sb.append("a3Offset: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A4Param.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A4Param.java
new file mode 100644
index 0000000..fe514bc
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A4Param.java
@@ -0,0 +1,143 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class A4Param 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 ThresholdEUTRA a4Threshold = null;
+
+    public A4Param() {
+    }
+
+    public A4Param(byte[] code) {
+        this.code = code;
+    }
+
+    public ThresholdEUTRA getA4Threshold() {
+        return a4Threshold;
+    }
+
+    public void setA4Threshold(ThresholdEUTRA a4Threshold) {
+        this.a4Threshold = a4Threshold;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        int sublength;
+
+        sublength = a4Threshold.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);
+            a4Threshold = new ThresholdEUTRA();
+            subCodeLength += a4Threshold.decode(is, null);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (a4Threshold != null) {
+            sb.append("a4Threshold: ");
+            a4Threshold.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("a4Threshold: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A5Param.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A5Param.java
new file mode 100644
index 0000000..878ae61
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A5Param.java
@@ -0,0 +1,179 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class A5Param 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 ThresholdEUTRA a5Threshold1 = null;
+    private ThresholdEUTRA a5Threshold2 = null;
+
+    public A5Param() {
+    }
+
+    public A5Param(byte[] code) {
+        this.code = code;
+    }
+
+    public ThresholdEUTRA getA5Threshold1() {
+        return a5Threshold1;
+    }
+
+    public void setA5Threshold1(ThresholdEUTRA a5Threshold1) {
+        this.a5Threshold1 = a5Threshold1;
+    }
+
+    public ThresholdEUTRA getA5Threshold2() {
+        return a5Threshold2;
+    }
+
+    public void setA5Threshold2(ThresholdEUTRA a5Threshold2) {
+        this.a5Threshold2 = a5Threshold2;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        int sublength;
+
+        sublength = a5Threshold2.encode(os);
+        codeLength += sublength;
+        codeLength += BerLength.encodeLength(os, sublength);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        sublength = a5Threshold1.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);
+            a5Threshold1 = new ThresholdEUTRA();
+            subCodeLength += a5Threshold1.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.CONSTRUCTED, 1)) {
+            subCodeLength += length.decode(is);
+            a5Threshold2 = new ThresholdEUTRA();
+            subCodeLength += a5Threshold2.decode(is, null);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (a5Threshold1 != null) {
+            sb.append("a5Threshold1: ");
+            a5Threshold1.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("a5Threshold1: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (a5Threshold2 != null) {
+            sb.append("a5Threshold2: ");
+            a5Threshold2.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("a5Threshold2: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A6Param.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A6Param.java
new file mode 100644
index 0000000..991a4bb
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/A6Param.java
@@ -0,0 +1,138 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class A6Param 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 a6Offset = null;
+
+    public A6Param() {
+    }
+
+    public A6Param(byte[] code) {
+        this.code = code;
+    }
+
+    public BerInteger getA6Offset() {
+        return a6Offset;
+    }
+
+    public void setA6Offset(BerInteger a6Offset) {
+        this.a6Offset = a6Offset;
+    }
+
+    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 += a6Offset.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)) {
+            a6Offset = new BerInteger();
+            subCodeLength += a6Offset.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (a6Offset != null) {
+            sb.append("a6Offset: ").append(a6Offset);
+        } else {
+            sb.append("a6Offset: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ARFCNValue.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ARFCNValue.java
new file mode 100644
index 0000000..1377785
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ARFCNValue.java
@@ -0,0 +1,43 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class ARFCNValue extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public ARFCNValue() {
+    }
+
+    public ARFCNValue(byte[] code) {
+        super(code);
+    }
+
+    public ARFCNValue(BigInteger value) {
+        super(value);
+    }
+
+    public ARFCNValue(long value) {
+        super(value);
+    }
+
+    @Override
+    public int hashCode() {
+        return value.intValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ARFCNValue) {
+            return value.intValue() == ((ARFCNValue) obj).value.intValue();
+        }
+        return super.equals(obj);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstCause.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstCause.java
new file mode 100644
index 0000000..cd30cfa
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstCause.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class AdmEstCause extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public AdmEstCause() {
+    }
+
+    public AdmEstCause(byte[] code) {
+        super(code);
+    }
+
+    public AdmEstCause(BigInteger value) {
+        super(value);
+    }
+
+    public AdmEstCause(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstResponse.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstResponse.java
new file mode 100644
index 0000000..57a1ce7
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstResponse.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class AdmEstResponse extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public AdmEstResponse() {
+    }
+
+    public AdmEstResponse(byte[] code) {
+        super(code);
+    }
+
+    public AdmEstResponse(BigInteger value) {
+        super(value);
+    }
+
+    public AdmEstResponse(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstStatus.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstStatus.java
new file mode 100644
index 0000000..1d5ac19
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/AdmEstStatus.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class AdmEstStatus extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public AdmEstStatus() {
+    }
+
+    public AdmEstStatus(byte[] code) {
+        super(code);
+    }
+
+    public AdmEstStatus(BigInteger value) {
+        super(value);
+    }
+
+    public AdmEstStatus(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/BitRate.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/BitRate.java
new file mode 100644
index 0000000..1eea849
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/BitRate.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class BitRate extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public BitRate() {
+    }
+
+    public BitRate(byte[] code) {
+        super(code);
+    }
+
+    public BitRate(BigInteger value) {
+        super(value);
+    }
+
+    public BitRate(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CACap.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CACap.java
new file mode 100644
index 0000000..32a4eda
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CACap.java
@@ -0,0 +1,236 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerBoolean;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class CACap 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 band = null;
+    private BerEnum caclassdl = null;
+    private BerEnum caclassul = null;
+    private BerBoolean crossCarrierSched = null;
+
+    public CACap() {
+    }
+
+    public CACap(byte[] code) {
+        this.code = code;
+    }
+
+    public BerInteger getBand() {
+        return band;
+    }
+
+    public void setBand(BerInteger band) {
+        this.band = band;
+    }
+
+    public BerEnum getCaclassdl() {
+        return caclassdl;
+    }
+
+    public void setCaclassdl(BerEnum caclassdl) {
+        this.caclassdl = caclassdl;
+    }
+
+    public BerEnum getCaclassul() {
+        return caclassul;
+    }
+
+    public void setCaclassul(BerEnum caclassul) {
+        this.caclassul = caclassul;
+    }
+
+    public BerBoolean getCrossCarrierSched() {
+        return crossCarrierSched;
+    }
+
+    public void setCrossCarrierSched(BerBoolean crossCarrierSched) {
+        this.crossCarrierSched = crossCarrierSched;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += crossCarrierSched.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += caclassul.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += caclassdl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += band.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            band = new BerInteger();
+            subCodeLength += band.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            caclassdl = new BerEnum();
+            subCodeLength += caclassdl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            caclassul = new BerEnum();
+            subCodeLength += caclassul.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            crossCarrierSched = new BerBoolean();
+            subCodeLength += crossCarrierSched.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (band != null) {
+            sb.append("band: ").append(band);
+        } else {
+            sb.append("band: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (caclassdl != null) {
+            sb.append("caclassdl: ").append(caclassdl);
+        } else {
+            sb.append("caclassdl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (caclassul != null) {
+            sb.append("caclassul: ").append(caclassul);
+        } else {
+            sb.append("caclassul: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crossCarrierSched != null) {
+            sb.append("crossCarrierSched: ").append(crossCarrierSched);
+        } else {
+            sb.append("crossCarrierSched: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CRNTI.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CRNTI.java
new file mode 100644
index 0000000..8b3245a
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CRNTI.java
@@ -0,0 +1,45 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerBitString;
+
+import javax.xml.bind.DatatypeConverter;
+import java.util.Arrays;
+
+
+public class CRNTI extends BerBitString {
+
+    private static final long serialVersionUID = 1L;
+
+    public CRNTI() {
+    }
+
+    public CRNTI(byte[] code) {
+        super(code);
+    }
+
+    public CRNTI(byte[] value, int numBits) {
+        super(value, numBits);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof CRNTI) {
+            return Arrays.equals(value, ((CRNTI) obj).value);
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public String toString() {
+        return "" + DatatypeConverter.printHexBinary(value) + "";
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CandScell.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CandScell.java
new file mode 100644
index 0000000..7ce4c2c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/CandScell.java
@@ -0,0 +1,169 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class CandScell 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 PhysCellId pci = null;
+    private ARFCNValue earfcnDl = null;
+
+    public CandScell() {
+    }
+
+    public CandScell(byte[] code) {
+        this.code = code;
+    }
+
+    public PhysCellId getPci() {
+        return pci;
+    }
+
+    public void setPci(PhysCellId pci) {
+        this.pci = pci;
+    }
+
+    public ARFCNValue getEarfcnDl() {
+        return earfcnDl;
+    }
+
+    public void setEarfcnDl(ARFCNValue earfcnDl) {
+        this.earfcnDl = earfcnDl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += earfcnDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += pci.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            pci = new PhysCellId();
+            subCodeLength += pci.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            earfcnDl = new ARFCNValue();
+            subCodeLength += earfcnDl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pci != null) {
+            sb.append("pci: ").append(pci);
+        } else {
+            sb.append("pci: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (earfcnDl != null) {
+            sb.append("earfcnDl: ").append(earfcnDl);
+        } else {
+            sb.append("earfcnDl: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/DCCap.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/DCCap.java
new file mode 100644
index 0000000..8b7e75a
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/DCCap.java
@@ -0,0 +1,138 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class DCCap 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 BerEnum drbTypeSplit = null;
+
+    public DCCap() {
+    }
+
+    public DCCap(byte[] code) {
+        this.code = code;
+    }
+
+    public BerEnum getDrbTypeSplit() {
+        return drbTypeSplit;
+    }
+
+    public void setDrbTypeSplit(BerEnum drbTypeSplit) {
+        this.drbTypeSplit = drbTypeSplit;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += drbTypeSplit.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            drbTypeSplit = new BerEnum();
+            subCodeLength += drbTypeSplit.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (drbTypeSplit != null) {
+            sb.append("drbTypeSplit: ").append(drbTypeSplit);
+        } else {
+            sb.append("drbTypeSplit: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/DuplexMode.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/DuplexMode.java
new file mode 100644
index 0000000..6e3b7f0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/DuplexMode.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class DuplexMode extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public DuplexMode() {
+    }
+
+    public DuplexMode(byte[] code) {
+        super(code);
+    }
+
+    public DuplexMode(BigInteger value) {
+        super(value);
+    }
+
+    public DuplexMode(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ECGI.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ECGI.java
new file mode 100644
index 0000000..e7c5cbd
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ECGI.java
@@ -0,0 +1,183 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class ECGI 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 PLMNIdentity pLMNIdentity = null;
+    private EUTRANCellIdentifier eUTRANcellIdentifier = null;
+
+    public ECGI() {
+    }
+
+    public ECGI(byte[] code) {
+        this.code = code;
+    }
+
+    public PLMNIdentity getPLMNIdentity() {
+        return pLMNIdentity;
+    }
+
+    public void setPLMNIdentity(PLMNIdentity pLMNIdentity) {
+        this.pLMNIdentity = pLMNIdentity;
+    }
+
+    public EUTRANCellIdentifier getEUTRANcellIdentifier() {
+        return eUTRANcellIdentifier;
+    }
+
+    public void setEUTRANcellIdentifier(EUTRANCellIdentifier eUTRANcellIdentifier) {
+        this.eUTRANcellIdentifier = eUTRANcellIdentifier;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += eUTRANcellIdentifier.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += pLMNIdentity.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            pLMNIdentity = new PLMNIdentity();
+            subCodeLength += pLMNIdentity.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            eUTRANcellIdentifier = new EUTRANCellIdentifier();
+            subCodeLength += eUTRANcellIdentifier.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pLMNIdentity != null) {
+            sb.append("pLMNIdentity: ").append(pLMNIdentity);
+        } else {
+            sb.append("pLMNIdentity: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (eUTRANcellIdentifier != null) {
+            sb.append("eUTRANcellIdentifier: ").append(eUTRANcellIdentifier);
+        } else {
+            sb.append("eUTRANcellIdentifier: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ECGI ecgi = (ECGI) o;
+
+        return eUTRANcellIdentifier.equals(ecgi.eUTRANcellIdentifier);
+    }
+
+    @Override
+    public int hashCode() {
+        return eUTRANcellIdentifier.hashCode();
+    }
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ENBUES1APID.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ENBUES1APID.java
new file mode 100644
index 0000000..385e1c0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ENBUES1APID.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class ENBUES1APID extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public ENBUES1APID() {
+    }
+
+    public ENBUES1APID(byte[] code) {
+        super(code);
+    }
+
+    public ENBUES1APID(BigInteger value) {
+        super(value);
+    }
+
+    public ENBUES1APID(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABDecision.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABDecision.java
new file mode 100644
index 0000000..ab2a7f0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABDecision.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class ERABDecision extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public ERABDecision() {
+    }
+
+    public ERABDecision(byte[] code) {
+        super(code);
+    }
+
+    public ERABDecision(BigInteger value) {
+        super(value);
+    }
+
+    public ERABDecision(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABDirection.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABDirection.java
new file mode 100644
index 0000000..57314e5
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABDirection.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class ERABDirection extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public ERABDirection() {
+    }
+
+    public ERABDirection(byte[] code) {
+        super(code);
+    }
+
+    public ERABDirection(BigInteger value) {
+        super(value);
+    }
+
+    public ERABDirection(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABID.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABID.java
new file mode 100644
index 0000000..b585441
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABID.java
@@ -0,0 +1,43 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class ERABID extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public ERABID() {
+    }
+
+    public ERABID(byte[] code) {
+        super(code);
+    }
+
+    public ERABID(BigInteger value) {
+        super(value);
+    }
+
+    public ERABID(long value) {
+        super(value);
+    }
+
+    @Override
+    public int hashCode() {
+        return value.intValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ERABID) {
+            return value.intValue() == ((ERABID) obj).intValue();
+        }
+        return super.equals(obj);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABParams.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABParams.java
new file mode 100644
index 0000000..c7f6e14
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABParams.java
@@ -0,0 +1,146 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class ERABParams 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 List<ERABParamsItem> seqOf = null;
+
+    public ERABParams() {
+        seqOf = new ArrayList<ERABParamsItem>();
+    }
+
+    public ERABParams(byte[] code) {
+        this.code = code;
+    }
+
+    @JsonValue
+    public List<ERABParamsItem> getERABParamsItem() {
+        if (seqOf == null) {
+            seqOf = new ArrayList<ERABParamsItem>();
+        }
+        return seqOf;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        for (int i = (seqOf.size() - 1); i >= 0; i--) {
+            codeLength += seqOf.get(i).encode(os, true);
+        }
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+        int totalLength = length.val;
+
+        while (subCodeLength < totalLength) {
+            ERABParamsItem element = new ERABParamsItem();
+            subCodeLength += element.decode(is, true);
+            seqOf.add(element);
+        }
+        if (subCodeLength != totalLength) {
+            throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+        }
+        codeLength += subCodeLength;
+
+        return codeLength;
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (seqOf == null) {
+            sb.append("null");
+        } else {
+            Iterator<ERABParamsItem> it = seqOf.iterator();
+            if (it.hasNext()) {
+                it.next().appendAsString(sb, indentLevel + 1);
+                while (it.hasNext()) {
+                    sb.append(",\n");
+                    for (int i = 0; i < indentLevel + 1; i++) {
+                        sb.append("\t");
+                    }
+                    it.next().appendAsString(sb, indentLevel + 1);
+                }
+            }
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABParamsItem.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABParamsItem.java
new file mode 100644
index 0000000..09d646e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABParamsItem.java
@@ -0,0 +1,394 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class ERABParamsItem 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 ERABID id = null;
+    private ERABDirection direction = null;
+    private ERABType type = null;
+    private QCI qci = null;
+    private BerInteger arp = null;
+    private BitRate gbrDl = null;
+    private BitRate gbrUl = null;
+    private BitRate mbrDl = null;
+    private BitRate mbrUl = null;
+
+    public ERABParamsItem() {
+    }
+
+    public ERABParamsItem(byte[] code) {
+        this.code = code;
+    }
+
+    public ERABID getId() {
+        return id;
+    }
+
+    public void setId(ERABID id) {
+        this.id = id;
+    }
+
+    public ERABDirection getDirection() {
+        return direction;
+    }
+
+    public void setDirection(ERABDirection direction) {
+        this.direction = direction;
+    }
+
+    public ERABType getType() {
+        return type;
+    }
+
+    public void setType(ERABType type) {
+        this.type = type;
+    }
+
+    public QCI getQci() {
+        return qci;
+    }
+
+    public void setQci(QCI qci) {
+        this.qci = qci;
+    }
+
+    public BerInteger getArp() {
+        return arp;
+    }
+
+    public void setArp(BerInteger arp) {
+        this.arp = arp;
+    }
+
+    public BitRate getGbrDl() {
+        return gbrDl;
+    }
+
+    public void setGbrDl(BitRate gbrDl) {
+        this.gbrDl = gbrDl;
+    }
+
+    public BitRate getGbrUl() {
+        return gbrUl;
+    }
+
+    public void setGbrUl(BitRate gbrUl) {
+        this.gbrUl = gbrUl;
+    }
+
+    public BitRate getMbrDl() {
+        return mbrDl;
+    }
+
+    public void setMbrDl(BitRate mbrDl) {
+        this.mbrDl = mbrDl;
+    }
+
+    public BitRate getMbrUl() {
+        return mbrUl;
+    }
+
+    public void setMbrUl(BitRate mbrUl) {
+        this.mbrUl = mbrUl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += mbrUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 8
+        os.write(0x88);
+        codeLength += 1;
+
+        codeLength += mbrDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 7
+        os.write(0x87);
+        codeLength += 1;
+
+        codeLength += gbrUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 6
+        os.write(0x86);
+        codeLength += 1;
+
+        codeLength += gbrDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 5
+        os.write(0x85);
+        codeLength += 1;
+
+        codeLength += arp.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 4
+        os.write(0x84);
+        codeLength += 1;
+
+        codeLength += qci.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += type.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += direction.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += id.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            id = new ERABID();
+            subCodeLength += id.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            direction = new ERABDirection();
+            subCodeLength += direction.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            type = new ERABType();
+            subCodeLength += type.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            qci = new QCI();
+            subCodeLength += qci.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+            arp = new BerInteger();
+            subCodeLength += arp.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
+            gbrDl = new BitRate();
+            subCodeLength += gbrDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 6)) {
+            gbrUl = new BitRate();
+            subCodeLength += gbrUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 7)) {
+            mbrDl = new BitRate();
+            subCodeLength += mbrDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 8)) {
+            mbrUl = new BitRate();
+            subCodeLength += mbrUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (id != null) {
+            sb.append("id: ").append(id);
+        } else {
+            sb.append("id: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (direction != null) {
+            sb.append("direction: ").append(direction);
+        } else {
+            sb.append("direction: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (type != null) {
+            sb.append("type: ").append(type);
+        } else {
+            sb.append("type: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (qci != null) {
+            sb.append("qci: ").append(qci);
+        } else {
+            sb.append("qci: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (arp != null) {
+            sb.append("arp: ").append(arp);
+        } else {
+            sb.append("arp: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (gbrDl != null) {
+            sb.append("gbrDl: ").append(gbrDl);
+        } else {
+            sb.append("gbrDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (gbrUl != null) {
+            sb.append("gbrUl: ").append(gbrUl);
+        } else {
+            sb.append("gbrUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (mbrDl != null) {
+            sb.append("mbrDl: ").append(mbrDl);
+        } else {
+            sb.append("mbrDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (mbrUl != null) {
+            sb.append("mbrUl: ").append(mbrUl);
+        } else {
+            sb.append("mbrUl: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABResponse.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABResponse.java
new file mode 100644
index 0000000..35b4fa6
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABResponse.java
@@ -0,0 +1,146 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class ERABResponse 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 List<ERABResponseItem> seqOf = null;
+
+    public ERABResponse() {
+        seqOf = new ArrayList<ERABResponseItem>();
+    }
+
+    public ERABResponse(byte[] code) {
+        this.code = code;
+    }
+
+    @JsonValue
+    public List<ERABResponseItem> getERABResponseItem() {
+        if (seqOf == null) {
+            seqOf = new ArrayList<ERABResponseItem>();
+        }
+        return seqOf;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        for (int i = (seqOf.size() - 1); i >= 0; i--) {
+            codeLength += seqOf.get(i).encode(os, true);
+        }
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+        int totalLength = length.val;
+
+        while (subCodeLength < totalLength) {
+            ERABResponseItem element = new ERABResponseItem();
+            subCodeLength += element.decode(is, true);
+            seqOf.add(element);
+        }
+        if (subCodeLength != totalLength) {
+            throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+        }
+        codeLength += subCodeLength;
+
+        return codeLength;
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (seqOf == null) {
+            sb.append("null");
+        } else {
+            Iterator<ERABResponseItem> it = seqOf.iterator();
+            if (it.hasNext()) {
+                it.next().appendAsString(sb, indentLevel + 1);
+                while (it.hasNext()) {
+                    sb.append(",\n");
+                    for (int i = 0; i < indentLevel + 1; i++) {
+                        sb.append("\t");
+                    }
+                    it.next().appendAsString(sb, indentLevel + 1);
+                }
+            }
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABResponseItem.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABResponseItem.java
new file mode 100644
index 0000000..4fc7e48
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABResponseItem.java
@@ -0,0 +1,169 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class ERABResponseItem 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 ERABID id = null;
+    private ERABDecision decision = null;
+
+    public ERABResponseItem() {
+    }
+
+    public ERABResponseItem(byte[] code) {
+        this.code = code;
+    }
+
+    public ERABID getId() {
+        return id;
+    }
+
+    public void setId(ERABID id) {
+        this.id = id;
+    }
+
+    public ERABDecision getDecision() {
+        return decision;
+    }
+
+    public void setDecision(ERABDecision decision) {
+        this.decision = decision;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += decision.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += id.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            id = new ERABID();
+            subCodeLength += id.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            decision = new ERABDecision();
+            subCodeLength += decision.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (id != null) {
+            sb.append("id: ").append(id);
+        } else {
+            sb.append("id: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (decision != null) {
+            sb.append("decision: ").append(decision);
+        } else {
+            sb.append("decision: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABType.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABType.java
new file mode 100644
index 0000000..707eff5
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ERABType.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class ERABType extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public ERABType() {
+    }
+
+    public ERABType(byte[] code) {
+        super(code);
+    }
+
+    public ERABType(BigInteger value) {
+        super(value);
+    }
+
+    public ERABType(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/EUTRANCellIdentifier.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/EUTRANCellIdentifier.java
new file mode 100644
index 0000000..2f1394c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/EUTRANCellIdentifier.java
@@ -0,0 +1,39 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerBitString;
+
+import java.util.Arrays;
+
+
+public class EUTRANCellIdentifier extends BerBitString {
+
+    private static final long serialVersionUID = 1L;
+
+    public EUTRANCellIdentifier() {
+    }
+
+    public EUTRANCellIdentifier(byte[] code) {
+        super(code);
+    }
+
+    public EUTRANCellIdentifier(byte[] value, int numBits) {
+        super(value, numBits);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof EUTRANCellIdentifier) {
+            return Arrays.equals(value, ((EUTRANCellIdentifier) obj).value);
+        }
+        return super.equals(obj);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/HOFailureCause.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/HOFailureCause.java
new file mode 100644
index 0000000..f37f200
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/HOFailureCause.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class HOFailureCause extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public HOFailureCause() {
+    }
+
+    public HOFailureCause(byte[] code) {
+        super(code);
+    }
+
+    public HOFailureCause(BigInteger value) {
+        super(value);
+    }
+
+    public HOFailureCause(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/Hysteresis.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/Hysteresis.java
new file mode 100644
index 0000000..53c614c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/Hysteresis.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class Hysteresis extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public Hysteresis() {
+    }
+
+    public Hysteresis(byte[] code) {
+        super(code);
+    }
+
+    public Hysteresis(BigInteger value) {
+        super(value);
+    }
+
+    public Hysteresis(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/L2MeasReportInterval.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/L2MeasReportInterval.java
new file mode 100644
index 0000000..8d23563
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/L2MeasReportInterval.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class L2MeasReportInterval extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public L2MeasReportInterval() {
+    }
+
+    public L2MeasReportInterval(byte[] code) {
+        super(code);
+    }
+
+    public L2MeasReportInterval(BigInteger value) {
+        super(value);
+    }
+
+    public L2MeasReportInterval(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/L2ReportInterval.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/L2ReportInterval.java
new file mode 100644
index 0000000..e3febdb
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/L2ReportInterval.java
@@ -0,0 +1,265 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class L2ReportInterval 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 L2MeasReportInterval tRadioMeasReportPerUe = null;
+    private L2MeasReportInterval tRadioMeasReportPerCell = null;
+    private L2MeasReportInterval tRadioSchedReportPerUe = null;
+    private L2MeasReportInterval tRadioSchedReportPerCell = null;
+    private L2MeasReportInterval tPdcpMeasReportPerUe = null;
+
+    public L2ReportInterval() {
+    }
+
+    public L2ReportInterval(byte[] code) {
+        this.code = code;
+    }
+
+    public L2MeasReportInterval getTRadioMeasReportPerUe() {
+        return tRadioMeasReportPerUe;
+    }
+
+    public void setTRadioMeasReportPerUe(L2MeasReportInterval tRadioMeasReportPerUe) {
+        this.tRadioMeasReportPerUe = tRadioMeasReportPerUe;
+    }
+
+    public L2MeasReportInterval getTRadioMeasReportPerCell() {
+        return tRadioMeasReportPerCell;
+    }
+
+    public void setTRadioMeasReportPerCell(L2MeasReportInterval tRadioMeasReportPerCell) {
+        this.tRadioMeasReportPerCell = tRadioMeasReportPerCell;
+    }
+
+    public L2MeasReportInterval getTRadioSchedReportPerUe() {
+        return tRadioSchedReportPerUe;
+    }
+
+    public void setTRadioSchedReportPerUe(L2MeasReportInterval tRadioSchedReportPerUe) {
+        this.tRadioSchedReportPerUe = tRadioSchedReportPerUe;
+    }
+
+    public L2MeasReportInterval getTRadioSchedReportPerCell() {
+        return tRadioSchedReportPerCell;
+    }
+
+    public void setTRadioSchedReportPerCell(L2MeasReportInterval tRadioSchedReportPerCell) {
+        this.tRadioSchedReportPerCell = tRadioSchedReportPerCell;
+    }
+
+    public L2MeasReportInterval getTPdcpMeasReportPerUe() {
+        return tPdcpMeasReportPerUe;
+    }
+
+    public void setTPdcpMeasReportPerUe(L2MeasReportInterval tPdcpMeasReportPerUe) {
+        this.tPdcpMeasReportPerUe = tPdcpMeasReportPerUe;
+    }
+
+    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 += tPdcpMeasReportPerUe.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 4
+        os.write(0x84);
+        codeLength += 1;
+
+        codeLength += tRadioSchedReportPerCell.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += tRadioSchedReportPerUe.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += tRadioMeasReportPerCell.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += tRadioMeasReportPerUe.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)) {
+            tRadioMeasReportPerUe = new L2MeasReportInterval();
+            subCodeLength += tRadioMeasReportPerUe.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)) {
+            tRadioMeasReportPerCell = new L2MeasReportInterval();
+            subCodeLength += tRadioMeasReportPerCell.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            tRadioSchedReportPerUe = new L2MeasReportInterval();
+            subCodeLength += tRadioSchedReportPerUe.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            tRadioSchedReportPerCell = new L2MeasReportInterval();
+            subCodeLength += tRadioSchedReportPerCell.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+            tPdcpMeasReportPerUe = new L2MeasReportInterval();
+            subCodeLength += tPdcpMeasReportPerUe.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (tRadioMeasReportPerUe != null) {
+            sb.append("tRadioMeasReportPerUe: ").append(tRadioMeasReportPerUe);
+        } else {
+            sb.append("tRadioMeasReportPerUe: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (tRadioMeasReportPerCell != null) {
+            sb.append("tRadioMeasReportPerCell: ").append(tRadioMeasReportPerCell);
+        } else {
+            sb.append("tRadioMeasReportPerCell: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (tRadioSchedReportPerUe != null) {
+            sb.append("tRadioSchedReportPerUe: ").append(tRadioSchedReportPerUe);
+        } else {
+            sb.append("tRadioSchedReportPerUe: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (tRadioSchedReportPerCell != null) {
+            sb.append("tRadioSchedReportPerCell: ").append(tRadioSchedReportPerCell);
+        } else {
+            sb.append("tRadioSchedReportPerCell: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (tPdcpMeasReportPerUe != null) {
+            sb.append("tPdcpMeasReportPerUe: ").append(tPdcpMeasReportPerUe);
+        } else {
+            sb.append("tPdcpMeasReportPerUe: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MMEUES1APID.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MMEUES1APID.java
new file mode 100644
index 0000000..d8876bc
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MMEUES1APID.java
@@ -0,0 +1,44 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+import java.util.Objects;
+
+
+public class MMEUES1APID extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public MMEUES1APID() {
+    }
+
+    public MMEUES1APID(byte[] code) {
+        super(code);
+    }
+
+    public MMEUES1APID(BigInteger value) {
+        super(value);
+    }
+
+    public MMEUES1APID(long value) {
+        super(value);
+    }
+
+    @Override
+    public int hashCode() {
+        return value.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof MMEUES1APID) {
+            return Objects.equals(value, ((MMEUES1APID) obj).value);
+        }
+        return super.equals(obj);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MeasID.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MeasID.java
new file mode 100644
index 0000000..e2f1be7
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MeasID.java
@@ -0,0 +1,615 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerBoolean;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class MeasID 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 measobjectId = null;
+    private BerInteger reportconfigId = null;
+    private Action action = null;
+    public MeasID() {
+    }
+
+    public MeasID(byte[] code) {
+        this.code = code;
+    }
+
+    public BerInteger getMeasobjectId() {
+        return measobjectId;
+    }
+
+    public void setMeasobjectId(BerInteger measobjectId) {
+        this.measobjectId = measobjectId;
+    }
+
+    public BerInteger getReportconfigId() {
+        return reportconfigId;
+    }
+
+    public void setReportconfigId(BerInteger reportconfigId) {
+        this.reportconfigId = reportconfigId;
+    }
+
+    public Action getAction() {
+        return action;
+    }
+
+    public void setAction(Action action) {
+        this.action = action;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        int sublength;
+
+        sublength = action.encode(os);
+        codeLength += sublength;
+        codeLength += BerLength.encodeLength(os, sublength);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += reportconfigId.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += measobjectId.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)) {
+            measobjectId = new BerInteger();
+            subCodeLength += measobjectId.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)) {
+            reportconfigId = new BerInteger();
+            subCodeLength += reportconfigId.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            subCodeLength += length.decode(is);
+            action = new Action();
+            subCodeLength += action.decode(is, null);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (measobjectId != null) {
+            sb.append("measobjectId: ").append(measobjectId);
+        } else {
+            sb.append("measobjectId: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (reportconfigId != null) {
+            sb.append("reportconfigId: ").append(reportconfigId);
+        } else {
+            sb.append("reportconfigId: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (action != null) {
+            sb.append("action: ");
+            action.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("action: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class Action implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        @JsonIgnore
+        public byte[] code = null;
+        private Addmeasid addmeasid = null;
+        private Delmeasid delmeasid = null;
+        private BerBoolean hototarget = null;
+        public Action() {
+        }
+        public Action(byte[] code) {
+            this.code = code;
+        }
+
+        public Addmeasid getAddmeasid() {
+            return addmeasid;
+        }
+
+        public void setAddmeasid(Addmeasid addmeasid) {
+            this.addmeasid = addmeasid;
+        }
+
+        public Delmeasid getDelmeasid() {
+            return delmeasid;
+        }
+
+        public void setDelmeasid(Delmeasid delmeasid) {
+            this.delmeasid = delmeasid;
+        }
+
+        public BerBoolean getHototarget() {
+            return hototarget;
+        }
+
+        public void setHototarget(BerBoolean hototarget) {
+            this.hototarget = hototarget;
+        }
+
+        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 (hototarget != null) {
+                codeLength += hototarget.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+                os.write(0x82);
+                codeLength += 1;
+                return codeLength;
+            }
+
+            if (delmeasid != null) {
+                codeLength += delmeasid.encode(os, false);
+                // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+                os.write(0xA1);
+                codeLength += 1;
+                return codeLength;
+            }
+
+            if (addmeasid != null) {
+                codeLength += addmeasid.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)) {
+                addmeasid = new Addmeasid();
+                codeLength += addmeasid.decode(is, false);
+                return codeLength;
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+                delmeasid = new Delmeasid();
+                codeLength += delmeasid.decode(is, false);
+                return codeLength;
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+                hototarget = new BerBoolean();
+                codeLength += hototarget.decode(is, false);
+                return codeLength;
+            }
+
+            if (passedTag != null) {
+                return 0;
+            }
+
+            throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            if (addmeasid != null) {
+                sb.append("addmeasid: ");
+                addmeasid.appendAsString(sb, indentLevel + 1);
+                return;
+            }
+
+            if (delmeasid != null) {
+                sb.append("delmeasid: ");
+                delmeasid.appendAsString(sb, indentLevel + 1);
+                return;
+            }
+
+            if (hototarget != null) {
+                sb.append("hototarget: ").append(hototarget);
+                return;
+            }
+
+            sb.append("<none>");
+        }
+
+        public static class Addmeasid 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 List<BerInteger> seqOf = null;
+
+            public Addmeasid() {
+                seqOf = new ArrayList<BerInteger>();
+            }
+
+            public Addmeasid(byte[] code) {
+                this.code = code;
+            }
+
+            @JsonValue
+            public List<BerInteger> getBerInteger() {
+                if (seqOf == null) {
+                    seqOf = new ArrayList<BerInteger>();
+                }
+                return seqOf;
+            }
+
+            public int encode(BerByteArrayOutputStream os) throws IOException {
+                return encode(os, true);
+            }
+
+            public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+                if (code != null) {
+                    for (int i = code.length - 1; i >= 0; i--) {
+                        os.write(code[i]);
+                    }
+                    if (withTag) {
+                        return tag.encode(os) + code.length;
+                    }
+                    return code.length;
+                }
+
+                int codeLength = 0;
+                for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                    codeLength += seqOf.get(i).encode(os, true);
+                }
+
+                codeLength += BerLength.encodeLength(os, codeLength);
+
+                if (withTag) {
+                    codeLength += tag.encode(os);
+                }
+
+                return codeLength;
+            }
+
+            public int decode(InputStream is) throws IOException {
+                return decode(is, true);
+            }
+
+            public int decode(InputStream is, boolean withTag) throws IOException {
+                int codeLength = 0;
+                int subCodeLength = 0;
+                if (withTag) {
+                    codeLength += tag.decodeAndCheck(is);
+                }
+
+                BerLength length = new BerLength();
+                codeLength += length.decode(is);
+                int totalLength = length.val;
+
+                while (subCodeLength < totalLength) {
+                    BerInteger element = new BerInteger();
+                    subCodeLength += element.decode(is, true);
+                    seqOf.add(element);
+                }
+                if (subCodeLength != totalLength) {
+                    throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+                }
+                codeLength += subCodeLength;
+
+                return codeLength;
+            }
+
+            public void encodeAndSave(int encodingSizeGuess) throws IOException {
+                BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+                encode(os, false);
+                code = os.getArray();
+            }
+
+            public String toString() {
+                StringBuilder sb = new StringBuilder();
+                appendAsString(sb, 0);
+                return sb.toString();
+            }
+
+            public void appendAsString(StringBuilder sb, int indentLevel) {
+
+                sb.append("{\n");
+                for (int i = 0; i < indentLevel + 1; i++) {
+                    sb.append("\t");
+                }
+                if (seqOf == null) {
+                    sb.append("null");
+                } else {
+                    Iterator<BerInteger> it = seqOf.iterator();
+                    if (it.hasNext()) {
+                        sb.append(it.next());
+                        while (it.hasNext()) {
+                            sb.append(",\n");
+                            for (int i = 0; i < indentLevel + 1; i++) {
+                                sb.append("\t");
+                            }
+                            sb.append(it.next());
+                        }
+                    }
+                }
+
+                sb.append("\n");
+                for (int i = 0; i < indentLevel; i++) {
+                    sb.append("\t");
+                }
+                sb.append("}");
+            }
+
+        }
+
+        public static class Delmeasid 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 List<BerInteger> seqOf = null;
+
+            public Delmeasid() {
+                seqOf = new ArrayList<BerInteger>();
+            }
+
+            public Delmeasid(byte[] code) {
+                this.code = code;
+            }
+
+            @JsonValue
+            public List<BerInteger> getBerInteger() {
+                if (seqOf == null) {
+                    seqOf = new ArrayList<BerInteger>();
+                }
+                return seqOf;
+            }
+
+            public int encode(BerByteArrayOutputStream os) throws IOException {
+                return encode(os, true);
+            }
+
+            public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+                if (code != null) {
+                    for (int i = code.length - 1; i >= 0; i--) {
+                        os.write(code[i]);
+                    }
+                    if (withTag) {
+                        return tag.encode(os) + code.length;
+                    }
+                    return code.length;
+                }
+
+                int codeLength = 0;
+                for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                    codeLength += seqOf.get(i).encode(os, true);
+                }
+
+                codeLength += BerLength.encodeLength(os, codeLength);
+
+                if (withTag) {
+                    codeLength += tag.encode(os);
+                }
+
+                return codeLength;
+            }
+
+            public int decode(InputStream is) throws IOException {
+                return decode(is, true);
+            }
+
+            public int decode(InputStream is, boolean withTag) throws IOException {
+                int codeLength = 0;
+                int subCodeLength = 0;
+                if (withTag) {
+                    codeLength += tag.decodeAndCheck(is);
+                }
+
+                BerLength length = new BerLength();
+                codeLength += length.decode(is);
+                int totalLength = length.val;
+
+                while (subCodeLength < totalLength) {
+                    BerInteger element = new BerInteger();
+                    subCodeLength += element.decode(is, true);
+                    seqOf.add(element);
+                }
+                if (subCodeLength != totalLength) {
+                    throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+                }
+                codeLength += subCodeLength;
+
+                return codeLength;
+            }
+
+            public void encodeAndSave(int encodingSizeGuess) throws IOException {
+                BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+                encode(os, false);
+                code = os.getArray();
+            }
+
+            public String toString() {
+                StringBuilder sb = new StringBuilder();
+                appendAsString(sb, 0);
+                return sb.toString();
+            }
+
+            public void appendAsString(StringBuilder sb, int indentLevel) {
+
+                sb.append("{\n");
+                for (int i = 0; i < indentLevel + 1; i++) {
+                    sb.append("\t");
+                }
+                if (seqOf == null) {
+                    sb.append("null");
+                } else {
+                    Iterator<BerInteger> it = seqOf.iterator();
+                    if (it.hasNext()) {
+                        sb.append(it.next());
+                        while (it.hasNext()) {
+                            sb.append(",\n");
+                            for (int i = 0; i < indentLevel + 1; i++) {
+                                sb.append("\t");
+                            }
+                            sb.append(it.next());
+                        }
+                    }
+                }
+
+                sb.append("\n");
+                for (int i = 0; i < indentLevel; i++) {
+                    sb.append("\t");
+                }
+                sb.append("}");
+            }
+
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MeasObject.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MeasObject.java
new file mode 100644
index 0000000..7c9f73f
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/MeasObject.java
@@ -0,0 +1,328 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class MeasObject 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 ARFCNValue dlFreq = null;
+    private MeasCells measCells = null;
+    public MeasObject() {
+    }
+
+    public MeasObject(byte[] code) {
+        this.code = code;
+    }
+
+    public ARFCNValue getDlFreq() {
+        return dlFreq;
+    }
+
+    public void setDlFreq(ARFCNValue dlFreq) {
+        this.dlFreq = dlFreq;
+    }
+
+    public MeasCells getMeasCells() {
+        return measCells;
+    }
+
+    public void setMeasCells(MeasCells measCells) {
+        this.measCells = measCells;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        if (measCells != null) {
+            codeLength += measCells.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+            os.write(0xA1);
+            codeLength += 1;
+        }
+
+        codeLength += dlFreq.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)) {
+            dlFreq = new ARFCNValue();
+            subCodeLength += dlFreq.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            measCells = new MeasCells();
+            subCodeLength += measCells.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (dlFreq != null) {
+            sb.append("dlFreq: ").append(dlFreq);
+        } else {
+            sb.append("dlFreq: <empty-required-field>");
+        }
+
+        if (measCells != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("measCells: ");
+            measCells.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class MeasCells 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 PhysCellId pci = null;
+        private QOffsetRange cellIndividualOffset = null;
+
+        public MeasCells() {
+        }
+
+        public MeasCells(byte[] code) {
+            this.code = code;
+        }
+
+        public PhysCellId getPci() {
+            return pci;
+        }
+
+        public void setPci(PhysCellId pci) {
+            this.pci = pci;
+        }
+
+        public QOffsetRange getCellIndividualOffset() {
+            return cellIndividualOffset;
+        }
+
+        public void setCellIndividualOffset(QOffsetRange cellIndividualOffset) {
+            this.cellIndividualOffset = cellIndividualOffset;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            if (cellIndividualOffset != null) {
+                codeLength += cellIndividualOffset.encode(os, false);
+                // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+                os.write(0x81);
+                codeLength += 1;
+            }
+
+            codeLength += pci.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+            os.write(0x80);
+            codeLength += 1;
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            BerTag berTag = new BerTag();
+
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+
+            int totalLength = length.val;
+            codeLength += totalLength;
+
+            subCodeLength += berTag.decode(is);
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+                pci = new PhysCellId();
+                subCodeLength += pci.decode(is, false);
+                if (subCodeLength == totalLength) {
+                    return codeLength;
+                }
+                subCodeLength += berTag.decode(is);
+            } else {
+                throw new IOException("Tag does not match the mandatory sequence element tag.");
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+                cellIndividualOffset = new QOffsetRange();
+                subCodeLength += cellIndividualOffset.decode(is, false);
+                if (subCodeLength == totalLength) {
+                    return codeLength;
+                }
+            }
+            throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{");
+            sb.append("\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (pci != null) {
+                sb.append("pci: ").append(pci);
+            } else {
+                sb.append("pci: <empty-required-field>");
+            }
+
+            if (cellIndividualOffset != null) {
+                sb.append(",\n");
+                for (int i = 0; i < indentLevel + 1; i++) {
+                    sb.append("\t");
+                }
+                sb.append("cellIndividualOffset: ").append(cellIndividualOffset);
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PCIARFCN.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PCIARFCN.java
new file mode 100644
index 0000000..5d50d9e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PCIARFCN.java
@@ -0,0 +1,184 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class PCIARFCN 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 PhysCellId pci = null;
+    private ARFCNValue earfcnDl = null;
+
+    public PCIARFCN() {
+    }
+
+    public PCIARFCN(byte[] code) {
+        this.code = code;
+    }
+
+    public PhysCellId getPci() {
+        return pci;
+    }
+
+    public void setPci(PhysCellId pci) {
+        this.pci = pci;
+    }
+
+    public ARFCNValue getEarfcnDl() {
+        return earfcnDl;
+    }
+
+    public void setEarfcnDl(ARFCNValue earfcnDl) {
+        this.earfcnDl = earfcnDl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += earfcnDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += pci.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            pci = new PhysCellId();
+            subCodeLength += pci.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            earfcnDl = new ARFCNValue();
+            subCodeLength += earfcnDl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pci != null) {
+            sb.append("pci: ").append(pci);
+        } else {
+            sb.append("pci: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (earfcnDl != null) {
+            sb.append("earfcnDl: ").append(earfcnDl);
+        } else {
+            sb.append("earfcnDl: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof PCIARFCN) {
+            return pci.equals(((PCIARFCN) o).getPci()) && earfcnDl.equals(((PCIARFCN) o).getEarfcnDl());
+        }
+
+        return super.equals(o);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = pci.hashCode();
+        result = 31 * result + earfcnDl.hashCode();
+        return result;
+    }
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PLMNIdentity.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PLMNIdentity.java
new file mode 100644
index 0000000..0d3a8c6
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PLMNIdentity.java
@@ -0,0 +1,35 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerOctetString;
+
+import java.util.Arrays;
+
+
+public class PLMNIdentity extends BerOctetString {
+
+    private static final long serialVersionUID = 1L;
+
+    public PLMNIdentity() {
+    }
+
+    public PLMNIdentity(byte[] value) {
+        super(value);
+    }
+
+    @Override
+    public int hashCode() {
+        return Arrays.hashCode(value);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof PLMNIdentity) {
+            return Arrays.equals(value, ((PLMNIdentity) obj).value);
+        }
+        return super.equals(obj);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PRBUsage.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PRBUsage.java
new file mode 100644
index 0000000..c7d846a
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PRBUsage.java
@@ -0,0 +1,426 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class PRBUsage 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 PrbUsageDl prbUsageDl = null;
+    private PrbUsageUl prbUsageUl = null;
+    public PRBUsage() {
+    }
+    public PRBUsage(byte[] code) {
+        this.code = code;
+    }
+
+    public PrbUsageDl getPrbUsageDl() {
+        return prbUsageDl;
+    }
+
+    public void setPrbUsageDl(PrbUsageDl prbUsageDl) {
+        this.prbUsageDl = prbUsageDl;
+    }
+
+    public PrbUsageUl getPrbUsageUl() {
+        return prbUsageUl;
+    }
+
+    public void setPrbUsageUl(PrbUsageUl prbUsageUl) {
+        this.prbUsageUl = prbUsageUl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += prbUsageUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += prbUsageDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            prbUsageDl = new PrbUsageDl();
+            subCodeLength += prbUsageDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            prbUsageUl = new PrbUsageUl();
+            subCodeLength += prbUsageUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (prbUsageDl != null) {
+            sb.append("prbUsageDl: ");
+            prbUsageDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("prbUsageDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (prbUsageUl != null) {
+            sb.append("prbUsageUl: ");
+            prbUsageUl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("prbUsageUl: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class PrbUsageDl 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 List<BerInteger> seqOf = null;
+
+        public PrbUsageDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PrbUsageDl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PrbUsageUl 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 List<BerInteger> seqOf = null;
+
+        public PrbUsageUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PrbUsageUl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PerParam.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PerParam.java
new file mode 100644
index 0000000..c287c2e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PerParam.java
@@ -0,0 +1,138 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class PerParam 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 BerEnum reportIntervalMs = null;
+
+    public PerParam() {
+    }
+
+    public PerParam(byte[] code) {
+        this.code = code;
+    }
+
+    public BerEnum getReportIntervalMs() {
+        return reportIntervalMs;
+    }
+
+    public void setReportIntervalMs(BerEnum reportIntervalMs) {
+        this.reportIntervalMs = reportIntervalMs;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += reportIntervalMs.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 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)) {
+            reportIntervalMs = new BerEnum();
+            subCodeLength += reportIntervalMs.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (reportIntervalMs != null) {
+            sb.append("reportIntervalMs: ").append(reportIntervalMs);
+        } else {
+            sb.append("reportIntervalMs: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PhysCellId.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PhysCellId.java
new file mode 100644
index 0000000..f875fee
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PhysCellId.java
@@ -0,0 +1,43 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class PhysCellId extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public PhysCellId() {
+    }
+
+    public PhysCellId(byte[] code) {
+        super(code);
+    }
+
+    public PhysCellId(BigInteger value) {
+        super(value);
+    }
+
+    public PhysCellId(long value) {
+        super(value);
+    }
+
+    @Override
+    public int hashCode() {
+        return value.intValue();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof PhysCellId) {
+            return value.intValue() == ((PhysCellId) obj).value.intValue();
+        }
+        return super.equals(obj);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PropScell.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PropScell.java
new file mode 100644
index 0000000..7f84337
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/PropScell.java
@@ -0,0 +1,237 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerBoolean;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class PropScell 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 PCIARFCN pciArfcn = null;
+    private BerBoolean crossCarrierSchedEnable = null;
+    private BerEnum caDirection = null;
+    private BerInteger deactTimer = null;
+
+    public PropScell() {
+    }
+
+    public PropScell(byte[] code) {
+        this.code = code;
+    }
+
+    public PCIARFCN getPciArfcn() {
+        return pciArfcn;
+    }
+
+    public void setPciArfcn(PCIARFCN pciArfcn) {
+        this.pciArfcn = pciArfcn;
+    }
+
+    public BerBoolean getCrossCarrierSchedEnable() {
+        return crossCarrierSchedEnable;
+    }
+
+    public void setCrossCarrierSchedEnable(BerBoolean crossCarrierSchedEnable) {
+        this.crossCarrierSchedEnable = crossCarrierSchedEnable;
+    }
+
+    public BerEnum getCaDirection() {
+        return caDirection;
+    }
+
+    public void setCaDirection(BerEnum caDirection) {
+        this.caDirection = caDirection;
+    }
+
+    public BerInteger getDeactTimer() {
+        return deactTimer;
+    }
+
+    public void setDeactTimer(BerInteger deactTimer) {
+        this.deactTimer = deactTimer;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += deactTimer.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += caDirection.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += crossCarrierSchedEnable.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += pciArfcn.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            pciArfcn = new PCIARFCN();
+            subCodeLength += pciArfcn.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            crossCarrierSchedEnable = new BerBoolean();
+            subCodeLength += crossCarrierSchedEnable.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            caDirection = new BerEnum();
+            subCodeLength += caDirection.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            deactTimer = new BerInteger();
+            subCodeLength += deactTimer.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pciArfcn != null) {
+            sb.append("pciArfcn: ");
+            pciArfcn.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pciArfcn: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crossCarrierSchedEnable != null) {
+            sb.append("crossCarrierSchedEnable: ").append(crossCarrierSchedEnable);
+        } else {
+            sb.append("crossCarrierSchedEnable: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (caDirection != null) {
+            sb.append("caDirection: ").append(caDirection);
+        } else {
+            sb.append("caDirection: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (deactTimer != null) {
+            sb.append("deactTimer: ").append(deactTimer);
+        } else {
+            sb.append("deactTimer: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/QCI.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/QCI.java
new file mode 100644
index 0000000..e8b2bee
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/QCI.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class QCI extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public QCI() {
+    }
+
+    public QCI(byte[] code) {
+        super(code);
+    }
+
+    public QCI(BigInteger value) {
+        super(value);
+    }
+
+    public QCI(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/QOffsetRange.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/QOffsetRange.java
new file mode 100644
index 0000000..4eb2577
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/QOffsetRange.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class QOffsetRange extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public QOffsetRange() {
+    }
+
+    public QOffsetRange(byte[] code) {
+        super(code);
+    }
+
+    public QOffsetRange(BigInteger value) {
+        super(value);
+    }
+
+    public QOffsetRange(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RSRPRange.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RSRPRange.java
new file mode 100644
index 0000000..836d36b
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RSRPRange.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class RSRPRange extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public RSRPRange() {
+    }
+
+    public RSRPRange(byte[] code) {
+        super(code);
+    }
+
+    public RSRPRange(BigInteger value) {
+        super(value);
+    }
+
+    public RSRPRange(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RSRQRange.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RSRQRange.java
new file mode 100644
index 0000000..f34b201
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RSRQRange.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.math.BigInteger;
+
+
+public class RSRQRange extends BerInteger {
+
+    private static final long serialVersionUID = 1L;
+
+    public RSRQRange() {
+    }
+
+    public RSRQRange(byte[] code) {
+        super(code);
+    }
+
+    public RSRQRange(BigInteger value) {
+        super(value);
+    }
+
+    public RSRQRange(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RXSigReport.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RXSigReport.java
new file mode 100644
index 0000000..afd630a
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RXSigReport.java
@@ -0,0 +1,240 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class RXSigReport 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 PCIARFCN pciArfcn = null;
+    private ECGI ecgi = null;
+    private RSRPRange rsrp = null;
+    private RSRQRange rsrq = null;
+
+    public RXSigReport() {
+    }
+
+    public RXSigReport(byte[] code) {
+        this.code = code;
+    }
+
+    public PCIARFCN getPciArfcn() {
+        return pciArfcn;
+    }
+
+    public void setPciArfcn(PCIARFCN pciArfcn) {
+        this.pciArfcn = pciArfcn;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public RSRPRange getRsrp() {
+        return rsrp;
+    }
+
+    public void setRsrp(RSRPRange rsrp) {
+        this.rsrp = rsrp;
+    }
+
+    public RSRQRange getRsrq() {
+        return rsrq;
+    }
+
+    public void setRsrq(RSRQRange rsrq) {
+        this.rsrq = rsrq;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        if (rsrq != null) {
+            codeLength += rsrq.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+            os.write(0x83);
+            codeLength += 1;
+        }
+
+        if (rsrp != null) {
+            codeLength += rsrp.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+            os.write(0x82);
+            codeLength += 1;
+        }
+
+        if (ecgi != null) {
+            codeLength += ecgi.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+            os.write(0xA1);
+            codeLength += 1;
+        }
+
+        codeLength += pciArfcn.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            pciArfcn = new PCIARFCN();
+            subCodeLength += pciArfcn.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            rsrp = new RSRPRange();
+            subCodeLength += rsrp.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            rsrq = new RSRQRange();
+            subCodeLength += rsrq.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pciArfcn != null) {
+            sb.append("pciArfcn: ");
+            pciArfcn.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pciArfcn: <empty-required-field>");
+        }
+
+        if (ecgi != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (rsrp != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("rsrp: ").append(rsrp);
+        }
+
+        if (rsrq != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("rsrq: ").append(rsrq);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RadioRepPerServCell.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RadioRepPerServCell.java
new file mode 100644
index 0000000..e6607cf
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RadioRepPerServCell.java
@@ -0,0 +1,777 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class RadioRepPerServCell implements Serializable {
+
+    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 ECGI ecgi = null;
+    private CqiHist cqiHist = null;
+    private RiHist riHist = null;
+    private PuschSinrHist puschSinrHist = null;
+    private PucchSinrHist pucchSinrHist = null;
+    public RadioRepPerServCell() {
+    }
+    public RadioRepPerServCell(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public CqiHist getCqiHist() {
+        return cqiHist;
+    }
+
+    public void setCqiHist(CqiHist cqiHist) {
+        this.cqiHist = cqiHist;
+    }
+
+    public RiHist getRiHist() {
+        return riHist;
+    }
+
+    public void setRiHist(RiHist riHist) {
+        this.riHist = riHist;
+    }
+
+    public PuschSinrHist getPuschSinrHist() {
+        return puschSinrHist;
+    }
+
+    public void setPuschSinrHist(PuschSinrHist puschSinrHist) {
+        this.puschSinrHist = puschSinrHist;
+    }
+
+    public PucchSinrHist getPucchSinrHist() {
+        return pucchSinrHist;
+    }
+
+    public void setPucchSinrHist(PucchSinrHist pucchSinrHist) {
+        this.pucchSinrHist = pucchSinrHist;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += pucchSinrHist.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+        os.write(0xA4);
+        codeLength += 1;
+
+        codeLength += puschSinrHist.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += riHist.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += cqiHist.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            cqiHist = new CqiHist();
+            subCodeLength += cqiHist.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            riHist = new RiHist();
+            subCodeLength += riHist.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            puschSinrHist = new PuschSinrHist();
+            subCodeLength += puschSinrHist.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+            pucchSinrHist = new PucchSinrHist();
+            subCodeLength += pucchSinrHist.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (cqiHist != null) {
+            sb.append("cqiHist: ");
+            cqiHist.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("cqiHist: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (riHist != null) {
+            sb.append("riHist: ");
+            riHist.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("riHist: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (puschSinrHist != null) {
+            sb.append("puschSinrHist: ");
+            puschSinrHist.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("puschSinrHist: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pucchSinrHist != null) {
+            sb.append("pucchSinrHist: ");
+            pucchSinrHist.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pucchSinrHist: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class CqiHist 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 List<BerInteger> seqOf = null;
+
+        public CqiHist() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public CqiHist(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class RiHist 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 List<BerInteger> seqOf = null;
+
+        public RiHist() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public RiHist(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PuschSinrHist 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 List<BerInteger> seqOf = null;
+
+        public PuschSinrHist() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PuschSinrHist(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PucchSinrHist 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 List<BerInteger> seqOf = null;
+
+        public PucchSinrHist() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PucchSinrHist(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ReconfIndReason.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ReconfIndReason.java
new file mode 100644
index 0000000..54ebc11
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ReconfIndReason.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class ReconfIndReason extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public ReconfIndReason() {
+    }
+
+    public ReconfIndReason(byte[] code) {
+        super(code);
+    }
+
+    public ReconfIndReason(BigInteger value) {
+        super(value);
+    }
+
+    public ReconfIndReason(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RelCause.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RelCause.java
new file mode 100644
index 0000000..eb4b62e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/RelCause.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class RelCause extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public RelCause() {
+    }
+
+    public RelCause(byte[] code) {
+        super(code);
+    }
+
+    public RelCause(BigInteger value) {
+        super(value);
+    }
+
+    public RelCause(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ReportConfig.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ReportConfig.java
new file mode 100644
index 0000000..c7314a6
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ReportConfig.java
@@ -0,0 +1,662 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class ReportConfig 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 ReportParams reportParams = null;
+    private BerEnum triggerQuantity = null;
+    private BerEnum reportQuantity = null;
+    public ReportConfig() {
+    }
+
+    public ReportConfig(byte[] code) {
+        this.code = code;
+    }
+
+    public ReportParams getReportParams() {
+        return reportParams;
+    }
+
+    public void setReportParams(ReportParams reportParams) {
+        this.reportParams = reportParams;
+    }
+
+    public BerEnum getTriggerQuantity() {
+        return triggerQuantity;
+    }
+
+    public void setTriggerQuantity(BerEnum triggerQuantity) {
+        this.triggerQuantity = triggerQuantity;
+    }
+
+    public BerEnum getReportQuantity() {
+        return reportQuantity;
+    }
+
+    public void setReportQuantity(BerEnum reportQuantity) {
+        this.reportQuantity = reportQuantity;
+    }
+
+    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 += reportQuantity.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += triggerQuantity.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += reportParams.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            reportParams = new ReportParams();
+            subCodeLength += reportParams.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)) {
+            triggerQuantity = new BerEnum();
+            subCodeLength += triggerQuantity.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            reportQuantity = new BerEnum();
+            subCodeLength += reportQuantity.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (reportParams != null) {
+            sb.append("reportParams: ");
+            reportParams.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("reportParams: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (triggerQuantity != null) {
+            sb.append("triggerQuantity: ").append(triggerQuantity);
+        } else {
+            sb.append("triggerQuantity: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (reportQuantity != null) {
+            sb.append("reportQuantity: ").append(reportQuantity);
+        } else {
+            sb.append("reportQuantity: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class ReportParams 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 Params params = null;
+        private Hysteresis hysteresis = null;
+        private TimeToTrigger timetotrigger = null;
+        public ReportParams() {
+        }
+
+        public ReportParams(byte[] code) {
+            this.code = code;
+        }
+
+        public Params getParams() {
+            return params;
+        }
+
+        public void setParams(Params params) {
+            this.params = params;
+        }
+
+        public Hysteresis getHysteresis() {
+            return hysteresis;
+        }
+
+        public void setHysteresis(Hysteresis hysteresis) {
+            this.hysteresis = hysteresis;
+        }
+
+        public TimeToTrigger getTimetotrigger() {
+            return timetotrigger;
+        }
+
+        public void setTimetotrigger(TimeToTrigger timetotrigger) {
+            this.timetotrigger = timetotrigger;
+        }
+
+        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 += timetotrigger.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+            os.write(0x82);
+            codeLength += 1;
+
+            codeLength += hysteresis.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+            os.write(0x81);
+            codeLength += 1;
+
+            sublength = params.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);
+                params = new Params();
+                subCodeLength += params.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)) {
+                hysteresis = new Hysteresis();
+                subCodeLength += hysteresis.decode(is, false);
+                subCodeLength += berTag.decode(is);
+            } else {
+                throw new IOException("Tag does not match the mandatory sequence element tag.");
+            }
+
+            if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+                timetotrigger = new TimeToTrigger();
+                subCodeLength += timetotrigger.decode(is, false);
+                if (subCodeLength == totalLength) {
+                    return codeLength;
+                }
+            }
+            throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{");
+            sb.append("\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (params != null) {
+                sb.append("params: ");
+                params.appendAsString(sb, indentLevel + 1);
+            } else {
+                sb.append("params: <empty-required-field>");
+            }
+
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (hysteresis != null) {
+                sb.append("hysteresis: ").append(hysteresis);
+            } else {
+                sb.append("hysteresis: <empty-required-field>");
+            }
+
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (timetotrigger != null) {
+                sb.append("timetotrigger: ").append(timetotrigger);
+            } else {
+                sb.append("timetotrigger: <empty-required-field>");
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+        public static class Params implements Serializable {
+
+            private static final long serialVersionUID = 1L;
+
+            @JsonIgnore
+            public byte[] code = null;
+            private PerParam perParam = null;
+            private A1Param a1param = null;
+            private A2Param a2param = null;
+            private A3Param a3param = null;
+            private A4Param a4param = null;
+            private A5Param a5param = null;
+            private A6Param a6param = null;
+
+            public Params() {
+            }
+
+            public Params(byte[] code) {
+                this.code = code;
+            }
+
+            public PerParam getPerParam() {
+                return perParam;
+            }
+
+            public void setPerParam(PerParam perParam) {
+                this.perParam = perParam;
+            }
+
+            public A1Param getA1param() {
+                return a1param;
+            }
+
+            public void setA1param(A1Param a1param) {
+                this.a1param = a1param;
+            }
+
+            public A2Param getA2param() {
+                return a2param;
+            }
+
+            public void setA2param(A2Param a2param) {
+                this.a2param = a2param;
+            }
+
+            public A3Param getA3param() {
+                return a3param;
+            }
+
+            public void setA3param(A3Param a3param) {
+                this.a3param = a3param;
+            }
+
+            public A4Param getA4param() {
+                return a4param;
+            }
+
+            public void setA4param(A4Param a4param) {
+                this.a4param = a4param;
+            }
+
+            public A5Param getA5param() {
+                return a5param;
+            }
+
+            public void setA5param(A5Param a5param) {
+                this.a5param = a5param;
+            }
+
+            public A6Param getA6param() {
+                return a6param;
+            }
+
+            public void setA6param(A6Param a6param) {
+                this.a6param = a6param;
+            }
+
+            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 (a6param != null) {
+                    codeLength += a6param.encode(os, false);
+                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+                    os.write(0xA6);
+                    codeLength += 1;
+                    return codeLength;
+                }
+
+                if (a5param != null) {
+                    codeLength += a5param.encode(os, false);
+                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+                    os.write(0xA5);
+                    codeLength += 1;
+                    return codeLength;
+                }
+
+                if (a4param != null) {
+                    codeLength += a4param.encode(os, false);
+                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+                    os.write(0xA4);
+                    codeLength += 1;
+                    return codeLength;
+                }
+
+                if (a3param != null) {
+                    codeLength += a3param.encode(os, false);
+                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+                    os.write(0xA3);
+                    codeLength += 1;
+                    return codeLength;
+                }
+
+                if (a2param != null) {
+                    codeLength += a2param.encode(os, false);
+                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+                    os.write(0xA2);
+                    codeLength += 1;
+                    return codeLength;
+                }
+
+                if (a1param != null) {
+                    codeLength += a1param.encode(os, false);
+                    // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+                    os.write(0xA1);
+                    codeLength += 1;
+                    return codeLength;
+                }
+
+                if (perParam != null) {
+                    codeLength += perParam.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)) {
+                    perParam = new PerParam();
+                    codeLength += perParam.decode(is, false);
+                    return codeLength;
+                }
+
+                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+                    a1param = new A1Param();
+                    codeLength += a1param.decode(is, false);
+                    return codeLength;
+                }
+
+                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+                    a2param = new A2Param();
+                    codeLength += a2param.decode(is, false);
+                    return codeLength;
+                }
+
+                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+                    a3param = new A3Param();
+                    codeLength += a3param.decode(is, false);
+                    return codeLength;
+                }
+
+                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+                    a4param = new A4Param();
+                    codeLength += a4param.decode(is, false);
+                    return codeLength;
+                }
+
+                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+                    a5param = new A5Param();
+                    codeLength += a5param.decode(is, false);
+                    return codeLength;
+                }
+
+                if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+                    a6param = new A6Param();
+                    codeLength += a6param.decode(is, false);
+                    return codeLength;
+                }
+
+                if (passedTag != null) {
+                    return 0;
+                }
+
+                throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
+            }
+
+            public void encodeAndSave(int encodingSizeGuess) throws IOException {
+                BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+                encode(os);
+                code = os.getArray();
+            }
+
+            public String toString() {
+                StringBuilder sb = new StringBuilder();
+                appendAsString(sb, 0);
+                return sb.toString();
+            }
+
+            public void appendAsString(StringBuilder sb, int indentLevel) {
+
+                if (perParam != null) {
+                    sb.append("perParam: ");
+                    perParam.appendAsString(sb, indentLevel + 1);
+                    return;
+                }
+
+                if (a1param != null) {
+                    sb.append("a1param: ");
+                    a1param.appendAsString(sb, indentLevel + 1);
+                    return;
+                }
+
+                if (a2param != null) {
+                    sb.append("a2param: ");
+                    a2param.appendAsString(sb, indentLevel + 1);
+                    return;
+                }
+
+                if (a3param != null) {
+                    sb.append("a3param: ");
+                    a3param.appendAsString(sb, indentLevel + 1);
+                    return;
+                }
+
+                if (a4param != null) {
+                    sb.append("a4param: ");
+                    a4param.appendAsString(sb, indentLevel + 1);
+                    return;
+                }
+
+                if (a5param != null) {
+                    sb.append("a5param: ");
+                    a5param.appendAsString(sb, indentLevel + 1);
+                    return;
+                }
+
+                if (a6param != null) {
+                    sb.append("a6param: ");
+                    a6param.appendAsString(sb, indentLevel + 1);
+                    return;
+                }
+
+                sb.append("<none>");
+            }
+
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/SchedMeasRepPerServCell.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/SchedMeasRepPerServCell.java
new file mode 100644
index 0000000..a367b9b
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/SchedMeasRepPerServCell.java
@@ -0,0 +1,1287 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class SchedMeasRepPerServCell 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 ECGI ecgi = null;
+    private QciVals qciVals = null;
+    private PRBUsage prbUsage = null;
+    private McsDl mcsDl = null;
+    private NumSchedTtisDl numSchedTtisDl = null;
+    private McsUl mcsUl = null;
+    private NumSchedTtisUl numSchedTtisUl = null;
+    private RankDl1 rankDl1 = null;
+    private RankDl2 rankDl2 = null;
+    public SchedMeasRepPerServCell() {
+    }
+    public SchedMeasRepPerServCell(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public QciVals getQciVals() {
+        return qciVals;
+    }
+
+    public void setQciVals(QciVals qciVals) {
+        this.qciVals = qciVals;
+    }
+
+    public PRBUsage getPrbUsage() {
+        return prbUsage;
+    }
+
+    public void setPrbUsage(PRBUsage prbUsage) {
+        this.prbUsage = prbUsage;
+    }
+
+    public McsDl getMcsDl() {
+        return mcsDl;
+    }
+
+    public void setMcsDl(McsDl mcsDl) {
+        this.mcsDl = mcsDl;
+    }
+
+    public NumSchedTtisDl getNumSchedTtisDl() {
+        return numSchedTtisDl;
+    }
+
+    public void setNumSchedTtisDl(NumSchedTtisDl numSchedTtisDl) {
+        this.numSchedTtisDl = numSchedTtisDl;
+    }
+
+    public McsUl getMcsUl() {
+        return mcsUl;
+    }
+
+    public void setMcsUl(McsUl mcsUl) {
+        this.mcsUl = mcsUl;
+    }
+
+    public NumSchedTtisUl getNumSchedTtisUl() {
+        return numSchedTtisUl;
+    }
+
+    public void setNumSchedTtisUl(NumSchedTtisUl numSchedTtisUl) {
+        this.numSchedTtisUl = numSchedTtisUl;
+    }
+
+    public RankDl1 getRankDl1() {
+        return rankDl1;
+    }
+
+    public void setRankDl1(RankDl1 rankDl1) {
+        this.rankDl1 = rankDl1;
+    }
+
+    public RankDl2 getRankDl2() {
+        return rankDl2;
+    }
+
+    public void setRankDl2(RankDl2 rankDl2) {
+        this.rankDl2 = rankDl2;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += rankDl2.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+        os.write(0xA8);
+        codeLength += 1;
+
+        codeLength += rankDl1.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+        os.write(0xA7);
+        codeLength += 1;
+
+        codeLength += numSchedTtisUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+        os.write(0xA6);
+        codeLength += 1;
+
+        codeLength += mcsUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+        os.write(0xA5);
+        codeLength += 1;
+
+        codeLength += numSchedTtisDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+        os.write(0xA4);
+        codeLength += 1;
+
+        codeLength += mcsDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += prbUsage.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += qciVals.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            qciVals = new QciVals();
+            subCodeLength += qciVals.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            prbUsage = new PRBUsage();
+            subCodeLength += prbUsage.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            mcsDl = new McsDl();
+            subCodeLength += mcsDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+            numSchedTtisDl = new NumSchedTtisDl();
+            subCodeLength += numSchedTtisDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+            mcsUl = new McsUl();
+            subCodeLength += mcsUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+            numSchedTtisUl = new NumSchedTtisUl();
+            subCodeLength += numSchedTtisUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+            rankDl1 = new RankDl1();
+            subCodeLength += rankDl1.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+            rankDl2 = new RankDl2();
+            subCodeLength += rankDl2.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (qciVals != null) {
+            sb.append("qciVals: ");
+            qciVals.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("qciVals: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (prbUsage != null) {
+            sb.append("prbUsage: ");
+            prbUsage.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("prbUsage: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (mcsDl != null) {
+            sb.append("mcsDl: ");
+            mcsDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("mcsDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (numSchedTtisDl != null) {
+            sb.append("numSchedTtisDl: ");
+            numSchedTtisDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("numSchedTtisDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (mcsUl != null) {
+            sb.append("mcsUl: ");
+            mcsUl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("mcsUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (numSchedTtisUl != null) {
+            sb.append("numSchedTtisUl: ");
+            numSchedTtisUl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("numSchedTtisUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (rankDl1 != null) {
+            sb.append("rankDl1: ");
+            rankDl1.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("rankDl1: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (rankDl2 != null) {
+            sb.append("rankDl2: ");
+            rankDl2.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("rankDl2: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class QciVals 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 List<QCI> seqOf = null;
+
+        public QciVals() {
+            seqOf = new ArrayList<QCI>();
+        }
+
+        public QciVals(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<QCI> getQCI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<QCI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                QCI element = new QCI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<QCI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class McsDl 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 List<BerInteger> seqOf = null;
+
+        public McsDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public McsDl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class NumSchedTtisDl 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 List<BerInteger> seqOf = null;
+
+        public NumSchedTtisDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public NumSchedTtisDl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class McsUl 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 List<BerInteger> seqOf = null;
+
+        public McsUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public McsUl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class NumSchedTtisUl 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 List<BerInteger> seqOf = null;
+
+        public NumSchedTtisUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public NumSchedTtisUl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class RankDl1 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 List<BerInteger> seqOf = null;
+
+        public RankDl1() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public RankDl1(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class RankDl2 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 List<BerInteger> seqOf = null;
+
+        public RankDl2() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public RankDl2(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ThresholdEUTRA.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ThresholdEUTRA.java
new file mode 100644
index 0000000..18f8f0c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/ThresholdEUTRA.java
@@ -0,0 +1,138 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class ThresholdEUTRA implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @JsonIgnore
+    public byte[] code = null;
+    private RSRPRange thresholdRSRP = null;
+    private RSRQRange thresholdRSRQ = null;
+
+    public ThresholdEUTRA() {
+    }
+
+    public ThresholdEUTRA(byte[] code) {
+        this.code = code;
+    }
+
+    public RSRPRange getThresholdRSRP() {
+        return thresholdRSRP;
+    }
+
+    public void setThresholdRSRP(RSRPRange thresholdRSRP) {
+        this.thresholdRSRP = thresholdRSRP;
+    }
+
+    public RSRQRange getThresholdRSRQ() {
+        return thresholdRSRQ;
+    }
+
+    public void setThresholdRSRQ(RSRQRange thresholdRSRQ) {
+        this.thresholdRSRQ = thresholdRSRQ;
+    }
+
+    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 (thresholdRSRQ != null) {
+            codeLength += thresholdRSRQ.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+            os.write(0x81);
+            codeLength += 1;
+            return codeLength;
+        }
+
+        if (thresholdRSRP != null) {
+            codeLength += thresholdRSRP.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+            os.write(0x80);
+            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.PRIMITIVE, 0)) {
+            thresholdRSRP = new RSRPRange();
+            codeLength += thresholdRSRP.decode(is, false);
+            return codeLength;
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            thresholdRSRQ = new RSRQRange();
+            codeLength += thresholdRSRQ.decode(is, false);
+            return codeLength;
+        }
+
+        if (passedTag != null) {
+            return 0;
+        }
+
+        throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        if (thresholdRSRP != null) {
+            sb.append("thresholdRSRP: ").append(thresholdRSRP);
+            return;
+        }
+
+        if (thresholdRSRQ != null) {
+            sb.append("thresholdRSRQ: ").append(thresholdRSRQ);
+            return;
+        }
+
+        sb.append("<none>");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/TimeToTrigger.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/TimeToTrigger.java
new file mode 100644
index 0000000..fe042ec
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/TimeToTrigger.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class TimeToTrigger extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public TimeToTrigger() {
+    }
+
+    public TimeToTrigger(byte[] code) {
+        super(code);
+    }
+
+    public TimeToTrigger(BigInteger value) {
+        super(value);
+    }
+
+    public TimeToTrigger(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/TrafficSplitPercentage.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/TrafficSplitPercentage.java
new file mode 100644
index 0000000..e0599c0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/TrafficSplitPercentage.java
@@ -0,0 +1,207 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class TrafficSplitPercentage 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 ECGI ecgi = null;
+    private BerInteger trafficPercentDl = null;
+    private BerInteger trafficPercentUl = null;
+
+    public TrafficSplitPercentage() {
+    }
+
+    public TrafficSplitPercentage(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public BerInteger getTrafficPercentDl() {
+        return trafficPercentDl;
+    }
+
+    public void setTrafficPercentDl(BerInteger trafficPercentDl) {
+        this.trafficPercentDl = trafficPercentDl;
+    }
+
+    public BerInteger getTrafficPercentUl() {
+        return trafficPercentUl;
+    }
+
+    public void setTrafficPercentUl(BerInteger trafficPercentUl) {
+        this.trafficPercentUl = trafficPercentUl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        if (trafficPercentUl != null) {
+            codeLength += trafficPercentUl.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+            os.write(0x82);
+            codeLength += 1;
+        }
+
+        if (trafficPercentDl != null) {
+            codeLength += trafficPercentDl.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+            os.write(0x81);
+            codeLength += 1;
+        }
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            trafficPercentDl = new BerInteger();
+            subCodeLength += trafficPercentDl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            trafficPercentUl = new BerInteger();
+            subCodeLength += trafficPercentUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        if (trafficPercentDl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("trafficPercentDl: ").append(trafficPercentDl);
+        }
+
+        if (trafficPercentUl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("trafficPercentUl: ").append(trafficPercentUl);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/UEAMBR.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/UEAMBR.java
new file mode 100644
index 0000000..3590d09
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/UEAMBR.java
@@ -0,0 +1,169 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class UEAMBR 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 BitRate ambrDl = null;
+    private BitRate ambrUl = null;
+
+    public UEAMBR() {
+    }
+
+    public UEAMBR(byte[] code) {
+        this.code = code;
+    }
+
+    public BitRate getAmbrDl() {
+        return ambrDl;
+    }
+
+    public void setAmbrDl(BitRate ambrDl) {
+        this.ambrDl = ambrDl;
+    }
+
+    public BitRate getAmbrUl() {
+        return ambrUl;
+    }
+
+    public void setAmbrUl(BitRate ambrUl) {
+        this.ambrUl = ambrUl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += ambrUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += ambrDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            ambrDl = new BitRate();
+            subCodeLength += ambrDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            ambrUl = new BitRate();
+            subCodeLength += ambrUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ambrDl != null) {
+            sb.append("ambrDl: ").append(ambrDl);
+        } else {
+            sb.append("ambrDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ambrUl != null) {
+            sb.append("ambrUl: ").append(ambrUl);
+        } else {
+            sb.append("ambrUl: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/XICICPA.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/XICICPA.java
new file mode 100644
index 0000000..431a1c9
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/api/XICICPA.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.api;
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+
+public class XICICPA extends BerEnum {
+
+    private static final long serialVersionUID = 1L;
+
+    public XICICPA() {
+    }
+
+    public XICICPA(byte[] code) {
+        super(code);
+    }
+
+    public XICICPA(BigInteger value) {
+        super(value);
+    }
+
+    public XICICPA(long value) {
+        super(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/BerByteArrayOutputStream.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/BerByteArrayOutputStream.java
new file mode 100644
index 0000000..a77e51d
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/BerLength.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/BerLength.java
new file mode 100644
index 0000000..5bb87b9
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/BerTag.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/BerTag.java
new file mode 100644
index 0000000..4e9bc12
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/internal/Util.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/internal/Util.java
new file mode 100644
index 0000000..b85b6ac
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerAny.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerAny.java
new file mode 100644
index 0000000..6445862
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerAny.java
@@ -0,0 +1,74 @@
+/* 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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.internal.Util;
+
+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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerBitString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerBitString.java
new file mode 100644
index 0000000..65b1e48
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerBitString.java
@@ -0,0 +1,130 @@
+/* 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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.internal.Util;
+
+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;
+    @JsonIgnore 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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerBoolean.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerBoolean.java
new file mode 100644
index 0000000..34a26af
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerDate.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerDate.java
new file mode 100644
index 0000000..e0548cb
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerDateTime.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerDateTime.java
new file mode 100644
index 0000000..cab9d98
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerDuration.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerDuration.java
new file mode 100644
index 0000000..1362547
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerEmbeddedPdv.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerEmbeddedPdv.java
new file mode 100644
index 0000000..6156edc
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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();
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerEnum.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerEnum.java
new file mode 100644
index 0000000..8c5acaa
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerGeneralizedTime.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerGeneralizedTime.java
new file mode 100644
index 0000000..b4df6fc
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerInteger.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerInteger.java
new file mode 100644
index 0000000..0c80fbb
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerNull.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerNull.java
new file mode 100644
index 0000000..b342632
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @Override
+    public String toString() {
+        return "ASN1_NULL";
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerObjectIdentifier.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerObjectIdentifier.java
new file mode 100644
index 0000000..b4f3e29
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerOctetString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerOctetString.java
new file mode 100644
index 0000000..16a085a
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerOctetString.java
@@ -0,0 +1,80 @@
+/* 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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.internal.Util;
+
+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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerReal.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerReal.java
new file mode 100644
index 0000000..2581e78
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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();
+    }
+
+    
+    @Override
+    public String toString() {
+        return "" + value;
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerTime.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerTime.java
new file mode 100644
index 0000000..6dad2af
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerTimeOfDay.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerTimeOfDay.java
new file mode 100644
index 0000000..2507525
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerUtcTime.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/BerUtcTime.java
new file mode 100644
index 0000000..e292aa5
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerBMPString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerBMPString.java
new file mode 100644
index 0000000..682fafa
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerGeneralString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerGeneralString.java
new file mode 100644
index 0000000..0608d43
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerGraphicString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerGraphicString.java
new file mode 100644
index 0000000..1efedb6
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerIA5String.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerIA5String.java
new file mode 100644
index 0000000..e38f3df
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerNumericString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerNumericString.java
new file mode 100644
index 0000000..141f3ed
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerObjectDescriptor.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerObjectDescriptor.java
new file mode 100644
index 0000000..bcf4829
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerPrintableString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerPrintableString.java
new file mode 100644
index 0000000..e6313bf
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerTeletexString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerTeletexString.java
new file mode 100644
index 0000000..ca56059
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerUTF8String.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerUTF8String.java
new file mode 100644
index 0000000..b27b82c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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");
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerUniversalString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerUniversalString.java
new file mode 100644
index 0000000..41e0a89
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerVideotexString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerVideotexString.java
new file mode 100644
index 0000000..5d88179
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+    }
+
+    
+    @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/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerVisibleString.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/ber/types/string/BerVisibleString.java
new file mode 100644
index 0000000..14a8665
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/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.asn1lib.ber.types.string;
+
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.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;
+
+    }
+
+    
+    @Override
+    public String toString() {
+        return new String(value);
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/package-info.java
new file mode 100644
index 0000000..17384cd
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/package-info.java
@@ -0,0 +1 @@
+package org.onosproject.xran.asn1lib;
\ No newline at end of file
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionRequest.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionRequest.java
new file mode 100644
index 0000000..3f31a27
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionRequest.java
@@ -0,0 +1,272 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.ERABParams;
+import org.onosproject.xran.asn1lib.api.UEAMBR;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BearerAdmissionRequest 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private UEAMBR ueAmbr = null;
+    private BerInteger numErabs = null;
+    private ERABParams erabParams = null;
+
+    public BearerAdmissionRequest() {
+    }
+
+    public BearerAdmissionRequest(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public UEAMBR getUeAmbr() {
+        return ueAmbr;
+    }
+
+    public void setUeAmbr(UEAMBR ueAmbr) {
+        this.ueAmbr = ueAmbr;
+    }
+
+    public BerInteger getNumErabs() {
+        return numErabs;
+    }
+
+    public void setNumErabs(BerInteger numErabs) {
+        this.numErabs = numErabs;
+    }
+
+    public ERABParams getErabParams() {
+        return erabParams;
+    }
+
+    public void setErabParams(ERABParams erabParams) {
+        this.erabParams = erabParams;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += erabParams.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+        os.write(0xA4);
+        codeLength += 1;
+
+        codeLength += numErabs.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += ueAmbr.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            ueAmbr = new UEAMBR();
+            subCodeLength += ueAmbr.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            numErabs = new BerInteger();
+            subCodeLength += numErabs.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+            erabParams = new ERABParams();
+            subCodeLength += erabParams.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ueAmbr != null) {
+            sb.append("ueAmbr: ");
+            ueAmbr.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ueAmbr: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (numErabs != null) {
+            sb.append("numErabs: ").append(numErabs);
+        } else {
+            sb.append("numErabs: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (erabParams != null) {
+            sb.append("erabParams: ");
+            erabParams.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("erabParams: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionResponse.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionResponse.java
new file mode 100644
index 0000000..333aca1
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionResponse.java
@@ -0,0 +1,281 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.*;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+
+public class BearerAdmissionResponse 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private BerInteger numErabList = null;
+    private ERABResponse erabResponse = null;
+
+    public BearerAdmissionResponse() {
+    }
+
+    public BearerAdmissionResponse(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(ECGI ecgi, CRNTI crnti, ERABParams erabParams, BerInteger numParams, boolean b) {
+        ERABResponse erabResponse = new ERABResponse();
+
+        for (int i = 0; i < numParams.intValue(); i++) {
+            ERABParamsItem erabParamsItem = erabParams.getERABParamsItem().get(i);
+
+            ERABResponseItem responseItem = new ERABResponseItem();
+            responseItem.setId(erabParamsItem.getId());
+
+            // FIXME: add logic
+            responseItem.setDecision(new ERABDecision(b ? 0 : 1));
+
+            erabResponse.getERABResponseItem().add(responseItem);
+        }
+
+
+        BearerAdmissionResponse bearerAdmissionResponse = new BearerAdmissionResponse();
+        bearerAdmissionResponse.setCrnti(crnti);
+        bearerAdmissionResponse.setEcgi(ecgi);
+        bearerAdmissionResponse.setErabResponse(erabResponse);
+        bearerAdmissionResponse.setNumErabList(numParams);
+
+        XrancPduBody body = new XrancPduBody();
+        body.setBearerAdmissionResponse(bearerAdmissionResponse);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        XrancApiID apiID = new XrancApiID(9);
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setHdr(hdr);
+        pdu.setBody(body);
+
+        return pdu;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public BerInteger getNumErabList() {
+        return numErabList;
+    }
+
+    public void setNumErabList(BerInteger numErabList) {
+        this.numErabList = numErabList;
+    }
+
+    public ERABResponse getErabResponse() {
+        return erabResponse;
+    }
+
+    public void setErabResponse(ERABResponse erabResponse) {
+        this.erabResponse = erabResponse;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += erabResponse.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += numErabList.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            numErabList = new BerInteger();
+            subCodeLength += numErabList.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            erabResponse = new ERABResponse();
+            subCodeLength += erabResponse.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (numErabList != null) {
+            sb.append("numErabList: ").append(numErabList);
+        } else {
+            sb.append("numErabList: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (erabResponse != null) {
+            sb.append("erabResponse: ");
+            erabResponse.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("erabResponse: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionStatus.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionStatus.java
new file mode 100644
index 0000000..aa5fdea
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerAdmissionStatus.java
@@ -0,0 +1,238 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.ERABResponse;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class BearerAdmissionStatus 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private BerInteger numErabs = null;
+    private ERABResponse erabStatus = null;
+
+    public BearerAdmissionStatus() {
+    }
+
+    public BearerAdmissionStatus(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public BerInteger getNumErabs() {
+        return numErabs;
+    }
+
+    public void setNumErabs(BerInteger numErabs) {
+        this.numErabs = numErabs;
+    }
+
+    public ERABResponse getErabStatus() {
+        return erabStatus;
+    }
+
+    public void setErabStatus(ERABResponse erabStatus) {
+        this.erabStatus = erabStatus;
+    }
+
+    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 += erabStatus.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += numErabs.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            numErabs = new BerInteger();
+            subCodeLength += numErabs.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            erabStatus = new ERABResponse();
+            subCodeLength += erabStatus.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (numErabs != null) {
+            sb.append("numErabs: ").append(numErabs);
+        } else {
+            sb.append("numErabs: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (erabStatus != null) {
+            sb.append("erabStatus: ");
+            erabStatus.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("erabStatus: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerReleaseInd.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerReleaseInd.java
new file mode 100644
index 0000000..7b4e15c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/BearerReleaseInd.java
@@ -0,0 +1,369 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.ERABID;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class BearerReleaseInd 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private BerInteger numErabs = null;
+    private ErabIds erabIds = null;
+    public BearerReleaseInd() {
+    }
+
+    public BearerReleaseInd(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public BerInteger getNumErabs() {
+        return numErabs;
+    }
+
+    public void setNumErabs(BerInteger numErabs) {
+        this.numErabs = numErabs;
+    }
+
+    public ErabIds getErabIds() {
+        return erabIds;
+    }
+
+    public void setErabIds(ErabIds erabIds) {
+        this.erabIds = erabIds;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += erabIds.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += numErabs.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            numErabs = new BerInteger();
+            subCodeLength += numErabs.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            erabIds = new ErabIds();
+            subCodeLength += erabIds.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (numErabs != null) {
+            sb.append("numErabs: ").append(numErabs);
+        } else {
+            sb.append("numErabs: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (erabIds != null) {
+            sb.append("erabIds: ");
+            erabIds.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("erabIds: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class ErabIds 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 List<ERABID> seqOf = null;
+
+        public ErabIds() {
+            seqOf = new ArrayList<ERABID>();
+        }
+
+        public ErabIds(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<ERABID> getERABID() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<ERABID>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                ERABID element = new ERABID();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<ERABID> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/CellConfigReport.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/CellConfigReport.java
new file mode 100644
index 0000000..896461a
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/CellConfigReport.java
@@ -0,0 +1,783 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.*;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerBitString;
+import org.onosproject.xran.asn1lib.ber.types.BerBoolean;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class CellConfigReport 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 ECGI ecgi = null;
+    private PhysCellId pci = null;
+    private CandScells candScells = null;
+    private ARFCNValue earfcnDl = null;
+    private ARFCNValue earfcnUl = null;
+    private BerInteger rbsPerTtiDl = null;
+    private BerInteger rbsPerTtiUl = null;
+    private BerInteger numTxAntenna = null;
+    private DuplexMode duplexMode = null;
+    private BerInteger tddConfig = null;
+    private BerInteger tddSplSfConfig = null;
+    private BerInteger maxNumConnectedUes = null;
+    private BerInteger maxNumConnectedBearers = null;
+    private BerInteger maxNumUesSchedPerTtiDl = null;
+    private BerInteger maxNumUesSchedPerTtiUl = null;
+    private BerBoolean dlfsSchedEnable = null;
+    private BerBitString featureSupportList = null;
+    public CellConfigReport() {
+    }
+
+    public CellConfigReport(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public PhysCellId getPci() {
+        return pci;
+    }
+
+    public void setPci(PhysCellId pci) {
+        this.pci = pci;
+    }
+
+    public CandScells getCandScells() {
+        return candScells;
+    }
+
+    public void setCandScells(CandScells candScells) {
+        this.candScells = candScells;
+    }
+
+    public ARFCNValue getEarfcnDl() {
+        return earfcnDl;
+    }
+
+    public void setEarfcnDl(ARFCNValue earfcnDl) {
+        this.earfcnDl = earfcnDl;
+    }
+
+    public ARFCNValue getEarfcnUl() {
+        return earfcnUl;
+    }
+
+    public void setEarfcnUl(ARFCNValue earfcnUl) {
+        this.earfcnUl = earfcnUl;
+    }
+
+    public BerInteger getRbsPerTtiDl() {
+        return rbsPerTtiDl;
+    }
+
+    public void setRbsPerTtiDl(BerInteger rbsPerTtiDl) {
+        this.rbsPerTtiDl = rbsPerTtiDl;
+    }
+
+    public BerInteger getRbsPerTtiUl() {
+        return rbsPerTtiUl;
+    }
+
+    public void setRbsPerTtiUl(BerInteger rbsPerTtiUl) {
+        this.rbsPerTtiUl = rbsPerTtiUl;
+    }
+
+    public BerInteger getNumTxAntenna() {
+        return numTxAntenna;
+    }
+
+    public void setNumTxAntenna(BerInteger numTxAntenna) {
+        this.numTxAntenna = numTxAntenna;
+    }
+
+    public DuplexMode getDuplexMode() {
+        return duplexMode;
+    }
+
+    public void setDuplexMode(DuplexMode duplexMode) {
+        this.duplexMode = duplexMode;
+    }
+
+    public BerInteger getTddConfig() {
+        return tddConfig;
+    }
+
+    public void setTddConfig(BerInteger tddConfig) {
+        this.tddConfig = tddConfig;
+    }
+
+    public BerInteger getTddSplSfConfig() {
+        return tddSplSfConfig;
+    }
+
+    public void setTddSplSfConfig(BerInteger tddSplSfConfig) {
+        this.tddSplSfConfig = tddSplSfConfig;
+    }
+
+    public BerInteger getMaxNumConnectedUes() {
+        return maxNumConnectedUes;
+    }
+
+    public void setMaxNumConnectedUes(BerInteger maxNumConnectedUes) {
+        this.maxNumConnectedUes = maxNumConnectedUes;
+    }
+
+    public BerInteger getMaxNumConnectedBearers() {
+        return maxNumConnectedBearers;
+    }
+
+    public void setMaxNumConnectedBearers(BerInteger maxNumConnectedBearers) {
+        this.maxNumConnectedBearers = maxNumConnectedBearers;
+    }
+
+    public BerInteger getMaxNumUesSchedPerTtiDl() {
+        return maxNumUesSchedPerTtiDl;
+    }
+
+    public void setMaxNumUesSchedPerTtiDl(BerInteger maxNumUesSchedPerTtiDl) {
+        this.maxNumUesSchedPerTtiDl = maxNumUesSchedPerTtiDl;
+    }
+
+    public BerInteger getMaxNumUesSchedPerTtiUl() {
+        return maxNumUesSchedPerTtiUl;
+    }
+
+    public void setMaxNumUesSchedPerTtiUl(BerInteger maxNumUesSchedPerTtiUl) {
+        this.maxNumUesSchedPerTtiUl = maxNumUesSchedPerTtiUl;
+    }
+
+    public BerBoolean getDlfsSchedEnable() {
+        return dlfsSchedEnable;
+    }
+
+    public void setDlfsSchedEnable(BerBoolean dlfsSchedEnable) {
+        this.dlfsSchedEnable = dlfsSchedEnable;
+    }
+
+    public BerBitString getFeatureSupportList() {
+        return featureSupportList;
+    }
+
+    public void setFeatureSupportList(BerBitString featureSupportList) {
+        this.featureSupportList = featureSupportList;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        if (featureSupportList != null) {
+            codeLength += featureSupportList.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 16
+            os.write(0x90);
+            codeLength += 1;
+        }
+
+        codeLength += dlfsSchedEnable.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 15
+        os.write(0x8F);
+        codeLength += 1;
+
+        codeLength += maxNumUesSchedPerTtiUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 14
+        os.write(0x8E);
+        codeLength += 1;
+
+        codeLength += maxNumUesSchedPerTtiDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 13
+        os.write(0x8D);
+        codeLength += 1;
+
+        codeLength += maxNumConnectedBearers.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 12
+        os.write(0x8C);
+        codeLength += 1;
+
+        codeLength += maxNumConnectedUes.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 11
+        os.write(0x8B);
+        codeLength += 1;
+
+        if (tddSplSfConfig != null) {
+            codeLength += tddSplSfConfig.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 10
+            os.write(0x8A);
+            codeLength += 1;
+        }
+
+        if (tddConfig != null) {
+            codeLength += tddConfig.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 9
+            os.write(0x89);
+            codeLength += 1;
+        }
+
+        codeLength += duplexMode.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 8
+        os.write(0x88);
+        codeLength += 1;
+
+        codeLength += numTxAntenna.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 7
+        os.write(0x87);
+        codeLength += 1;
+
+        codeLength += rbsPerTtiUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 6
+        os.write(0x86);
+        codeLength += 1;
+
+        codeLength += rbsPerTtiDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 5
+        os.write(0x85);
+        codeLength += 1;
+
+        codeLength += earfcnUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 4
+        os.write(0x84);
+        codeLength += 1;
+
+        codeLength += earfcnDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += candScells.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += pci.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            pci = new PhysCellId();
+            subCodeLength += pci.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            candScells = new CandScells();
+            subCodeLength += candScells.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            earfcnDl = new ARFCNValue();
+            subCodeLength += earfcnDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+            earfcnUl = new ARFCNValue();
+            subCodeLength += earfcnUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 5)) {
+            rbsPerTtiDl = new BerInteger();
+            subCodeLength += rbsPerTtiDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 6)) {
+            rbsPerTtiUl = new BerInteger();
+            subCodeLength += rbsPerTtiUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 7)) {
+            numTxAntenna = new BerInteger();
+            subCodeLength += numTxAntenna.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 8)) {
+            duplexMode = new DuplexMode();
+            subCodeLength += duplexMode.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 9)) {
+            tddConfig = new BerInteger();
+            subCodeLength += tddConfig.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 10)) {
+            tddSplSfConfig = new BerInteger();
+            subCodeLength += tddSplSfConfig.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 11)) {
+            maxNumConnectedUes = new BerInteger();
+            subCodeLength += maxNumConnectedUes.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 12)) {
+            maxNumConnectedBearers = new BerInteger();
+            subCodeLength += maxNumConnectedBearers.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 13)) {
+            maxNumUesSchedPerTtiDl = new BerInteger();
+            subCodeLength += maxNumUesSchedPerTtiDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 14)) {
+            maxNumUesSchedPerTtiUl = new BerInteger();
+            subCodeLength += maxNumUesSchedPerTtiUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 15)) {
+            dlfsSchedEnable = new BerBoolean();
+            subCodeLength += dlfsSchedEnable.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            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, 16)) {
+            featureSupportList = new BerBitString();
+            subCodeLength += featureSupportList.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pci != null) {
+            sb.append("pci: ").append(pci);
+        } else {
+            sb.append("pci: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (candScells != null) {
+            sb.append("candScells: ");
+            candScells.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("candScells: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (earfcnDl != null) {
+            sb.append("earfcnDl: ").append(earfcnDl);
+        } else {
+            sb.append("earfcnDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (earfcnUl != null) {
+            sb.append("earfcnUl: ").append(earfcnUl);
+        } else {
+            sb.append("earfcnUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (rbsPerTtiDl != null) {
+            sb.append("rbsPerTtiDl: ").append(rbsPerTtiDl);
+        } else {
+            sb.append("rbsPerTtiDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (rbsPerTtiUl != null) {
+            sb.append("rbsPerTtiUl: ").append(rbsPerTtiUl);
+        } else {
+            sb.append("rbsPerTtiUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (numTxAntenna != null) {
+            sb.append("numTxAntenna: ").append(numTxAntenna);
+        } else {
+            sb.append("numTxAntenna: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (duplexMode != null) {
+            sb.append("duplexMode: ").append(duplexMode);
+        } else {
+            sb.append("duplexMode: <empty-required-field>");
+        }
+
+        if (tddConfig != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("tddConfig: ").append(tddConfig);
+        }
+
+        if (tddSplSfConfig != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("tddSplSfConfig: ").append(tddSplSfConfig);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (maxNumConnectedUes != null) {
+            sb.append("maxNumConnectedUes: ").append(maxNumConnectedUes);
+        } else {
+            sb.append("maxNumConnectedUes: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (maxNumConnectedBearers != null) {
+            sb.append("maxNumConnectedBearers: ").append(maxNumConnectedBearers);
+        } else {
+            sb.append("maxNumConnectedBearers: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (maxNumUesSchedPerTtiDl != null) {
+            sb.append("maxNumUesSchedPerTtiDl: ").append(maxNumUesSchedPerTtiDl);
+        } else {
+            sb.append("maxNumUesSchedPerTtiDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (maxNumUesSchedPerTtiUl != null) {
+            sb.append("maxNumUesSchedPerTtiUl: ").append(maxNumUesSchedPerTtiUl);
+        } else {
+            sb.append("maxNumUesSchedPerTtiUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (dlfsSchedEnable != null) {
+            sb.append("dlfsSchedEnable: ").append(dlfsSchedEnable);
+        } else {
+            sb.append("dlfsSchedEnable: <empty-required-field>");
+        }
+
+        if (featureSupportList != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("featureSupportList: ").append(featureSupportList);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class CandScells 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 List<CandScell> seqOf = null;
+
+        public CandScells() {
+            seqOf = new ArrayList<CandScell>();
+        }
+
+        public CandScells(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<CandScell> getCandScell() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<CandScell>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                CandScell element = new CandScell();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<CandScell> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/CellConfigRequest.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/CellConfigRequest.java
new file mode 100644
index 0000000..7de2dd1
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/CellConfigRequest.java
@@ -0,0 +1,163 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class CellConfigRequest 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 ECGI ecgi = null;
+
+    public CellConfigRequest() {
+    }
+
+    public CellConfigRequest(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(ECGI ecgi) {
+        CellConfigRequest cellConfigRequest = new CellConfigRequest();
+        cellConfigRequest.setEcgi(ecgi);
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (Exception ignored) {
+        }
+
+        XrancApiID apiID = new XrancApiID(0);
+        XrancPduBody body = new XrancPduBody();
+        body.setCellConfigRequest(cellConfigRequest);
+
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setBody(body);
+        pdu.setHdr(hdr);
+
+        return pdu;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOCause.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOCause.java
new file mode 100644
index 0000000..140b234
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOCause.java
@@ -0,0 +1,402 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.RXSigReport;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerBitString;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class HOCause 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 CRNTI crnti = null;
+    private ECGI ecgiS = null;
+    private ECGI ecgiT = null;
+    private BerBitString hoCause = null;
+    private HoTrigger hoTrigger = null;
+    public HOCause() {
+    }
+
+    public HOCause(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgiS() {
+        return ecgiS;
+    }
+
+    public void setEcgiS(ECGI ecgiS) {
+        this.ecgiS = ecgiS;
+    }
+
+    public ECGI getEcgiT() {
+        return ecgiT;
+    }
+
+    public void setEcgiT(ECGI ecgiT) {
+        this.ecgiT = ecgiT;
+    }
+
+    public BerBitString getHoCause() {
+        return hoCause;
+    }
+
+    public void setHoCause(BerBitString hoCause) {
+        this.hoCause = hoCause;
+    }
+
+    public HoTrigger getHoTrigger() {
+        return hoTrigger;
+    }
+
+    public void setHoTrigger(HoTrigger hoTrigger) {
+        this.hoTrigger = hoTrigger;
+    }
+
+    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 += hoTrigger.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+        os.write(0xA4);
+        codeLength += 1;
+
+        codeLength += hoCause.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += ecgiT.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgiS.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgiS = new ECGI();
+            subCodeLength += ecgiS.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            ecgiT = new ECGI();
+            subCodeLength += ecgiT.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            hoCause = new BerBitString();
+            subCodeLength += hoCause.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+            hoTrigger = new HoTrigger();
+            subCodeLength += hoTrigger.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgiS != null) {
+            sb.append("ecgiS: ");
+            ecgiS.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgiS: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgiT != null) {
+            sb.append("ecgiT: ");
+            ecgiT.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgiT: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (hoCause != null) {
+            sb.append("hoCause: ").append(hoCause);
+        } else {
+            sb.append("hoCause: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (hoTrigger != null) {
+            sb.append("hoTrigger: ");
+            hoTrigger.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("hoTrigger: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class HoTrigger 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 List<RXSigReport> seqOf = null;
+
+        public HoTrigger() {
+            seqOf = new ArrayList<RXSigReport>();
+        }
+
+        public HoTrigger(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<RXSigReport> getRXSigReport() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<RXSigReport>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                RXSigReport element = new RXSigReport();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<RXSigReport> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOComplete.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOComplete.java
new file mode 100644
index 0000000..8094bab
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOComplete.java
@@ -0,0 +1,205 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class HOComplete 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 ECGI ecgiT = null;
+    private ECGI ecgiS = null;
+    private CRNTI crntiNew = null;
+
+    public HOComplete() {
+    }
+
+    public HOComplete(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgiT() {
+        return ecgiT;
+    }
+
+    public void setEcgiT(ECGI ecgiT) {
+        this.ecgiT = ecgiT;
+    }
+
+    public ECGI getEcgiS() {
+        return ecgiS;
+    }
+
+    public void setEcgiS(ECGI ecgiS) {
+        this.ecgiS = ecgiS;
+    }
+
+    public CRNTI getCrntiNew() {
+        return crntiNew;
+    }
+
+    public void setCrntiNew(CRNTI crntiNew) {
+        this.crntiNew = crntiNew;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += crntiNew.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgiS.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += ecgiT.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgiT = new ECGI();
+            subCodeLength += ecgiT.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgiS = new ECGI();
+            subCodeLength += ecgiS.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            crntiNew = new CRNTI();
+            subCodeLength += crntiNew.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgiT != null) {
+            sb.append("ecgiT: ");
+            ecgiT.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgiT: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgiS != null) {
+            sb.append("ecgiS: ");
+            ecgiS.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgiS: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crntiNew != null) {
+            sb.append("crntiNew: ").append(crntiNew);
+        } else {
+            sb.append("crntiNew: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOFailure.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOFailure.java
new file mode 100644
index 0000000..9b96818
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HOFailure.java
@@ -0,0 +1,205 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.HOFailureCause;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class HOFailure 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private HOFailureCause cause = null;
+
+    public HOFailure() {
+    }
+
+    public HOFailure(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public HOFailureCause getCause() {
+        return cause;
+    }
+
+    public void setCause(HOFailureCause cause) {
+        this.cause = cause;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += cause.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            cause = new HOFailureCause();
+            subCodeLength += cause.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (cause != null) {
+            sb.append("cause: ").append(cause);
+        } else {
+            sb.append("cause: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HORequest.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HORequest.java
new file mode 100644
index 0000000..2618f0b
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/HORequest.java
@@ -0,0 +1,234 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class HORequest 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 CRNTI crnti = null;
+    private ECGI ecgiS = null;
+    private ECGI ecgiT = null;
+
+    public HORequest() {
+    }
+
+    public HORequest(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(CRNTI crnti, ECGI ecgis, ECGI ecgit) {
+        HORequest hoRequest = new HORequest();
+
+        hoRequest.setCrnti(crnti);
+        hoRequest.setEcgiS(ecgis);
+        hoRequest.setEcgiT(ecgit);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (Exception ignored) {
+        }
+
+        XrancApiID apiID = new XrancApiID(12);
+        XrancPduBody body = new XrancPduBody();
+        body.setHORequest(hoRequest);
+
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setBody(body);
+        pdu.setHdr(hdr);
+
+        return pdu;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgiS() {
+        return ecgiS;
+    }
+
+    public void setEcgiS(ECGI ecgiS) {
+        this.ecgiS = ecgiS;
+    }
+
+    public ECGI getEcgiT() {
+        return ecgiT;
+    }
+
+    public void setEcgiT(ECGI ecgiT) {
+        this.ecgiT = ecgiT;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += ecgiT.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgiS.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgiS = new ECGI();
+            subCodeLength += ecgiS.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            ecgiT = new ECGI();
+            subCodeLength += ecgiT.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgiS != null) {
+            sb.append("ecgiS: ");
+            ecgiS.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgiS: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgiT != null) {
+            sb.append("ecgiT: ");
+            ecgiT.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgiT: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/L2MeasConfig.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/L2MeasConfig.java
new file mode 100644
index 0000000..16f00d0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/L2MeasConfig.java
@@ -0,0 +1,376 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.L2MeasReportInterval;
+import org.onosproject.xran.asn1lib.api.L2ReportInterval;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class L2MeasConfig 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 ECGI ecgi = null;
+    private Crnti crnti = null;
+    private L2ReportInterval reportIntervals = null;
+
+    public L2MeasConfig() {
+    }
+
+    public L2MeasConfig(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(ECGI ecgi, int l2MeasInterval) {
+        L2MeasConfig measConfig = new L2MeasConfig();
+        measConfig.setEcgi(ecgi);
+
+        L2ReportInterval l2ReportInterval = new L2ReportInterval();
+        L2MeasReportInterval l2MeasReportInterval = new L2MeasReportInterval(l2MeasInterval);
+        l2ReportInterval.setTPdcpMeasReportPerUe(l2MeasReportInterval);
+        l2ReportInterval.setTRadioMeasReportPerCell(l2MeasReportInterval);
+        l2ReportInterval.setTRadioMeasReportPerUe(l2MeasReportInterval);
+        l2ReportInterval.setTRadioSchedReportPerUe(l2MeasReportInterval);
+        l2ReportInterval.setTRadioSchedReportPerCell(l2MeasReportInterval);
+
+        measConfig.setReportIntervals(l2ReportInterval);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        XrancApiID apiID = new XrancApiID(16);
+        XrancPduBody body = new XrancPduBody();
+        body.setL2MeasConfig(measConfig);
+
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setBody(body);
+        pdu.setHdr(hdr);
+
+        return pdu;
+
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public Crnti getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(Crnti crnti) {
+        this.crnti = crnti;
+    }
+
+    public L2ReportInterval getReportIntervals() {
+        return reportIntervals;
+    }
+
+    public void setReportIntervals(L2ReportInterval reportIntervals) {
+        this.reportIntervals = reportIntervals;
+    }
+
+    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 += reportIntervals.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        if (crnti != null) {
+            codeLength += crnti.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+            os.write(0xA1);
+            codeLength += 1;
+        }
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            crnti = new Crnti();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            reportIntervals = new L2ReportInterval();
+            subCodeLength += reportIntervals.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        if (crnti != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("crnti: ");
+            crnti.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (reportIntervals != null) {
+            sb.append("reportIntervals: ");
+            reportIntervals.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("reportIntervals: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class Crnti 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 List<CRNTI> seqOf = null;
+
+        public Crnti() {
+            seqOf = new ArrayList<CRNTI>();
+        }
+
+        public Crnti(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<CRNTI> getCRNTI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<CRNTI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                CRNTI element = new CRNTI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<CRNTI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/PDCPMeasReportPerUe.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/PDCPMeasReportPerUe.java
new file mode 100644
index 0000000..8765da9
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/PDCPMeasReportPerUe.java
@@ -0,0 +1,1788 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.QCI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class PDCPMeasReportPerUe 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 ECGI ecgi = null;
+    private CRNTI crnti = null;
+    private QciVals qciVals = null;
+    private DataVolDl dataVolDl = null;
+    private DataVolUl dataVolUl = null;
+    private PktDelayDl pktDelayDl = null;
+    private PktDelayUl pktDelayUl = null;
+    private PktDiscardRateDl pktDiscardRateDl = null;
+    private PktLossRateDl pktLossRateDl = null;
+    private PktLossRateUl pktLossRateUl = null;
+    private ThroughputDl throughputDl = null;
+    private ThroughputUl throughputUl = null;
+
+    public PDCPMeasReportPerUe() {
+    }
+
+    public PDCPMeasReportPerUe(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public QciVals getQciVals() {
+        return qciVals;
+    }
+
+    public void setQciVals(QciVals qciVals) {
+        this.qciVals = qciVals;
+    }
+
+    public DataVolDl getDataVolDl() {
+        return dataVolDl;
+    }
+
+    public void setDataVolDl(DataVolDl dataVolDl) {
+        this.dataVolDl = dataVolDl;
+    }
+
+    public DataVolUl getDataVolUl() {
+        return dataVolUl;
+    }
+
+    public void setDataVolUl(DataVolUl dataVolUl) {
+        this.dataVolUl = dataVolUl;
+    }
+
+    public PktDelayDl getPktDelayDl() {
+        return pktDelayDl;
+    }
+
+    public void setPktDelayDl(PktDelayDl pktDelayDl) {
+        this.pktDelayDl = pktDelayDl;
+    }
+
+    public PktDelayUl getPktDelayUl() {
+        return pktDelayUl;
+    }
+
+    public void setPktDelayUl(PktDelayUl pktDelayUl) {
+        this.pktDelayUl = pktDelayUl;
+    }
+
+    public PktDiscardRateDl getPktDiscardRateDl() {
+        return pktDiscardRateDl;
+    }
+
+    public void setPktDiscardRateDl(PktDiscardRateDl pktDiscardRateDl) {
+        this.pktDiscardRateDl = pktDiscardRateDl;
+    }
+
+    public PktLossRateDl getPktLossRateDl() {
+        return pktLossRateDl;
+    }
+
+    public void setPktLossRateDl(PktLossRateDl pktLossRateDl) {
+        this.pktLossRateDl = pktLossRateDl;
+    }
+
+    public PktLossRateUl getPktLossRateUl() {
+        return pktLossRateUl;
+    }
+
+    public void setPktLossRateUl(PktLossRateUl pktLossRateUl) {
+        this.pktLossRateUl = pktLossRateUl;
+    }
+
+    public ThroughputDl getThroughputDl() {
+        return throughputDl;
+    }
+
+    public void setThroughputDl(ThroughputDl throughputDl) {
+        this.throughputDl = throughputDl;
+    }
+
+    public ThroughputUl getThroughputUl() {
+        return throughputUl;
+    }
+
+    public void setThroughputUl(ThroughputUl throughputUl) {
+        this.throughputUl = throughputUl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += throughputUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 11
+        os.write(0xAB);
+        codeLength += 1;
+
+        codeLength += throughputDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 10
+        os.write(0xAA);
+        codeLength += 1;
+
+        codeLength += pktLossRateUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 9
+        os.write(0xA9);
+        codeLength += 1;
+
+        codeLength += pktLossRateDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+        os.write(0xA8);
+        codeLength += 1;
+
+        codeLength += pktDiscardRateDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+        os.write(0xA7);
+        codeLength += 1;
+
+        codeLength += pktDelayUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+        os.write(0xA6);
+        codeLength += 1;
+
+        codeLength += pktDelayDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+        os.write(0xA5);
+        codeLength += 1;
+
+        codeLength += dataVolUl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+        os.write(0xA4);
+        codeLength += 1;
+
+        codeLength += dataVolDl.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += qciVals.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            qciVals = new QciVals();
+            subCodeLength += qciVals.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            dataVolDl = new DataVolDl();
+            subCodeLength += dataVolDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+            dataVolUl = new DataVolUl();
+            subCodeLength += dataVolUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+            pktDelayDl = new PktDelayDl();
+            subCodeLength += pktDelayDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+            pktDelayUl = new PktDelayUl();
+            subCodeLength += pktDelayUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+            pktDiscardRateDl = new PktDiscardRateDl();
+            subCodeLength += pktDiscardRateDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+            pktLossRateDl = new PktLossRateDl();
+            subCodeLength += pktLossRateDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 9)) {
+            pktLossRateUl = new PktLossRateUl();
+            subCodeLength += pktLossRateUl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 10)) {
+            throughputDl = new ThroughputDl();
+            subCodeLength += throughputDl.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 11)) {
+            throughputUl = new ThroughputUl();
+            subCodeLength += throughputUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (qciVals != null) {
+            sb.append("qciVals: ");
+            qciVals.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("qciVals: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (dataVolDl != null) {
+            sb.append("dataVolDl: ");
+            dataVolDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("dataVolDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (dataVolUl != null) {
+            sb.append("dataVolUl: ");
+            dataVolUl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("dataVolUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pktDelayDl != null) {
+            sb.append("pktDelayDl: ");
+            pktDelayDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pktDelayDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pktDelayUl != null) {
+            sb.append("pktDelayUl: ");
+            pktDelayUl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pktDelayUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pktDiscardRateDl != null) {
+            sb.append("pktDiscardRateDl: ");
+            pktDiscardRateDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pktDiscardRateDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pktLossRateDl != null) {
+            sb.append("pktLossRateDl: ");
+            pktLossRateDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pktLossRateDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pktLossRateUl != null) {
+            sb.append("pktLossRateUl: ");
+            pktLossRateUl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pktLossRateUl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (throughputDl != null) {
+            sb.append("throughputDl: ");
+            throughputDl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("throughputDl: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (throughputUl != null) {
+            sb.append("throughputUl: ");
+            throughputUl.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("throughputUl: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class QciVals 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 List<QCI> seqOf = null;
+
+        public QciVals() {
+            seqOf = new ArrayList<QCI>();
+        }
+
+        public QciVals(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<QCI> getQCI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<QCI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                QCI element = new QCI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<QCI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class DataVolDl 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 List<BerInteger> seqOf = null;
+
+        public DataVolDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public DataVolDl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class DataVolUl 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 List<BerInteger> seqOf = null;
+
+        public DataVolUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public DataVolUl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PktDelayDl 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 List<BerInteger> seqOf = null;
+
+        public PktDelayDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PktDelayDl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PktDelayUl 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 List<BerInteger> seqOf = null;
+
+        public PktDelayUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PktDelayUl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PktDiscardRateDl 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 List<BerInteger> seqOf = null;
+
+        public PktDiscardRateDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PktDiscardRateDl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PktLossRateDl 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 List<BerInteger> seqOf = null;
+
+        public PktLossRateDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PktLossRateDl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PktLossRateUl 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 List<BerInteger> seqOf = null;
+
+        public PktLossRateUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PktLossRateUl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class ThroughputDl 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 List<BerInteger> seqOf = null;
+
+        public ThroughputDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public ThroughputDl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class ThroughputUl 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 List<BerInteger> seqOf = null;
+
+        public ThroughputUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public ThroughputUl(byte[] code) {
+            this.code = code;
+        }
+
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRCMeasConfig.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRCMeasConfig.java
new file mode 100644
index 0000000..20b0980
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRCMeasConfig.java
@@ -0,0 +1,815 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.*;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RRCMeasConfig 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 ECGI ecgi = null;
+    private Crnti crnti = null;
+    private MeasObjects measObjects = null;
+    private ReportConfigs reportConfigs = null;
+    private MeasIds measIds = null;
+
+    public RRCMeasConfig() {
+    }
+
+    public RRCMeasConfig(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(
+            ECGI ecgi, CRNTI crnti, MeasObjects measObjects, ReportConfigs reportConfigs,
+            MeasIds measIds, int rxSignalInterval
+    ) {
+        RRCMeasConfig rrcMeasConfig = new RRCMeasConfig();
+
+        Crnti crntilist = new Crnti();
+        crntilist.getCRNTI().add(crnti);
+
+        rrcMeasConfig.setEcgi(ecgi);
+        rrcMeasConfig.setCrnti(crntilist);
+        rrcMeasConfig.setMeasIds(measIds);
+        rrcMeasConfig.setMeasObjects(measObjects);
+        rrcMeasConfig.setReportConfigs(reportConfigs);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        XrancApiID apiID = new XrancApiID(34);
+        XrancPduBody body = new XrancPduBody();
+        body.setRRCMeasConfig(rrcMeasConfig);
+
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setBody(body);
+        pdu.setHdr(hdr);
+
+        return pdu;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public Crnti getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(Crnti crnti) {
+        this.crnti = crnti;
+    }
+
+    public MeasObjects getMeasObjects() {
+        return measObjects;
+    }
+
+    public void setMeasObjects(MeasObjects measObjects) {
+        this.measObjects = measObjects;
+    }
+
+    public ReportConfigs getReportConfigs() {
+        return reportConfigs;
+    }
+
+    public void setReportConfigs(ReportConfigs reportConfigs) {
+        this.reportConfigs = reportConfigs;
+    }
+
+    public MeasIds getMeasIds() {
+        return measIds;
+    }
+
+    public void setMeasIds(MeasIds measIds) {
+        this.measIds = measIds;
+    }
+
+    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 += measIds.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+        os.write(0xA4);
+        codeLength += 1;
+
+        codeLength += reportConfigs.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += measObjects.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        if (crnti != null) {
+            codeLength += crnti.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+            os.write(0xA1);
+            codeLength += 1;
+        }
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            crnti = new Crnti();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            measObjects = new MeasObjects();
+            subCodeLength += measObjects.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            reportConfigs = new ReportConfigs();
+            subCodeLength += reportConfigs.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+            measIds = new MeasIds();
+            subCodeLength += measIds.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        if (crnti != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("crnti: ");
+            crnti.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (measObjects != null) {
+            sb.append("measObjects: ");
+            measObjects.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("measObjects: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (reportConfigs != null) {
+            sb.append("reportConfigs: ");
+            reportConfigs.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("reportConfigs: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (measIds != null) {
+            sb.append("measIds: ");
+            measIds.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("measIds: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class Crnti 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 List<CRNTI> seqOf = null;
+
+        public Crnti() {
+            seqOf = new ArrayList<CRNTI>();
+        }
+
+        public Crnti(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<CRNTI> getCRNTI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<CRNTI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                CRNTI element = new CRNTI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<CRNTI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class MeasObjects 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 List<MeasObject> seqOf = null;
+
+        public MeasObjects() {
+            seqOf = new ArrayList<MeasObject>();
+        }
+
+        public MeasObjects(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<MeasObject> getMeasObject() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<MeasObject>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                MeasObject element = new MeasObject();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<MeasObject> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class ReportConfigs 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 List<ReportConfig> seqOf = null;
+
+        public ReportConfigs() {
+            seqOf = new ArrayList<ReportConfig>();
+        }
+
+        public ReportConfigs(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<ReportConfig> getReportConfig() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<ReportConfig>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                ReportConfig element = new ReportConfig();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<ReportConfig> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class MeasIds 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 List<MeasID> seqOf = null;
+
+        public MeasIds() {
+            seqOf = new ArrayList<MeasID>();
+        }
+
+        public MeasIds(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<MeasID> getMeasID() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<MeasID>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                MeasID element = new MeasID();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<MeasID> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRMConfig.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRMConfig.java
new file mode 100644
index 0000000..196071c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRMConfig.java
@@ -0,0 +1,1647 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.PCIARFCN;
+import org.onosproject.xran.asn1lib.api.XICICPA;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerBitString;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RRMConfig 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 ECGI ecgi = null;
+    private Crnti crnti = null;
+    private PCIARFCN pciArfcn = null;
+    private Pa pa = null;
+    private StartPrbDl startPrbDl = null;
+    private EndPrbDl endPrbDl = null;
+    private SubframeBitmaskDl subframeBitmaskDl = null;
+    private P0UePusch p0UePusch = null;
+    private StartPrbUl startPrbUl = null;
+    private EndPrbUl endPrbUl = null;
+    private SubframeBitmaskUl subframeBitmaskUl = null;
+
+    public RRMConfig() {
+    }
+
+    public static XrancPdu constructPacket(RRMConfig config) {
+        XrancPduBody body = new XrancPduBody();
+        body.setRRMConfig(config);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        XrancApiID apiID = new XrancApiID(27);
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setHdr(hdr);
+        pdu.setBody(body);
+        return pdu;
+    }
+
+    public RRMConfig(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public Crnti getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(Crnti crnti) {
+        this.crnti = crnti;
+    }
+
+    public PCIARFCN getPciArfcn() {
+        return pciArfcn;
+    }
+
+    public void setPciArfcn(PCIARFCN pciArfcn) {
+        this.pciArfcn = pciArfcn;
+    }
+
+    public Pa getPa() {
+        return pa;
+    }
+
+    public void setPa(Pa pa) {
+        this.pa = pa;
+    }
+
+    public StartPrbDl getStartPrbDl() {
+        return startPrbDl;
+    }
+
+    public void setStartPrbDl(StartPrbDl startPrbDl) {
+        this.startPrbDl = startPrbDl;
+    }
+
+    public EndPrbDl getEndPrbDl() {
+        return endPrbDl;
+    }
+
+    public void setEndPrbDl(EndPrbDl endPrbDl) {
+        this.endPrbDl = endPrbDl;
+    }
+
+    public SubframeBitmaskDl getSubframeBitmaskDl() {
+        return subframeBitmaskDl;
+    }
+
+    public void setSubframeBitmaskDl(SubframeBitmaskDl subframeBitmaskDl) {
+        this.subframeBitmaskDl = subframeBitmaskDl;
+    }
+
+    public P0UePusch getP0UePusch() {
+        return p0UePusch;
+    }
+
+    public void setP0UePusch(P0UePusch p0UePusch) {
+        this.p0UePusch = p0UePusch;
+    }
+
+    public StartPrbUl getStartPrbUl() {
+        return startPrbUl;
+    }
+
+    public void setStartPrbUl(StartPrbUl startPrbUl) {
+        this.startPrbUl = startPrbUl;
+    }
+
+    public EndPrbUl getEndPrbUl() {
+        return endPrbUl;
+    }
+
+    public void setEndPrbUl(EndPrbUl endPrbUl) {
+        this.endPrbUl = endPrbUl;
+    }
+
+    public SubframeBitmaskUl getSubframeBitmaskUl() {
+        return subframeBitmaskUl;
+    }
+
+    public void setSubframeBitmaskUl(SubframeBitmaskUl subframeBitmaskUl) {
+        this.subframeBitmaskUl = subframeBitmaskUl;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        if (subframeBitmaskUl != null) {
+            codeLength += subframeBitmaskUl.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 10
+            os.write(0xAA);
+            codeLength += 1;
+        }
+
+        if (endPrbUl != null) {
+            codeLength += endPrbUl.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 9
+            os.write(0xA9);
+            codeLength += 1;
+        }
+
+        if (startPrbUl != null) {
+            codeLength += startPrbUl.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+            os.write(0xA8);
+            codeLength += 1;
+        }
+
+        if (p0UePusch != null) {
+            codeLength += p0UePusch.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+            os.write(0xA7);
+            codeLength += 1;
+        }
+
+        if (subframeBitmaskDl != null) {
+            codeLength += subframeBitmaskDl.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+            os.write(0xA6);
+            codeLength += 1;
+        }
+
+        if (endPrbDl != null) {
+            codeLength += endPrbDl.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+            os.write(0xA5);
+            codeLength += 1;
+        }
+
+        if (startPrbDl != null) {
+            codeLength += startPrbDl.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+            os.write(0xA4);
+            codeLength += 1;
+        }
+
+        if (pa != null) {
+            codeLength += pa.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+            os.write(0xA3);
+            codeLength += 1;
+        }
+
+        if (pciArfcn != null) {
+            codeLength += pciArfcn.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+            os.write(0xA2);
+            codeLength += 1;
+        }
+
+        if (crnti != null) {
+            codeLength += crnti.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+            os.write(0xA1);
+            codeLength += 1;
+        }
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            crnti = new Crnti();
+            subCodeLength += crnti.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            pciArfcn = new PCIARFCN();
+            subCodeLength += pciArfcn.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            pa = new Pa();
+            subCodeLength += pa.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+            startPrbDl = new StartPrbDl();
+            subCodeLength += startPrbDl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+            endPrbDl = new EndPrbDl();
+            subCodeLength += endPrbDl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+            subframeBitmaskDl = new SubframeBitmaskDl();
+            subCodeLength += subframeBitmaskDl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+            p0UePusch = new P0UePusch();
+            subCodeLength += p0UePusch.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+            startPrbUl = new StartPrbUl();
+            subCodeLength += startPrbUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 9)) {
+            endPrbUl = new EndPrbUl();
+            subCodeLength += endPrbUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 10)) {
+            subframeBitmaskUl = new SubframeBitmaskUl();
+            subCodeLength += subframeBitmaskUl.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        if (crnti != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("crnti: ");
+            crnti.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (pciArfcn != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("pciArfcn: ");
+            pciArfcn.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (pa != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("pa: ");
+            pa.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (startPrbDl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("startPrbDl: ");
+            startPrbDl.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (endPrbDl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("endPrbDl: ");
+            endPrbDl.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (subframeBitmaskDl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("subframeBitmaskDl: ");
+            subframeBitmaskDl.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (p0UePusch != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("p0UePusch: ");
+            p0UePusch.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (startPrbUl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("startPrbUl: ");
+            startPrbUl.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (endPrbUl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("endPrbUl: ");
+            endPrbUl.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (subframeBitmaskUl != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("subframeBitmaskUl: ");
+            subframeBitmaskUl.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class Crnti 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 List<CRNTI> seqOf = null;
+
+        public Crnti() {
+            seqOf = new ArrayList<CRNTI>();
+        }
+
+        public Crnti(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<CRNTI> getCRNTI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<CRNTI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                CRNTI element = new CRNTI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<CRNTI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class Pa implements Serializable {
+
+        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 List<XICICPA> seqOf = null;
+
+        public Pa() {
+            seqOf = new ArrayList<XICICPA>();
+        }
+
+        public Pa(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<XICICPA> getXICICPA() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<XICICPA>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                XICICPA element = new XICICPA();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<XICICPA> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class StartPrbDl implements Serializable {
+
+        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 List<BerInteger> seqOf = null;
+
+        public StartPrbDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public StartPrbDl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class EndPrbDl implements Serializable {
+
+        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 List<BerInteger> seqOf = null;
+
+        public EndPrbDl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public EndPrbDl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class SubframeBitmaskDl implements Serializable {
+
+        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 List<BerBitString> seqOf = null;
+
+        public SubframeBitmaskDl() {
+            seqOf = new ArrayList<BerBitString>();
+        }
+
+        public SubframeBitmaskDl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerBitString> getBerBitString() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerBitString>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerBitString element = new BerBitString();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerBitString> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class P0UePusch implements Serializable {
+
+        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 List<BerInteger> seqOf = null;
+
+        public P0UePusch() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public P0UePusch(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class StartPrbUl implements Serializable {
+
+        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 List<BerInteger> seqOf = null;
+
+        public StartPrbUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public StartPrbUl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class EndPrbUl implements Serializable {
+
+        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 List<BerInteger> seqOf = null;
+
+        public EndPrbUl() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public EndPrbUl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class SubframeBitmaskUl implements Serializable {
+
+        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 List<BerBitString> seqOf = null;
+
+        public SubframeBitmaskUl() {
+            seqOf = new ArrayList<BerBitString>();
+        }
+
+        public SubframeBitmaskUl(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerBitString> getBerBitString() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerBitString>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerBitString element = new BerBitString();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerBitString> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRMConfigStatus.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRMConfigStatus.java
new file mode 100644
index 0000000..009c0da
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RRMConfigStatus.java
@@ -0,0 +1,460 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RRMConfigStatus implements Serializable {
+
+    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 ECGI ecgi = null;
+    private Crnti crnti = null;
+    private Status status = null;
+
+    public RRMConfigStatus() {
+    }
+
+    public RRMConfigStatus(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public Crnti getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(Crnti crnti) {
+        this.crnti = crnti;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += status.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        if (crnti != null) {
+            codeLength += crnti.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+            os.write(0xA1);
+            codeLength += 1;
+        }
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            crnti = new Crnti();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            status = new Status();
+            subCodeLength += status.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        if (crnti != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("crnti: ");
+            crnti.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (status != null) {
+            sb.append("status: ");
+            status.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("status: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class Crnti 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 List<CRNTI> seqOf = null;
+
+        public Crnti() {
+            seqOf = new ArrayList<CRNTI>();
+        }
+
+        public Crnti(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<CRNTI> getCRNTI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<CRNTI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                CRNTI element = new CRNTI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<CRNTI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class Status implements Serializable {
+
+        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 List<BerEnum> seqOf = null;
+
+        public Status() {
+            seqOf = new ArrayList<BerEnum>();
+        }
+
+        public Status(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerEnum> getBerEnum() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerEnum>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerEnum element = new BerEnum();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerEnum> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RXSigMeasReport.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RXSigMeasReport.java
new file mode 100644
index 0000000..9e12d1f
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RXSigMeasReport.java
@@ -0,0 +1,588 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.RXSigReport;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RXSigMeasReport implements Serializable {
+
+    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 Crnti crnti = null;
+    private ECGI ecgi = null;
+    private CellMeasReports cellMeasReports = null;
+
+    public RXSigMeasReport() {
+    }
+
+    public RXSigMeasReport(byte[] code) {
+        this.code = code;
+    }
+
+    public Crnti getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(Crnti crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public CellMeasReports getCellMeasReports() {
+        return cellMeasReports;
+    }
+
+    public void setCellMeasReports(CellMeasReports cellMeasReports) {
+        this.cellMeasReports = cellMeasReports;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += cellMeasReports.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, 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)) {
+            crnti = new Crnti();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            cellMeasReports = new CellMeasReports();
+            subCodeLength += cellMeasReports.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ");
+            crnti.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (cellMeasReports != null) {
+            sb.append("cellMeasReports: ");
+            cellMeasReports.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("cellMeasReports: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class Crnti 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 List<CRNTI> seqOf = null;
+
+        public Crnti() {
+            seqOf = new ArrayList<CRNTI>();
+        }
+
+        public Crnti(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<CRNTI> getCRNTI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<CRNTI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                CRNTI element = new CRNTI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<CRNTI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class CellMeasReports 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 List<SEQUENCEOF> seqOf = null;
+
+        public CellMeasReports() {
+            seqOf = new ArrayList<SEQUENCEOF>();
+        }
+
+        public CellMeasReports(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<SEQUENCEOF> getSEQUENCEOF() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<SEQUENCEOF>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                SEQUENCEOF element = new SEQUENCEOF();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<SEQUENCEOF> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+        public static class SEQUENCEOF 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 List<RXSigReport> seqOf = null;
+
+            public SEQUENCEOF() {
+                seqOf = new ArrayList<RXSigReport>();
+            }
+
+            public SEQUENCEOF(byte[] code) {
+                this.code = code;
+            }
+
+            @JsonValue
+            public List<RXSigReport> getRXSigReport() {
+                if (seqOf == null) {
+                    seqOf = new ArrayList<RXSigReport>();
+                }
+                return seqOf;
+            }
+
+            public int encode(BerByteArrayOutputStream os) throws IOException {
+                return encode(os, true);
+            }
+
+            public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+                if (code != null) {
+                    for (int i = code.length - 1; i >= 0; i--) {
+                        os.write(code[i]);
+                    }
+                    if (withTag) {
+                        return tag.encode(os) + code.length;
+                    }
+                    return code.length;
+                }
+
+                int codeLength = 0;
+                for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                    codeLength += seqOf.get(i).encode(os, true);
+                }
+
+                codeLength += BerLength.encodeLength(os, codeLength);
+
+                if (withTag) {
+                    codeLength += tag.encode(os);
+                }
+
+                return codeLength;
+            }
+
+            public int decode(InputStream is) throws IOException {
+                return decode(is, true);
+            }
+
+            public int decode(InputStream is, boolean withTag) throws IOException {
+                int codeLength = 0;
+                int subCodeLength = 0;
+                if (withTag) {
+                    codeLength += tag.decodeAndCheck(is);
+                }
+
+                BerLength length = new BerLength();
+                codeLength += length.decode(is);
+                int totalLength = length.val;
+
+                while (subCodeLength < totalLength) {
+                    RXSigReport element = new RXSigReport();
+                    subCodeLength += element.decode(is, true);
+                    seqOf.add(element);
+                }
+                if (subCodeLength != totalLength) {
+                    throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+                }
+                codeLength += subCodeLength;
+
+                return codeLength;
+            }
+
+            public void encodeAndSave(int encodingSizeGuess) throws IOException {
+                BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+                encode(os, false);
+                code = os.getArray();
+            }
+
+            public String toString() {
+                StringBuilder sb = new StringBuilder();
+                appendAsString(sb, 0);
+                return sb.toString();
+            }
+
+            public void appendAsString(StringBuilder sb, int indentLevel) {
+
+                sb.append("{\n");
+                for (int i = 0; i < indentLevel + 1; i++) {
+                    sb.append("\t");
+                }
+                if (seqOf == null) {
+                    sb.append("null");
+                } else {
+                    Iterator<RXSigReport> it = seqOf.iterator();
+                    if (it.hasNext()) {
+                        it.next().appendAsString(sb, indentLevel + 1);
+                        while (it.hasNext()) {
+                            sb.append(",\n");
+                            for (int i = 0; i < indentLevel + 1; i++) {
+                                sb.append("\t");
+                            }
+                            it.next().appendAsString(sb, indentLevel + 1);
+                        }
+                    }
+                }
+
+                sb.append("\n");
+                for (int i = 0; i < indentLevel; i++) {
+                    sb.append("\t");
+                }
+                sb.append("}");
+            }
+
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RadioMeasReportPerCell.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RadioMeasReportPerCell.java
new file mode 100644
index 0000000..60838a0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RadioMeasReportPerCell.java
@@ -0,0 +1,461 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RadioMeasReportPerCell implements Serializable {
+
+    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 ECGI ecgi = null;
+    private PuschIntfPowerHist puschIntfPowerHist = null;
+    private PucchIntfPowerHist pucchIntfPowerHist = null;
+
+    public RadioMeasReportPerCell() {
+    }
+
+    public RadioMeasReportPerCell(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public PuschIntfPowerHist getPuschIntfPowerHist() {
+        return puschIntfPowerHist;
+    }
+
+    public void setPuschIntfPowerHist(PuschIntfPowerHist puschIntfPowerHist) {
+        this.puschIntfPowerHist = puschIntfPowerHist;
+    }
+
+    public PucchIntfPowerHist getPucchIntfPowerHist() {
+        return pucchIntfPowerHist;
+    }
+
+    public void setPucchIntfPowerHist(PucchIntfPowerHist pucchIntfPowerHist) {
+        this.pucchIntfPowerHist = pucchIntfPowerHist;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += pucchIntfPowerHist.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += puschIntfPowerHist.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            puschIntfPowerHist = new PuschIntfPowerHist();
+            subCodeLength += puschIntfPowerHist.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            pucchIntfPowerHist = new PucchIntfPowerHist();
+            subCodeLength += pucchIntfPowerHist.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (puschIntfPowerHist != null) {
+            sb.append("puschIntfPowerHist: ");
+            puschIntfPowerHist.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("puschIntfPowerHist: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (pucchIntfPowerHist != null) {
+            sb.append("pucchIntfPowerHist: ");
+            pucchIntfPowerHist.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("pucchIntfPowerHist: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class PuschIntfPowerHist 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 List<BerInteger> seqOf = null;
+
+        public PuschIntfPowerHist() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PuschIntfPowerHist(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class PucchIntfPowerHist 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 List<BerInteger> seqOf = null;
+
+        public PucchIntfPowerHist() {
+            seqOf = new ArrayList<BerInteger>();
+        }
+
+        public PucchIntfPowerHist(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerInteger> getBerInteger() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerInteger>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerInteger element = new BerInteger();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerInteger> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RadioMeasReportPerUE.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RadioMeasReportPerUE.java
new file mode 100644
index 0000000..204060b
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/RadioMeasReportPerUE.java
@@ -0,0 +1,335 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.RadioRepPerServCell;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RadioMeasReportPerUE implements Serializable {
+
+    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 ECGI ecgi = null;
+    private CRNTI crnti = null;
+    private RadioReportServCells radioReportServCells = null;
+
+    public RadioMeasReportPerUE() {
+    }
+
+    public RadioMeasReportPerUE(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public RadioReportServCells getRadioReportServCells() {
+        return radioReportServCells;
+    }
+
+    public void setRadioReportServCells(RadioReportServCells radioReportServCells) {
+        this.radioReportServCells = radioReportServCells;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += radioReportServCells.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            radioReportServCells = new RadioReportServCells();
+            subCodeLength += radioReportServCells.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (radioReportServCells != null) {
+            sb.append("radioReportServCells: ");
+            radioReportServCells.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("radioReportServCells: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class RadioReportServCells 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 List<RadioRepPerServCell> seqOf = null;
+
+        public RadioReportServCells() {
+            seqOf = new ArrayList<RadioRepPerServCell>();
+        }
+
+        public RadioReportServCells(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<RadioRepPerServCell> getRadioRepPerServCell() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<RadioRepPerServCell>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                RadioRepPerServCell element = new RadioRepPerServCell();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<RadioRepPerServCell> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellAdd.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellAdd.java
new file mode 100644
index 0000000..5e524e9
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellAdd.java
@@ -0,0 +1,374 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.PropScell;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerBoolean;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ScellAdd 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private ScellsProp scellsProp = null;
+
+    public ScellAdd() {
+    }
+
+    public ScellAdd(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(ECGI ecgi, CRNTI crnti, PropScell propScell) {
+        ScellAdd scellAdd = new ScellAdd();
+        scellAdd.setCrnti(crnti);
+        scellAdd.setEcgi(ecgi);
+
+        propScell.setCrossCarrierSchedEnable(new BerBoolean(true));
+        propScell.setCaDirection(new BerEnum(new BigInteger("dl")));
+        propScell.setDeactTimer(new BerInteger(1000));
+        ScellsProp scellsProp = new ScellsProp();
+        scellsProp.getPropScell().add(propScell);
+        scellAdd.setScellsProp(scellsProp);
+
+        XrancPduBody body = new XrancPduBody();
+        body.setScellAdd(scellAdd);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        XrancApiID apiID = new XrancApiID(24);
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setHdr(hdr);
+        pdu.setBody(body);
+
+        return pdu;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public ScellsProp getScellsProp() {
+        return scellsProp;
+    }
+
+    public void setScellsProp(ScellsProp scellsProp) {
+        this.scellsProp = scellsProp;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += scellsProp.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            scellsProp = new ScellsProp();
+            subCodeLength += scellsProp.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (scellsProp != null) {
+            sb.append("scellsProp: ");
+            scellsProp.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("scellsProp: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class ScellsProp 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 List<PropScell> seqOf = null;
+
+        public ScellsProp() {
+            seqOf = new ArrayList<PropScell>();
+        }
+
+        public ScellsProp(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<PropScell> getPropScell() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<PropScell>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                PropScell element = new PropScell();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<PropScell> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellAddStatus.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellAddStatus.java
new file mode 100644
index 0000000..ea29f54
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellAddStatus.java
@@ -0,0 +1,493 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.PCIARFCN;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ScellAddStatus implements Serializable {
+
+    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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private ScellsInd scellsInd = null;
+    private Status status = null;
+    public ScellAddStatus() {
+    }
+    public ScellAddStatus(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public ScellsInd getScellsInd() {
+        return scellsInd;
+    }
+
+    public void setScellsInd(ScellsInd scellsInd) {
+        this.scellsInd = scellsInd;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += status.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += scellsInd.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            scellsInd = new ScellsInd();
+            subCodeLength += scellsInd.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            status = new Status();
+            subCodeLength += status.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (scellsInd != null) {
+            sb.append("scellsInd: ");
+            scellsInd.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("scellsInd: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (status != null) {
+            sb.append("status: ");
+            status.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("status: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class ScellsInd 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 List<PCIARFCN> seqOf = null;
+
+        public ScellsInd() {
+            seqOf = new ArrayList<PCIARFCN>();
+        }
+
+        public ScellsInd(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<PCIARFCN> getPCIARFCN() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<PCIARFCN>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                PCIARFCN element = new PCIARFCN();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<PCIARFCN> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+    public static class Status implements Serializable {
+
+        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 List<BerEnum> seqOf = null;
+
+        public Status() {
+            seqOf = new ArrayList<BerEnum>();
+        }
+
+        public Status(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<BerEnum> getBerEnum() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<BerEnum>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                BerEnum element = new BerEnum();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<BerEnum> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellDelete.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellDelete.java
new file mode 100644
index 0000000..a17b221
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/ScellDelete.java
@@ -0,0 +1,367 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.PCIARFCN;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ScellDelete 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private ScellsInd scellsInd = null;
+
+    public ScellDelete() {
+    }
+
+    public ScellDelete(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(ECGI ecgi, CRNTI crnti, PCIARFCN pciarfcn) {
+        ScellDelete scellDelete = new ScellDelete();
+        scellDelete.setEcgi(ecgi);
+        scellDelete.setCrnti(crnti);
+        ScellsInd scellsInd = new ScellsInd();
+        scellsInd.getPCIARFCN().add(pciarfcn);
+        scellDelete.setScellsInd(scellsInd);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+
+        XrancApiID apiID = new XrancApiID(26);
+        XrancPduBody body = new XrancPduBody();
+        body.setScellDelete(scellDelete);
+
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setBody(body);
+        pdu.setHdr(hdr);
+
+        return pdu;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public ScellsInd getScellsInd() {
+        return scellsInd;
+    }
+
+    public void setScellsInd(ScellsInd scellsInd) {
+        this.scellsInd = scellsInd;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += scellsInd.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            scellsInd = new ScellsInd();
+            subCodeLength += scellsInd.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (scellsInd != null) {
+            sb.append("scellsInd: ");
+            scellsInd.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("scellsInd: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class ScellsInd 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 List<PCIARFCN> seqOf = null;
+
+        public ScellsInd() {
+            seqOf = new ArrayList<PCIARFCN>();
+        }
+
+        public ScellsInd(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<PCIARFCN> getPCIARFCN() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<PCIARFCN>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                PCIARFCN element = new PCIARFCN();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<PCIARFCN> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SchedMeasReportPerCell.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SchedMeasReportPerCell.java
new file mode 100644
index 0000000..e926702
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SchedMeasReportPerCell.java
@@ -0,0 +1,369 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.PRBUsage;
+import org.onosproject.xran.asn1lib.api.QCI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class SchedMeasReportPerCell implements Serializable {
+
+    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 ECGI ecgi = null;
+    private QciVals qciVals = null;
+    private PRBUsage prbUsagePcell = null;
+    private PRBUsage prbUsageScell = null;
+
+    public SchedMeasReportPerCell() {
+    }
+
+    public SchedMeasReportPerCell(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public QciVals getQciVals() {
+        return qciVals;
+    }
+
+    public void setQciVals(QciVals qciVals) {
+        this.qciVals = qciVals;
+    }
+
+    public PRBUsage getPrbUsagePcell() {
+        return prbUsagePcell;
+    }
+
+    public void setPrbUsagePcell(PRBUsage prbUsagePcell) {
+        this.prbUsagePcell = prbUsagePcell;
+    }
+
+    public PRBUsage getPrbUsageScell() {
+        return prbUsageScell;
+    }
+
+    public void setPrbUsageScell(PRBUsage prbUsageScell) {
+        this.prbUsageScell = prbUsageScell;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += prbUsageScell.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+        os.write(0xA3);
+        codeLength += 1;
+
+        codeLength += prbUsagePcell.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += qciVals.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            qciVals = new QciVals();
+            subCodeLength += qciVals.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            prbUsagePcell = new PRBUsage();
+            subCodeLength += prbUsagePcell.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            prbUsageScell = new PRBUsage();
+            subCodeLength += prbUsageScell.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (qciVals != null) {
+            sb.append("qciVals: ");
+            qciVals.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("qciVals: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (prbUsagePcell != null) {
+            sb.append("prbUsagePcell: ");
+            prbUsagePcell.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("prbUsagePcell: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (prbUsageScell != null) {
+            sb.append("prbUsageScell: ");
+            prbUsageScell.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("prbUsageScell: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class QciVals 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 List<QCI> seqOf = null;
+
+        public QciVals() {
+            seqOf = new ArrayList<QCI>();
+        }
+
+        public QciVals(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<QCI> getQCI() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<QCI>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                QCI element = new QCI();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<QCI> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    sb.append(it.next());
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        sb.append(it.next());
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SchedMeasReportPerUE.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SchedMeasReportPerUE.java
new file mode 100644
index 0000000..211ea0f
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SchedMeasReportPerUE.java
@@ -0,0 +1,335 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.SchedMeasRepPerServCell;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class SchedMeasReportPerUE implements Serializable {
+
+    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 ECGI ecgi = null;
+    private CRNTI crnti = null;
+    private SchedReportServCells schedReportServCells = null;
+
+    public SchedMeasReportPerUE() {
+    }
+
+    public SchedMeasReportPerUE(byte[] code) {
+        this.code = code;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public SchedReportServCells getSchedReportServCells() {
+        return schedReportServCells;
+    }
+
+    public void setSchedReportServCells(SchedReportServCells schedReportServCells) {
+        this.schedReportServCells = schedReportServCells;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += schedReportServCells.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 1
+        os.write(0x81);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+        os.write(0xA0);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            schedReportServCells = new SchedReportServCells();
+            subCodeLength += schedReportServCells.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (schedReportServCells != null) {
+            sb.append("schedReportServCells: ");
+            schedReportServCells.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("schedReportServCells: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class SchedReportServCells 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 List<SchedMeasRepPerServCell> seqOf = null;
+
+        public SchedReportServCells() {
+            seqOf = new ArrayList<SchedMeasRepPerServCell>();
+        }
+
+        public SchedReportServCells(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<SchedMeasRepPerServCell> getSchedMeasRepPerServCell() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<SchedMeasRepPerServCell>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                SchedMeasRepPerServCell element = new SchedMeasRepPerServCell();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<SchedMeasRepPerServCell> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBAdd.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBAdd.java
new file mode 100644
index 0000000..df99522
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBAdd.java
@@ -0,0 +1,204 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class SeNBAdd 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 CRNTI crnti = null;
+    private ECGI mEcgi = null;
+    private ECGI sEcgi = null;
+
+    public SeNBAdd() {
+    }
+
+    public SeNBAdd(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getMEcgi() {
+        return mEcgi;
+    }
+
+    public void setMEcgi(ECGI mEcgi) {
+        this.mEcgi = mEcgi;
+    }
+
+    public ECGI getSEcgi() {
+        return sEcgi;
+    }
+
+    public void setSEcgi(ECGI sEcgi) {
+        this.sEcgi = sEcgi;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += sEcgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += mEcgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            mEcgi = new ECGI();
+            subCodeLength += mEcgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            sEcgi = new ECGI();
+            subCodeLength += sEcgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (mEcgi != null) {
+            sb.append("mEcgi: ");
+            mEcgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("mEcgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (sEcgi != null) {
+            sb.append("sEcgi: ");
+            sEcgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("sEcgi: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBAddStatus.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBAddStatus.java
new file mode 100644
index 0000000..e68799b
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBAddStatus.java
@@ -0,0 +1,204 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class SeNBAddStatus 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private BerEnum status = null;
+
+    public SeNBAddStatus() {
+    }
+
+    public SeNBAddStatus(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public BerEnum getStatus() {
+        return status;
+    }
+
+    public void setStatus(BerEnum status) {
+        this.status = status;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += status.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            status = new BerEnum();
+            subCodeLength += status.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (status != null) {
+            sb.append("status: ").append(status);
+        } else {
+            sb.append("status: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBDelete.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBDelete.java
new file mode 100644
index 0000000..35fc047
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/SeNBDelete.java
@@ -0,0 +1,204 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class SeNBDelete 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 CRNTI crnti = null;
+    private ECGI mEcgi = null;
+    private ECGI sEcgi = null;
+
+    public SeNBDelete() {
+    }
+
+    public SeNBDelete(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getMEcgi() {
+        return mEcgi;
+    }
+
+    public void setMEcgi(ECGI mEcgi) {
+        this.mEcgi = mEcgi;
+    }
+
+    public ECGI getSEcgi() {
+        return sEcgi;
+    }
+
+    public void setSEcgi(ECGI sEcgi) {
+        this.sEcgi = sEcgi;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += sEcgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += mEcgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            mEcgi = new ECGI();
+            subCodeLength += mEcgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            sEcgi = new ECGI();
+            subCodeLength += sEcgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (mEcgi != null) {
+            sb.append("mEcgi: ");
+            mEcgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("mEcgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (sEcgi != null) {
+            sb.append("sEcgi: ");
+            sEcgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("sEcgi: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/TrafficSplitConfig.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/TrafficSplitConfig.java
new file mode 100644
index 0000000..ebdc917
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/TrafficSplitConfig.java
@@ -0,0 +1,335 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonValue;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.TrafficSplitPercentage;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class TrafficSplitConfig implements Serializable {
+
+    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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private TrafficSplitPercent trafficSplitPercent = null;
+
+    public TrafficSplitConfig() {
+    }
+
+    public TrafficSplitConfig(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public TrafficSplitPercent getTrafficSplitPercent() {
+        return trafficSplitPercent;
+    }
+
+    public void setTrafficSplitPercent(TrafficSplitPercent trafficSplitPercent) {
+        this.trafficSplitPercent = trafficSplitPercent;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += trafficSplitPercent.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+        os.write(0xA2);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            trafficSplitPercent = new TrafficSplitPercent();
+            subCodeLength += trafficSplitPercent.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (trafficSplitPercent != null) {
+            sb.append("trafficSplitPercent: ");
+            trafficSplitPercent.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("trafficSplitPercent: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+    public static class TrafficSplitPercent 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 List<TrafficSplitPercentage> seqOf = null;
+
+        public TrafficSplitPercent() {
+            seqOf = new ArrayList<TrafficSplitPercentage>();
+        }
+
+        public TrafficSplitPercent(byte[] code) {
+            this.code = code;
+        }
+
+        @JsonValue
+        public List<TrafficSplitPercentage> getTrafficSplitPercentage() {
+            if (seqOf == null) {
+                seqOf = new ArrayList<TrafficSplitPercentage>();
+            }
+            return seqOf;
+        }
+
+        public int encode(BerByteArrayOutputStream os) throws IOException {
+            return encode(os, true);
+        }
+
+        public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+            if (code != null) {
+                for (int i = code.length - 1; i >= 0; i--) {
+                    os.write(code[i]);
+                }
+                if (withTag) {
+                    return tag.encode(os) + code.length;
+                }
+                return code.length;
+            }
+
+            int codeLength = 0;
+            for (int i = (seqOf.size() - 1); i >= 0; i--) {
+                codeLength += seqOf.get(i).encode(os, true);
+            }
+
+            codeLength += BerLength.encodeLength(os, codeLength);
+
+            if (withTag) {
+                codeLength += tag.encode(os);
+            }
+
+            return codeLength;
+        }
+
+        public int decode(InputStream is) throws IOException {
+            return decode(is, true);
+        }
+
+        public int decode(InputStream is, boolean withTag) throws IOException {
+            int codeLength = 0;
+            int subCodeLength = 0;
+            if (withTag) {
+                codeLength += tag.decodeAndCheck(is);
+            }
+
+            BerLength length = new BerLength();
+            codeLength += length.decode(is);
+            int totalLength = length.val;
+
+            while (subCodeLength < totalLength) {
+                TrafficSplitPercentage element = new TrafficSplitPercentage();
+                subCodeLength += element.decode(is, true);
+                seqOf.add(element);
+            }
+            if (subCodeLength != totalLength) {
+                throw new IOException("Decoded SequenceOf or SetOf has wrong length. Expected " + totalLength + " but has " + subCodeLength);
+
+            }
+            codeLength += subCodeLength;
+
+            return codeLength;
+        }
+
+        public void encodeAndSave(int encodingSizeGuess) throws IOException {
+            BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+            encode(os, false);
+            code = os.getArray();
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            appendAsString(sb, 0);
+            return sb.toString();
+        }
+
+        public void appendAsString(StringBuilder sb, int indentLevel) {
+
+            sb.append("{\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            if (seqOf == null) {
+                sb.append("null");
+            } else {
+                Iterator<TrafficSplitPercentage> it = seqOf.iterator();
+                if (it.hasNext()) {
+                    it.next().appendAsString(sb, indentLevel + 1);
+                    while (it.hasNext()) {
+                        sb.append(",\n");
+                        for (int i = 0; i < indentLevel + 1; i++) {
+                            sb.append("\t");
+                        }
+                        it.next().appendAsString(sb, indentLevel + 1);
+                    }
+                }
+            }
+
+            sb.append("\n");
+            for (int i = 0; i < indentLevel; i++) {
+                sb.append("\t");
+            }
+            sb.append("}");
+        }
+
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionRequest.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionRequest.java
new file mode 100644
index 0000000..b807e50
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionRequest.java
@@ -0,0 +1,211 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.AdmEstCause;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEAdmissionRequest implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	@JsonIgnore
+	public byte[] code = null;
+	private CRNTI crnti = null;
+	private ECGI ecgi = null;
+	private AdmEstCause admEstCause = null;
+	
+	public UEAdmissionRequest() {
+	}
+
+	public UEAdmissionRequest(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCrnti(CRNTI crnti) {
+		this.crnti = crnti;
+	}
+
+	public CRNTI getCrnti() {
+		return crnti;
+	}
+
+	public void setEcgi(ECGI ecgi) {
+		this.ecgi = ecgi;
+	}
+
+	public ECGI getEcgi() {
+		return ecgi;
+	}
+
+	public void setAdmEstCause(AdmEstCause admEstCause) {
+		this.admEstCause = admEstCause;
+	}
+
+	public AdmEstCause getAdmEstCause() {
+		return admEstCause;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += admEstCause.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 2
+		os.write(0x82);
+		codeLength += 1;
+		
+		codeLength += ecgi.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += crnti.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			crnti = new CRNTI();
+			subCodeLength += crnti.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			ecgi = new ECGI();
+			subCodeLength += ecgi.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+			admEstCause = new AdmEstCause();
+			subCodeLength += admEstCause.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (crnti != null) {
+			sb.append("crnti: ").append(crnti);
+		}
+		else {
+			sb.append("crnti: <empty-required-field>");
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ecgi != null) {
+			sb.append("ecgi: ");
+			ecgi.appendAsString(sb, indentLevel + 1);
+		}
+		else {
+			sb.append("ecgi: <empty-required-field>");
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (admEstCause != null) {
+			sb.append("admEstCause: ").append(admEstCause);
+		}
+		else {
+			sb.append("admEstCause: <empty-required-field>");
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionResponse.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionResponse.java
new file mode 100644
index 0000000..e06c0fd
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionResponse.java
@@ -0,0 +1,234 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.AdmEstResponse;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+
+public class UEAdmissionResponse 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private AdmEstResponse admEstResponse = null;
+
+    public UEAdmissionResponse() {
+    }
+
+    public UEAdmissionResponse(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(ECGI ecgi, CRNTI crnti, boolean b) {
+        AdmEstResponse response = new AdmEstResponse(b ? 0 : 1);
+
+        UEAdmissionResponse ueAdmissionResponse = new UEAdmissionResponse();
+        ueAdmissionResponse.setCrnti(crnti);
+        ueAdmissionResponse.setEcgi(ecgi);
+        ueAdmissionResponse.setAdmEstResponse(response);
+
+        XrancPduBody body = new XrancPduBody();
+        body.setUEAdmissionResponse(ueAdmissionResponse);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        XrancApiID apiID = new XrancApiID(3);
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setHdr(hdr);
+        pdu.setBody(body);
+        return pdu;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public AdmEstResponse getAdmEstResponse() {
+        return admEstResponse;
+    }
+
+    public void setAdmEstResponse(AdmEstResponse admEstResponse) {
+        this.admEstResponse = admEstResponse;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += admEstResponse.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            admEstResponse = new AdmEstResponse();
+            subCodeLength += admEstResponse.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (admEstResponse != null) {
+            sb.append("admEstResponse: ").append(admEstResponse);
+        } else {
+            sb.append("admEstResponse: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionStatus.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionStatus.java
new file mode 100644
index 0000000..137bf60
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEAdmissionStatus.java
@@ -0,0 +1,204 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.AdmEstStatus;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEAdmissionStatus 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private AdmEstStatus admEstStatus = null;
+
+    public UEAdmissionStatus() {
+    }
+
+    public UEAdmissionStatus(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public AdmEstStatus getAdmEstStatus() {
+        return admEstStatus;
+    }
+
+    public void setAdmEstStatus(AdmEstStatus admEstStatus) {
+        this.admEstStatus = admEstStatus;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += admEstStatus.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            admEstStatus = new AdmEstStatus();
+            subCodeLength += admEstStatus.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (admEstStatus != null) {
+            sb.append("admEstStatus: ").append(admEstStatus);
+        } else {
+            sb.append("admEstStatus: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UECapabilityEnquiry.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UECapabilityEnquiry.java
new file mode 100644
index 0000000..ceb3b79
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UECapabilityEnquiry.java
@@ -0,0 +1,199 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+
+public class UECapabilityEnquiry 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+
+    public UECapabilityEnquiry() {
+    }
+
+    public UECapabilityEnquiry(byte[] code) {
+        this.code = code;
+    }
+
+    public static XrancPdu constructPacket(ECGI ecgi, CRNTI crnti) {
+        UECapabilityEnquiry capabilityEnquiry = new UECapabilityEnquiry();
+        capabilityEnquiry.setCrnti(crnti);
+        capabilityEnquiry.setEcgi(ecgi);
+
+        XrancPduBody body = new XrancPduBody();
+        body.setUECapabilityEnquiry(capabilityEnquiry);
+
+        BerUTF8String ver = null;
+        try {
+            ver = new BerUTF8String("5");
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        }
+        XrancApiID apiID = new XrancApiID(22);
+        XrancPduHdr hdr = new XrancPduHdr();
+        hdr.setVer(ver);
+        hdr.setApiId(apiID);
+
+        XrancPdu pdu = new XrancPdu();
+        pdu.setHdr(hdr);
+        pdu.setBody(body);
+
+        return pdu;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UECapabilityInfo.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UECapabilityInfo.java
new file mode 100644
index 0000000..b842ec4
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UECapabilityInfo.java
@@ -0,0 +1,243 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CACap;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.DCCap;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UECapabilityInfo 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private CACap caCap = null;
+    private DCCap dcCap = null;
+
+    public UECapabilityInfo() {
+    }
+
+    public UECapabilityInfo(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public CACap getCaCap() {
+        return caCap;
+    }
+
+    public void setCaCap(CACap caCap) {
+        this.caCap = caCap;
+    }
+
+    public DCCap getDcCap() {
+        return dcCap;
+    }
+
+    public void setDcCap(DCCap dcCap) {
+        this.dcCap = dcCap;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        if (dcCap != null) {
+            codeLength += dcCap.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+            os.write(0xA3);
+            codeLength += 1;
+        }
+
+        if (caCap != null) {
+            codeLength += caCap.encode(os, false);
+            // write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+            os.write(0xA2);
+            codeLength += 1;
+        }
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+            caCap = new CACap();
+            subCodeLength += caCap.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+            dcCap = new DCCap();
+            subCodeLength += dcCap.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        if (caCap != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("caCap: ");
+            caCap.appendAsString(sb, indentLevel + 1);
+        }
+
+        if (dcCap != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("dcCap: ");
+            dcCap.appendAsString(sb, indentLevel + 1);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEContextUpdate.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEContextUpdate.java
new file mode 100644
index 0000000..310cc7d
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEContextUpdate.java
@@ -0,0 +1,273 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.ENBUES1APID;
+import org.onosproject.xran.asn1lib.api.MMEUES1APID;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEContextUpdate 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private MMEUES1APID mMEUES1APID = null;
+    private ENBUES1APID eNBUES1APID = null;
+    private BerUTF8String imsi = null;
+
+    public UEContextUpdate() {
+    }
+
+    public UEContextUpdate(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public MMEUES1APID getMMEUES1APID() {
+        return mMEUES1APID;
+    }
+
+    public void setMMEUES1APID(MMEUES1APID mMEUES1APID) {
+        this.mMEUES1APID = mMEUES1APID;
+    }
+
+    public ENBUES1APID getENBUES1APID() {
+        return eNBUES1APID;
+    }
+
+    public void setENBUES1APID(ENBUES1APID eNBUES1APID) {
+        this.eNBUES1APID = eNBUES1APID;
+    }
+
+    public BerUTF8String getImsi() {
+        return imsi;
+    }
+
+    public void setImsi(BerUTF8String imsi) {
+        this.imsi = imsi;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        if (imsi != null) {
+            codeLength += imsi.encode(os, false);
+            // write tag: CONTEXT_CLASS, PRIMITIVE, 4
+            os.write(0x84);
+            codeLength += 1;
+        }
+
+        codeLength += eNBUES1APID.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += mMEUES1APID.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            mMEUES1APID = new MMEUES1APID();
+            subCodeLength += mMEUES1APID.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            eNBUES1APID = new ENBUES1APID();
+            subCodeLength += eNBUES1APID.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 4)) {
+            imsi = new BerUTF8String();
+            subCodeLength += imsi.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (mMEUES1APID != null) {
+            sb.append("mMEUES1APID: ").append(mMEUES1APID);
+        } else {
+            sb.append("mMEUES1APID: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (eNBUES1APID != null) {
+            sb.append("eNBUES1APID: ").append(eNBUES1APID);
+        } else {
+            sb.append("eNBUES1APID: <empty-required-field>");
+        }
+
+        if (imsi != null) {
+            sb.append(",\n");
+            for (int i = 0; i < indentLevel + 1; i++) {
+                sb.append("\t");
+            }
+            sb.append("imsi: ").append(imsi);
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEReconfigInd.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEReconfigInd.java
new file mode 100644
index 0000000..3d7fe2e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEReconfigInd.java
@@ -0,0 +1,236 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.ReconfIndReason;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEReconfigInd 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 CRNTI crntiOld = null;
+    private ECGI ecgi = null;
+    private CRNTI crntiNew = null;
+    private ReconfIndReason reconfigCause = null;
+
+    public UEReconfigInd() {
+    }
+
+    public UEReconfigInd(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrntiOld() {
+        return crntiOld;
+    }
+
+    public void setCrntiOld(CRNTI crntiOld) {
+        this.crntiOld = crntiOld;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public CRNTI getCrntiNew() {
+        return crntiNew;
+    }
+
+    public void setCrntiNew(CRNTI crntiNew) {
+        this.crntiNew = crntiNew;
+    }
+
+    public ReconfIndReason getReconfigCause() {
+        return reconfigCause;
+    }
+
+    public void setReconfigCause(ReconfIndReason reconfigCause) {
+        this.reconfigCause = reconfigCause;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += reconfigCause.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 3
+        os.write(0x83);
+        codeLength += 1;
+
+        codeLength += crntiNew.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crntiOld.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crntiOld = new CRNTI();
+            subCodeLength += crntiOld.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            crntiNew = new CRNTI();
+            subCodeLength += crntiNew.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 3)) {
+            reconfigCause = new ReconfIndReason();
+            subCodeLength += reconfigCause.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crntiOld != null) {
+            sb.append("crntiOld: ").append(crntiOld);
+        } else {
+            sb.append("crntiOld: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crntiNew != null) {
+            sb.append("crntiNew: ").append(crntiNew);
+        } else {
+            sb.append("crntiNew: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (reconfigCause != null) {
+            sb.append("reconfigCause: ").append(reconfigCause);
+        } else {
+            sb.append("reconfigCause: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEReleaseInd.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEReleaseInd.java
new file mode 100644
index 0000000..dd4f717
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/UEReleaseInd.java
@@ -0,0 +1,204 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.RelCause;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class UEReleaseInd 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 CRNTI crnti = null;
+    private ECGI ecgi = null;
+    private RelCause releaseCause = null;
+
+    public UEReleaseInd() {
+    }
+
+    public UEReleaseInd(byte[] code) {
+        this.code = code;
+    }
+
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    public RelCause getReleaseCause() {
+        return releaseCause;
+    }
+
+    public void setReleaseCause(RelCause releaseCause) {
+        this.releaseCause = releaseCause;
+    }
+
+    public int encode(BerByteArrayOutputStream os) throws IOException {
+        return encode(os, true);
+    }
+
+    public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+        if (code != null) {
+            for (int i = code.length - 1; i >= 0; i--) {
+                os.write(code[i]);
+            }
+            if (withTag) {
+                return tag.encode(os) + code.length;
+            }
+            return code.length;
+        }
+
+        int codeLength = 0;
+        codeLength += releaseCause.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 2
+        os.write(0x82);
+        codeLength += 1;
+
+        codeLength += ecgi.encode(os, false);
+        // write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+        os.write(0xA1);
+        codeLength += 1;
+
+        codeLength += crnti.encode(os, false);
+        // write tag: CONTEXT_CLASS, PRIMITIVE, 0
+        os.write(0x80);
+        codeLength += 1;
+
+        codeLength += BerLength.encodeLength(os, codeLength);
+
+        if (withTag) {
+            codeLength += tag.encode(os);
+        }
+
+        return codeLength;
+
+    }
+
+    public int decode(InputStream is) throws IOException {
+        return decode(is, true);
+    }
+
+    public int decode(InputStream is, boolean withTag) throws IOException {
+        int codeLength = 0;
+        int subCodeLength = 0;
+        BerTag berTag = new BerTag();
+
+        if (withTag) {
+            codeLength += tag.decodeAndCheck(is);
+        }
+
+        BerLength length = new BerLength();
+        codeLength += length.decode(is);
+
+        int totalLength = length.val;
+        codeLength += totalLength;
+
+        subCodeLength += berTag.decode(is);
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+            crnti = new CRNTI();
+            subCodeLength += crnti.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+            ecgi = new ECGI();
+            subCodeLength += ecgi.decode(is, false);
+            subCodeLength += berTag.decode(is);
+        } else {
+            throw new IOException("Tag does not match the mandatory sequence element tag.");
+        }
+
+        if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 2)) {
+            releaseCause = new RelCause();
+            subCodeLength += releaseCause.decode(is, false);
+            if (subCodeLength == totalLength) {
+                return codeLength;
+            }
+        }
+        throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+
+    }
+
+    public void encodeAndSave(int encodingSizeGuess) throws IOException {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+        encode(os, false);
+        code = os.getArray();
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        appendAsString(sb, 0);
+        return sb.toString();
+    }
+
+    public void appendAsString(StringBuilder sb, int indentLevel) {
+
+        sb.append("{");
+        sb.append("\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (crnti != null) {
+            sb.append("crnti: ").append(crnti);
+        } else {
+            sb.append("crnti: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (ecgi != null) {
+            sb.append("ecgi: ");
+            ecgi.appendAsString(sb, indentLevel + 1);
+        } else {
+            sb.append("ecgi: <empty-required-field>");
+        }
+
+        sb.append(",\n");
+        for (int i = 0; i < indentLevel + 1; i++) {
+            sb.append("\t");
+        }
+        if (releaseCause != null) {
+            sb.append("releaseCause: ").append(releaseCause);
+        } else {
+            sb.append("releaseCause: <empty-required-field>");
+        }
+
+        sb.append("\n");
+        for (int i = 0; i < indentLevel; i++) {
+            sb.append("\t");
+        }
+        sb.append("}");
+    }
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancApiID.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancApiID.java
new file mode 100644
index 0000000..c258f10
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancApiID.java
@@ -0,0 +1,31 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+
+import java.math.BigInteger;
+
+public class XrancApiID extends BerEnum {
+
+	private static final long serialVersionUID = 1L;
+
+	public XrancApiID() {
+	}
+
+	public XrancApiID(byte[] code) {
+		super(code);
+	}
+
+	public XrancApiID(BigInteger value) {
+		super(value);
+	}
+
+	public XrancApiID(long value) {
+		super(value);
+	}
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPdu.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPdu.java
new file mode 100644
index 0000000..2253dd1
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPdu.java
@@ -0,0 +1,179 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class XrancPdu implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private XrancPduHdr hdr = null;
+	private XrancPduBody body = null;
+	
+	public XrancPdu() {
+	}
+
+	public XrancPdu(byte[] code) {
+		this.code = code;
+	}
+
+	public void setHdr(XrancPduHdr hdr) {
+		this.hdr = hdr;
+	}
+
+	public XrancPduHdr getHdr() {
+		return hdr;
+	}
+
+	public void setBody(XrancPduBody body) {
+		this.body = body;
+	}
+
+	public XrancPduBody getBody() {
+		return body;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		int sublength;
+
+		sublength = body.encode(os);
+		codeLength += sublength;
+		codeLength += BerLength.encodeLength(os, sublength);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+		os.write(0xA1);
+		codeLength += 1;
+		
+		codeLength += hdr.encode(os, false);
+		// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+		os.write(0xA0);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			hdr = new XrancPduHdr();
+			subCodeLength += hdr.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			subCodeLength += length.decode(is);
+			body = new XrancPduBody();
+			subCodeLength += body.decode(is, null);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (hdr != null) {
+			sb.append("hdr: ");
+			hdr.appendAsString(sb, indentLevel + 1);
+		}
+		else {
+			sb.append("hdr: <empty-required-field>");
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (body != null) {
+			sb.append("body: ");
+			body.appendAsString(sb, indentLevel + 1);
+		}
+		else {
+			sb.append("body: <empty-required-field>");
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPduBody.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPduBody.java
new file mode 100644
index 0000000..047827e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPduBody.java
@@ -0,0 +1,1099 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class XrancPduBody implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public byte[] code = null;
+	private CellConfigRequest cellConfigRequest = null;
+	private CellConfigReport cellConfigReport = null;
+	private UEAdmissionRequest uEAdmissionRequest = null;
+	private UEAdmissionResponse uEAdmissionResponse = null;
+	private UEAdmissionStatus uEAdmissionStatus = null;
+	private UEContextUpdate uEContextUpdate = null;
+	private UEReconfigInd uEReconfigInd = null;
+	private UEReleaseInd uEReleaseInd = null;
+	private BearerAdmissionRequest bearerAdmissionRequest = null;
+	private BearerAdmissionResponse bearerAdmissionResponse = null;
+	private BearerAdmissionStatus bearerAdmissionStatus = null;
+	private BearerReleaseInd bearerReleaseInd = null;
+	private HORequest hORequest = null;
+	private HOFailure hOFailure = null;
+	private HOComplete hOComplete = null;
+	private RXSigMeasReport rXSigMeasReport = null;
+	private L2MeasConfig l2MeasConfig = null;
+	private RadioMeasReportPerUE radioMeasReportPerUE = null;
+	private RadioMeasReportPerCell radioMeasReportPerCell = null;
+	private SchedMeasReportPerUE schedMeasReportPerUE = null;
+	private SchedMeasReportPerCell schedMeasReportPerCell = null;
+	private PDCPMeasReportPerUe pDCPMeasReportPerUe = null;
+	private UECapabilityEnquiry uECapabilityEnquiry = null;
+	private UECapabilityInfo uECapabilityInfo = null;
+	private ScellAdd scellAdd = null;
+	private ScellAddStatus scellAddStatus = null;
+	private ScellDelete scellDelete = null;
+	private RRMConfig rRMConfig = null;
+	private RRMConfigStatus rRMConfigStatus = null;
+	private SeNBAdd seNBAdd = null;
+	private SeNBAddStatus seNBAddStatus = null;
+	private SeNBDelete seNBDelete = null;
+	private TrafficSplitConfig trafficSplitConfig = null;
+	private HOCause hOCause = null;
+	private RRCMeasConfig rRCMeasConfig = null;
+	
+	public XrancPduBody() {
+	}
+
+	public XrancPduBody(byte[] code) {
+		this.code = code;
+	}
+
+	public void setCellConfigRequest(CellConfigRequest cellConfigRequest) {
+		this.cellConfigRequest = cellConfigRequest;
+	}
+
+	public CellConfigRequest getCellConfigRequest() {
+		return cellConfigRequest;
+	}
+
+	public void setCellConfigReport(CellConfigReport cellConfigReport) {
+		this.cellConfigReport = cellConfigReport;
+	}
+
+	public CellConfigReport getCellConfigReport() {
+		return cellConfigReport;
+	}
+
+	public void setUEAdmissionRequest(UEAdmissionRequest uEAdmissionRequest) {
+		this.uEAdmissionRequest = uEAdmissionRequest;
+	}
+
+	public UEAdmissionRequest getUEAdmissionRequest() {
+		return uEAdmissionRequest;
+	}
+
+	public void setUEAdmissionResponse(UEAdmissionResponse uEAdmissionResponse) {
+		this.uEAdmissionResponse = uEAdmissionResponse;
+	}
+
+	public UEAdmissionResponse getUEAdmissionResponse() {
+		return uEAdmissionResponse;
+	}
+
+	public void setUEAdmissionStatus(UEAdmissionStatus uEAdmissionStatus) {
+		this.uEAdmissionStatus = uEAdmissionStatus;
+	}
+
+	public UEAdmissionStatus getUEAdmissionStatus() {
+		return uEAdmissionStatus;
+	}
+
+	public void setUEContextUpdate(UEContextUpdate uEContextUpdate) {
+		this.uEContextUpdate = uEContextUpdate;
+	}
+
+	public UEContextUpdate getUEContextUpdate() {
+		return uEContextUpdate;
+	}
+
+	public void setUEReconfigInd(UEReconfigInd uEReconfigInd) {
+		this.uEReconfigInd = uEReconfigInd;
+	}
+
+	public UEReconfigInd getUEReconfigInd() {
+		return uEReconfigInd;
+	}
+
+	public void setUEReleaseInd(UEReleaseInd uEReleaseInd) {
+		this.uEReleaseInd = uEReleaseInd;
+	}
+
+	public UEReleaseInd getUEReleaseInd() {
+		return uEReleaseInd;
+	}
+
+	public void setBearerAdmissionRequest(BearerAdmissionRequest bearerAdmissionRequest) {
+		this.bearerAdmissionRequest = bearerAdmissionRequest;
+	}
+
+	public BearerAdmissionRequest getBearerAdmissionRequest() {
+		return bearerAdmissionRequest;
+	}
+
+	public void setBearerAdmissionResponse(BearerAdmissionResponse bearerAdmissionResponse) {
+		this.bearerAdmissionResponse = bearerAdmissionResponse;
+	}
+
+	public BearerAdmissionResponse getBearerAdmissionResponse() {
+		return bearerAdmissionResponse;
+	}
+
+	public void setBearerAdmissionStatus(BearerAdmissionStatus bearerAdmissionStatus) {
+		this.bearerAdmissionStatus = bearerAdmissionStatus;
+	}
+
+	public BearerAdmissionStatus getBearerAdmissionStatus() {
+		return bearerAdmissionStatus;
+	}
+
+	public void setBearerReleaseInd(BearerReleaseInd bearerReleaseInd) {
+		this.bearerReleaseInd = bearerReleaseInd;
+	}
+
+	public BearerReleaseInd getBearerReleaseInd() {
+		return bearerReleaseInd;
+	}
+
+	public void setHORequest(HORequest hORequest) {
+		this.hORequest = hORequest;
+	}
+
+	public HORequest getHORequest() {
+		return hORequest;
+	}
+
+	public void setHOFailure(HOFailure hOFailure) {
+		this.hOFailure = hOFailure;
+	}
+
+	public HOFailure getHOFailure() {
+		return hOFailure;
+	}
+
+	public void setHOComplete(HOComplete hOComplete) {
+		this.hOComplete = hOComplete;
+	}
+
+	public HOComplete getHOComplete() {
+		return hOComplete;
+	}
+
+	public void setRXSigMeasReport(RXSigMeasReport rXSigMeasReport) {
+		this.rXSigMeasReport = rXSigMeasReport;
+	}
+
+	public RXSigMeasReport getRXSigMeasReport() {
+		return rXSigMeasReport;
+	}
+
+	public void setL2MeasConfig(L2MeasConfig l2MeasConfig) {
+		this.l2MeasConfig = l2MeasConfig;
+	}
+
+	public L2MeasConfig getL2MeasConfig() {
+		return l2MeasConfig;
+	}
+
+	public void setRadioMeasReportPerUE(RadioMeasReportPerUE radioMeasReportPerUE) {
+		this.radioMeasReportPerUE = radioMeasReportPerUE;
+	}
+
+	public RadioMeasReportPerUE getRadioMeasReportPerUE() {
+		return radioMeasReportPerUE;
+	}
+
+	public void setRadioMeasReportPerCell(RadioMeasReportPerCell radioMeasReportPerCell) {
+		this.radioMeasReportPerCell = radioMeasReportPerCell;
+	}
+
+	public RadioMeasReportPerCell getRadioMeasReportPerCell() {
+		return radioMeasReportPerCell;
+	}
+
+	public void setSchedMeasReportPerUE(SchedMeasReportPerUE schedMeasReportPerUE) {
+		this.schedMeasReportPerUE = schedMeasReportPerUE;
+	}
+
+	public SchedMeasReportPerUE getSchedMeasReportPerUE() {
+		return schedMeasReportPerUE;
+	}
+
+	public void setSchedMeasReportPerCell(SchedMeasReportPerCell schedMeasReportPerCell) {
+		this.schedMeasReportPerCell = schedMeasReportPerCell;
+	}
+
+	public SchedMeasReportPerCell getSchedMeasReportPerCell() {
+		return schedMeasReportPerCell;
+	}
+
+	public void setPDCPMeasReportPerUe(PDCPMeasReportPerUe pDCPMeasReportPerUe) {
+		this.pDCPMeasReportPerUe = pDCPMeasReportPerUe;
+	}
+
+	public PDCPMeasReportPerUe getPDCPMeasReportPerUe() {
+		return pDCPMeasReportPerUe;
+	}
+
+	public void setUECapabilityEnquiry(UECapabilityEnquiry uECapabilityEnquiry) {
+		this.uECapabilityEnquiry = uECapabilityEnquiry;
+	}
+
+	public UECapabilityEnquiry getUECapabilityEnquiry() {
+		return uECapabilityEnquiry;
+	}
+
+	public void setUECapabilityInfo(UECapabilityInfo uECapabilityInfo) {
+		this.uECapabilityInfo = uECapabilityInfo;
+	}
+
+	public UECapabilityInfo getUECapabilityInfo() {
+		return uECapabilityInfo;
+	}
+
+	public void setScellAdd(ScellAdd scellAdd) {
+		this.scellAdd = scellAdd;
+	}
+
+	public ScellAdd getScellAdd() {
+		return scellAdd;
+	}
+
+	public void setScellAddStatus(ScellAddStatus scellAddStatus) {
+		this.scellAddStatus = scellAddStatus;
+	}
+
+	public ScellAddStatus getScellAddStatus() {
+		return scellAddStatus;
+	}
+
+	public void setScellDelete(ScellDelete scellDelete) {
+		this.scellDelete = scellDelete;
+	}
+
+	public ScellDelete getScellDelete() {
+		return scellDelete;
+	}
+
+	public void setRRMConfig(RRMConfig rRMConfig) {
+		this.rRMConfig = rRMConfig;
+	}
+
+	public RRMConfig getRRMConfig() {
+		return rRMConfig;
+	}
+
+	public void setRRMConfigStatus(RRMConfigStatus rRMConfigStatus) {
+		this.rRMConfigStatus = rRMConfigStatus;
+	}
+
+	public RRMConfigStatus getRRMConfigStatus() {
+		return rRMConfigStatus;
+	}
+
+	public void setSeNBAdd(SeNBAdd seNBAdd) {
+		this.seNBAdd = seNBAdd;
+	}
+
+	public SeNBAdd getSeNBAdd() {
+		return seNBAdd;
+	}
+
+	public void setSeNBAddStatus(SeNBAddStatus seNBAddStatus) {
+		this.seNBAddStatus = seNBAddStatus;
+	}
+
+	public SeNBAddStatus getSeNBAddStatus() {
+		return seNBAddStatus;
+	}
+
+	public void setSeNBDelete(SeNBDelete seNBDelete) {
+		this.seNBDelete = seNBDelete;
+	}
+
+	public SeNBDelete getSeNBDelete() {
+		return seNBDelete;
+	}
+
+	public void setTrafficSplitConfig(TrafficSplitConfig trafficSplitConfig) {
+		this.trafficSplitConfig = trafficSplitConfig;
+	}
+
+	public TrafficSplitConfig getTrafficSplitConfig() {
+		return trafficSplitConfig;
+	}
+
+	public void setHOCause(HOCause hOCause) {
+		this.hOCause = hOCause;
+	}
+
+	public HOCause getHOCause() {
+		return hOCause;
+	}
+
+	public void setRRCMeasConfig(RRCMeasConfig rRCMeasConfig) {
+		this.rRCMeasConfig = rRCMeasConfig;
+	}
+
+	public RRCMeasConfig getRRCMeasConfig() {
+		return rRCMeasConfig;
+	}
+
+	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 (rRCMeasConfig != null) {
+			codeLength += rRCMeasConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 34
+			os.write(0x22);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (hOCause != null) {
+			codeLength += hOCause.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 33
+			os.write(0x21);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (trafficSplitConfig != null) {
+			codeLength += trafficSplitConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 32
+			os.write(0x20);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (seNBDelete != null) {
+			codeLength += seNBDelete.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 31
+			os.write(0x1F);
+			os.write(0xBF);
+			codeLength += 2;
+			return codeLength;
+		}
+		
+		if (seNBAddStatus != null) {
+			codeLength += seNBAddStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 30
+			os.write(0xBE);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (seNBAdd != null) {
+			codeLength += seNBAdd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 29
+			os.write(0xBD);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (rRMConfigStatus != null) {
+			codeLength += rRMConfigStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 28
+			os.write(0xBC);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (rRMConfig != null) {
+			codeLength += rRMConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 27
+			os.write(0xBB);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (scellDelete != null) {
+			codeLength += scellDelete.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 26
+			os.write(0xBA);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (scellAddStatus != null) {
+			codeLength += scellAddStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 25
+			os.write(0xB9);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (scellAdd != null) {
+			codeLength += scellAdd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 24
+			os.write(0xB8);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uECapabilityInfo != null) {
+			codeLength += uECapabilityInfo.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 23
+			os.write(0xB7);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uECapabilityEnquiry != null) {
+			codeLength += uECapabilityEnquiry.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 22
+			os.write(0xB6);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (pDCPMeasReportPerUe != null) {
+			codeLength += pDCPMeasReportPerUe.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 21
+			os.write(0xB5);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (schedMeasReportPerCell != null) {
+			codeLength += schedMeasReportPerCell.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 20
+			os.write(0xB4);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (schedMeasReportPerUE != null) {
+			codeLength += schedMeasReportPerUE.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 19
+			os.write(0xB3);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (radioMeasReportPerCell != null) {
+			codeLength += radioMeasReportPerCell.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 18
+			os.write(0xB2);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (radioMeasReportPerUE != null) {
+			codeLength += radioMeasReportPerUE.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 17
+			os.write(0xB1);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (l2MeasConfig != null) {
+			codeLength += l2MeasConfig.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 16
+			os.write(0xB0);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (rXSigMeasReport != null) {
+			codeLength += rXSigMeasReport.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 15
+			os.write(0xAF);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (hOComplete != null) {
+			codeLength += hOComplete.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 14
+			os.write(0xAE);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (hOFailure != null) {
+			codeLength += hOFailure.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 13
+			os.write(0xAD);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (hORequest != null) {
+			codeLength += hORequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 12
+			os.write(0xAC);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerReleaseInd != null) {
+			codeLength += bearerReleaseInd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 11
+			os.write(0xAB);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerAdmissionStatus != null) {
+			codeLength += bearerAdmissionStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 10
+			os.write(0xAA);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerAdmissionResponse != null) {
+			codeLength += bearerAdmissionResponse.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 9
+			os.write(0xA9);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (bearerAdmissionRequest != null) {
+			codeLength += bearerAdmissionRequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 8
+			os.write(0xA8);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEReleaseInd != null) {
+			codeLength += uEReleaseInd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 7
+			os.write(0xA7);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEReconfigInd != null) {
+			codeLength += uEReconfigInd.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 6
+			os.write(0xA6);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEContextUpdate != null) {
+			codeLength += uEContextUpdate.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 5
+			os.write(0xA5);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEAdmissionStatus != null) {
+			codeLength += uEAdmissionStatus.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 4
+			os.write(0xA4);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEAdmissionResponse != null) {
+			codeLength += uEAdmissionResponse.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 3
+			os.write(0xA3);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (uEAdmissionRequest != null) {
+			codeLength += uEAdmissionRequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 2
+			os.write(0xA2);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (cellConfigReport != null) {
+			codeLength += cellConfigReport.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 1
+			os.write(0xA1);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		if (cellConfigRequest != null) {
+			codeLength += cellConfigRequest.encode(os, false);
+			// write tag: CONTEXT_CLASS, CONSTRUCTED, 0
+			os.write(0xA0);
+			codeLength += 1;
+			return codeLength;
+		}
+		
+		throw new IOException("Error encoding CHOICE: No element of CHOICE was selected.");
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, null);
+	}
+
+	public int decode(InputStream is, BerTag berTag) throws IOException {
+
+		int codeLength = 0;
+		BerTag passedTag = berTag;
+
+		if (berTag == null) {
+			berTag = new BerTag();
+			codeLength += berTag.decode(is);
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 0)) {
+			cellConfigRequest = new CellConfigRequest();
+			codeLength += cellConfigRequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 1)) {
+			cellConfigReport = new CellConfigReport();
+			codeLength += cellConfigReport.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 2)) {
+			uEAdmissionRequest = new UEAdmissionRequest();
+			codeLength += uEAdmissionRequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 3)) {
+			uEAdmissionResponse = new UEAdmissionResponse();
+			codeLength += uEAdmissionResponse.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 4)) {
+			uEAdmissionStatus = new UEAdmissionStatus();
+			codeLength += uEAdmissionStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 5)) {
+			uEContextUpdate = new UEContextUpdate();
+			codeLength += uEContextUpdate.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 6)) {
+			uEReconfigInd = new UEReconfigInd();
+			codeLength += uEReconfigInd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 7)) {
+			uEReleaseInd = new UEReleaseInd();
+			codeLength += uEReleaseInd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 8)) {
+			bearerAdmissionRequest = new BearerAdmissionRequest();
+			codeLength += bearerAdmissionRequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 9)) {
+			bearerAdmissionResponse = new BearerAdmissionResponse();
+			codeLength += bearerAdmissionResponse.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 10)) {
+			bearerAdmissionStatus = new BearerAdmissionStatus();
+			codeLength += bearerAdmissionStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 11)) {
+			bearerReleaseInd = new BearerReleaseInd();
+			codeLength += bearerReleaseInd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 12)) {
+			hORequest = new HORequest();
+			codeLength += hORequest.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 13)) {
+			hOFailure = new HOFailure();
+			codeLength += hOFailure.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 14)) {
+			hOComplete = new HOComplete();
+			codeLength += hOComplete.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 15)) {
+			rXSigMeasReport = new RXSigMeasReport();
+			codeLength += rXSigMeasReport.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 16)) {
+			l2MeasConfig = new L2MeasConfig();
+			codeLength += l2MeasConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 17)) {
+			radioMeasReportPerUE = new RadioMeasReportPerUE();
+			codeLength += radioMeasReportPerUE.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 18)) {
+			radioMeasReportPerCell = new RadioMeasReportPerCell();
+			codeLength += radioMeasReportPerCell.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 19)) {
+			schedMeasReportPerUE = new SchedMeasReportPerUE();
+			codeLength += schedMeasReportPerUE.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 20)) {
+			schedMeasReportPerCell = new SchedMeasReportPerCell();
+			codeLength += schedMeasReportPerCell.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 21)) {
+			pDCPMeasReportPerUe = new PDCPMeasReportPerUe();
+			codeLength += pDCPMeasReportPerUe.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 22)) {
+			uECapabilityEnquiry = new UECapabilityEnquiry();
+			codeLength += uECapabilityEnquiry.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 23)) {
+			uECapabilityInfo = new UECapabilityInfo();
+			codeLength += uECapabilityInfo.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 24)) {
+			scellAdd = new ScellAdd();
+			codeLength += scellAdd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 25)) {
+			scellAddStatus = new ScellAddStatus();
+			codeLength += scellAddStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 26)) {
+			scellDelete = new ScellDelete();
+			codeLength += scellDelete.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 27)) {
+			rRMConfig = new RRMConfig();
+			codeLength += rRMConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 28)) {
+			rRMConfigStatus = new RRMConfigStatus();
+			codeLength += rRMConfigStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 29)) {
+			seNBAdd = new SeNBAdd();
+			codeLength += seNBAdd.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 30)) {
+			seNBAddStatus = new SeNBAddStatus();
+			codeLength += seNBAddStatus.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 31)) {
+			seNBDelete = new SeNBDelete();
+			codeLength += seNBDelete.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 32)) {
+			trafficSplitConfig = new TrafficSplitConfig();
+			codeLength += trafficSplitConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 33)) {
+			hOCause = new HOCause();
+			codeLength += hOCause.decode(is, false);
+			return codeLength;
+		}
+
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.CONSTRUCTED, 34)) {
+			rRCMeasConfig = new RRCMeasConfig();
+			codeLength += rRCMeasConfig.decode(is, false);
+			return codeLength;
+		}
+
+		if (passedTag != null) {
+			return 0;
+		}
+
+		throw new IOException("Error decoding CHOICE: Tag " + berTag + " matched to no item.");
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		if (cellConfigRequest != null) {
+			sb.append("cellConfigRequest: ");
+			cellConfigRequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (cellConfigReport != null) {
+			sb.append("cellConfigReport: ");
+			cellConfigReport.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEAdmissionRequest != null) {
+			sb.append("uEAdmissionRequest: ");
+			uEAdmissionRequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEAdmissionResponse != null) {
+			sb.append("uEAdmissionResponse: ");
+			uEAdmissionResponse.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEAdmissionStatus != null) {
+			sb.append("uEAdmissionStatus: ");
+			uEAdmissionStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEContextUpdate != null) {
+			sb.append("uEContextUpdate: ");
+			uEContextUpdate.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEReconfigInd != null) {
+			sb.append("uEReconfigInd: ");
+			uEReconfigInd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uEReleaseInd != null) {
+			sb.append("uEReleaseInd: ");
+			uEReleaseInd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerAdmissionRequest != null) {
+			sb.append("bearerAdmissionRequest: ");
+			bearerAdmissionRequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerAdmissionResponse != null) {
+			sb.append("bearerAdmissionResponse: ");
+			bearerAdmissionResponse.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerAdmissionStatus != null) {
+			sb.append("bearerAdmissionStatus: ");
+			bearerAdmissionStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (bearerReleaseInd != null) {
+			sb.append("bearerReleaseInd: ");
+			bearerReleaseInd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (hORequest != null) {
+			sb.append("hORequest: ");
+			hORequest.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (hOFailure != null) {
+			sb.append("hOFailure: ");
+			hOFailure.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (hOComplete != null) {
+			sb.append("hOComplete: ");
+			hOComplete.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rXSigMeasReport != null) {
+			sb.append("rXSigMeasReport: ");
+			rXSigMeasReport.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (l2MeasConfig != null) {
+			sb.append("l2MeasConfig: ");
+			l2MeasConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (radioMeasReportPerUE != null) {
+			sb.append("radioMeasReportPerUE: ");
+			radioMeasReportPerUE.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (radioMeasReportPerCell != null) {
+			sb.append("radioMeasReportPerCell: ");
+			radioMeasReportPerCell.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (schedMeasReportPerUE != null) {
+			sb.append("schedMeasReportPerUE: ");
+			schedMeasReportPerUE.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (schedMeasReportPerCell != null) {
+			sb.append("schedMeasReportPerCell: ");
+			schedMeasReportPerCell.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (pDCPMeasReportPerUe != null) {
+			sb.append("pDCPMeasReportPerUe: ");
+			pDCPMeasReportPerUe.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uECapabilityEnquiry != null) {
+			sb.append("uECapabilityEnquiry: ");
+			uECapabilityEnquiry.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (uECapabilityInfo != null) {
+			sb.append("uECapabilityInfo: ");
+			uECapabilityInfo.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (scellAdd != null) {
+			sb.append("scellAdd: ");
+			scellAdd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (scellAddStatus != null) {
+			sb.append("scellAddStatus: ");
+			scellAddStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (scellDelete != null) {
+			sb.append("scellDelete: ");
+			scellDelete.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rRMConfig != null) {
+			sb.append("rRMConfig: ");
+			rRMConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rRMConfigStatus != null) {
+			sb.append("rRMConfigStatus: ");
+			rRMConfigStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (seNBAdd != null) {
+			sb.append("seNBAdd: ");
+			seNBAdd.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (seNBAddStatus != null) {
+			sb.append("seNBAddStatus: ");
+			seNBAddStatus.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (seNBDelete != null) {
+			sb.append("seNBDelete: ");
+			seNBDelete.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (trafficSplitConfig != null) {
+			sb.append("trafficSplitConfig: ");
+			trafficSplitConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (hOCause != null) {
+			sb.append("hOCause: ");
+			hOCause.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		if (rRCMeasConfig != null) {
+			sb.append("rRCMeasConfig: ");
+			rRCMeasConfig.appendAsString(sb, indentLevel + 1);
+			return;
+		}
+
+		sb.append("<none>");
+	}
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPduHdr.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPduHdr.java
new file mode 100644
index 0000000..49390fe
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/pdu/XrancPduHdr.java
@@ -0,0 +1,173 @@
+/**
+ * This class file was automatically generated by jASN1 v1.8.2 (http://www.openmuc.org)
+ */
+
+package org.onosproject.xran.asn1lib.pdu;
+
+
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.BerLength;
+import org.onosproject.xran.asn1lib.ber.BerTag;
+import org.onosproject.xran.asn1lib.ber.types.string.BerUTF8String;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+public class XrancPduHdr implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	public static final BerTag tag = new BerTag(BerTag.UNIVERSAL_CLASS, BerTag.CONSTRUCTED, 16);
+
+	public byte[] code = null;
+	private BerUTF8String ver = null;
+	private XrancApiID apiId = null;
+	
+	public XrancPduHdr() {
+	}
+
+	public XrancPduHdr(byte[] code) {
+		this.code = code;
+	}
+
+	public void setVer(BerUTF8String ver) {
+		this.ver = ver;
+	}
+
+	public BerUTF8String getVer() {
+		return ver;
+	}
+
+	public void setApiId(XrancApiID apiId) {
+		this.apiId = apiId;
+	}
+
+	public XrancApiID getApiId() {
+		return apiId;
+	}
+
+	public int encode(BerByteArrayOutputStream os) throws IOException {
+		return encode(os, true);
+	}
+
+	public int encode(BerByteArrayOutputStream os, boolean withTag) throws IOException {
+
+		if (code != null) {
+			for (int i = code.length - 1; i >= 0; i--) {
+				os.write(code[i]);
+			}
+			if (withTag) {
+				return tag.encode(os) + code.length;
+			}
+			return code.length;
+		}
+
+		int codeLength = 0;
+		codeLength += apiId.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 1
+		os.write(0x81);
+		codeLength += 1;
+		
+		codeLength += ver.encode(os, false);
+		// write tag: CONTEXT_CLASS, PRIMITIVE, 0
+		os.write(0x80);
+		codeLength += 1;
+		
+		codeLength += BerLength.encodeLength(os, codeLength);
+
+		if (withTag) {
+			codeLength += tag.encode(os);
+		}
+
+		return codeLength;
+
+	}
+
+	public int decode(InputStream is) throws IOException {
+		return decode(is, true);
+	}
+
+	public int decode(InputStream is, boolean withTag) throws IOException {
+		int codeLength = 0;
+		int subCodeLength = 0;
+		BerTag berTag = new BerTag();
+
+		if (withTag) {
+			codeLength += tag.decodeAndCheck(is);
+		}
+
+		BerLength length = new BerLength();
+		codeLength += length.decode(is);
+
+		int totalLength = length.val;
+		codeLength += totalLength;
+
+		subCodeLength += berTag.decode(is);
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 0)) {
+			ver = new BerUTF8String();
+			subCodeLength += ver.decode(is, false);
+			subCodeLength += berTag.decode(is);
+		}
+		else {
+			throw new IOException("Tag does not match the mandatory sequence element tag.");
+		}
+		
+		if (berTag.equals(BerTag.CONTEXT_CLASS, BerTag.PRIMITIVE, 1)) {
+			apiId = new XrancApiID();
+			subCodeLength += apiId.decode(is, false);
+			if (subCodeLength == totalLength) {
+				return codeLength;
+			}
+		}
+		throw new IOException("Unexpected end of sequence, length tag: " + totalLength + ", actual sequence length: " + subCodeLength);
+
+		
+	}
+
+	public void encodeAndSave(int encodingSizeGuess) throws IOException {
+		BerByteArrayOutputStream os = new BerByteArrayOutputStream(encodingSizeGuess);
+		encode(os, false);
+		code = os.getArray();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		appendAsString(sb, 0);
+		return sb.toString();
+	}
+
+	public void appendAsString(StringBuilder sb, int indentLevel) {
+
+		sb.append("{");
+		sb.append("\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (ver != null) {
+			sb.append("ver: ").append(ver);
+		}
+		else {
+			sb.append("ver: <empty-required-field>");
+		}
+		
+		sb.append(",\n");
+		for (int i = 0; i < indentLevel + 1; i++) {
+			sb.append("\t");
+		}
+		if (apiId != null) {
+			sb.append("apiId: ").append(apiId);
+		}
+		else {
+			sb.append("apiId: <empty-required-field>");
+		}
+		
+		sb.append("\n");
+		for (int i = 0; i < indentLevel; i++) {
+			sb.append("\t");
+		}
+		sb.append("}");
+	}
+
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/asn1lib/util/HexConverter.java b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/util/HexConverter.java
new file mode 100644
index 0000000..573598f
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/asn1lib/util/HexConverter.java
@@ -0,0 +1,155 @@
+package org.onosproject.xran.asn1lib.util;
+
+public class HexConverter {
+
+    public static String toHexString(byte b) {
+        StringBuilder builder = new StringBuilder();
+        appendHexString(b, builder);
+        return builder.toString();
+    }
+
+    public static String toHexString(byte[] bytes) {
+        return toHexString(bytes, 0, bytes.length);
+    }
+
+    public static String toHexString(byte[] bytes, int offset, int length) {
+        StringBuilder builder = new StringBuilder();
+
+        int l = 1;
+        for (int i = offset; i < (offset + length); i++) {
+            if ((l != 1) && ((l - 1) % 8 == 0)) {
+                builder.append(' ');
+            }
+            if ((l != 1) && ((l - 1) % 16 == 0)) {
+                builder.append('\n');
+            }
+            l++;
+            appendHexString(bytes[i], builder);
+            if (i != offset + length - 1) {
+                builder.append(' ');
+            }
+        }
+
+        return builder.toString();
+    }
+
+    /**
+     * Returns the integer value as hex string filled with leading zeros. If you do not want leading zeros use
+     * Integer.toHexString(int i) instead.
+     * 
+     * @param i
+     *            the integer value to be converted
+     * @return the hex string
+     */
+    public static String toShortHexString(int i) {
+        byte[] bytes = new byte[] { (byte) (i >> 24), (byte) (i >> 16), (byte) (i >> 8), (byte) (i) };
+        return toShortHexString(bytes);
+    }
+
+    /**
+     * Returns the long value as hex string filled with leading zeros. If you do not want leading zeros use
+     * Long.toHexString(long i) instead.
+     * 
+     * @param l
+     *            the long value to be converted
+     * @return the hex string
+     */
+    public static String toShortHexString(long l) {
+        byte[] bytes = new byte[] { (byte) (l >> 56), (byte) (l >> 48), (byte) (l >> 40), (byte) (l >> 32),
+                (byte) (l >> 24), (byte) (l >> 16), (byte) (l >> 8), (byte) (l) };
+        return toShortHexString(bytes);
+    }
+
+    /**
+     * Returns the byte as a hex string. If b is less than 16 the hex string returned contains a leading zero.
+     * 
+     * @param b
+     *            the byte to be converted
+     * @return the byte as a hex string.
+     */
+    public static String toShortHexString(byte b) {
+        return toShortHexString(new byte[] { b });
+    }
+
+    private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
+
+    public static String toShortHexString(byte[] bytes) {
+        return toShortHexString(bytes, 0, bytes.length);
+    }
+
+    public static String toShortHexString(byte[] bytes, int offset, int length) {
+        char[] hexChars = new char[length * 2];
+        for (int j = offset; j < (offset + length); j++) {
+            int v = bytes[j] & 0xff;
+            hexChars[j * 2] = hexArray[v >>> 4];
+            hexChars[j * 2 + 1] = hexArray[v & 0x0f];
+        }
+        return new String(hexChars);
+    }
+
+    public static byte[] fromShortHexString(String shortHexString) throws NumberFormatException {
+
+        validate(shortHexString);
+
+        int length = shortHexString.length();
+
+        byte[] data = new byte[length / 2];
+        for (int i = 0; i < length; i += 2) {
+            int firstCharacter = Character.digit(shortHexString.charAt(i), 16);
+            int secondCharacter = Character.digit(shortHexString.charAt(i + 1), 16);
+
+            if (firstCharacter == -1 || secondCharacter == -1) {
+                throw new NumberFormatException("string is not a legal hex string.");
+            }
+
+            data[i / 2] = (byte) ((firstCharacter << 4) + secondCharacter);
+        }
+        return data;
+    }
+
+    public static void appendShortHexString(byte b, StringBuilder builder) {
+        builder.append(toShortHexString(b));
+    }
+
+    public static void appendShortHexString(StringBuilder builder, byte[] bytes, int offset, int length) {
+        builder.append(toShortHexString(bytes, offset, length));
+    }
+
+    public static void appendHexString(byte b, StringBuilder builder) {
+        builder.append("0x");
+        appendShortHexString(b, builder);
+    }
+
+    public static void appendHexString(StringBuilder builder, byte[] byteArray, int offset, int length) {
+        int l = 1;
+        for (int i = offset; i < (offset + length); i++) {
+            if ((l != 1) && ((l - 1) % 8 == 0)) {
+                builder.append(' ');
+            }
+            if ((l != 1) && ((l - 1) % 16 == 0)) {
+                builder.append('\n');
+            }
+            l++;
+            appendHexString(byteArray[i], builder);
+            if (i != offset + length - 1) {
+                builder.append(' ');
+            }
+        }
+    }
+
+    private static void validate(String s) {
+        if (s == null) {
+            throw new IllegalArgumentException("string s may not be null");
+        }
+
+        if ((s.length() == 0) || ((s.length() % 2) != 0)) {
+            throw new NumberFormatException("string is not a legal hex string.");
+        }
+    }
+
+    /**
+     * Don't let anyone instantiate this class.
+     */
+    private HexConverter() {
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java b/apps/xran/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
new file mode 100644
index 0000000..14b93af
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/DefaultXranStore.java
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import com.google.common.collect.Lists;
+import io.netty.channel.ChannelHandlerContext;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.xran.XranService;
+import org.onosproject.xran.XranStore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.EUTRANCellIdentifier;
+import org.onosproject.xran.asn1lib.api.PCIARFCN;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.onosproject.xran.impl.entities.RnibLink;
+import org.onosproject.xran.impl.entities.RnibSlice;
+import org.onosproject.xran.impl.entities.RnibUe;
+import org.onosproject.xran.impl.identifiers.EcgiCrntiPair;
+import org.onosproject.xran.impl.identifiers.LinkId;
+import org.slf4j.Logger;
+
+import javax.xml.bind.DatatypeConverter;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.stream.Collectors;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Default xran store.
+ */
+@Component(immediate = true)
+@Service
+public class DefaultXranStore extends AbstractStore implements XranStore {
+    private static final String XRAN_APP_ID = "org.onosproject.xran";
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    protected ConcurrentMap<LinkId, RnibLink> linkMap = new ConcurrentHashMap<>();
+    private ConcurrentMap<ECGI, RnibCell> cellMap = new ConcurrentHashMap<>();
+    private ConcurrentMap<Long, RnibUe> ueMap = new ConcurrentHashMap<>();
+    private ConcurrentMap<Object, RnibSlice> sliceMap = new ConcurrentHashMap<>();
+
+    private XranService controller;
+    private IdGenerator ueIdGenerator;
+
+    // map to get the context channel based on ecgi
+    private ConcurrentMap<ECGI, ChannelHandlerContext> ctxMap = new ConcurrentHashMap<>();
+    // pci-arfcn to ecgi bimap
+    private BiMap<PCIARFCN, ECGI> pciarfcnMap = HashBiMap.create();
+    // ECGI, CRNTI pair of primary cell for specified UE.
+    private BiMap<EcgiCrntiPair, Long> crntiMap = HashBiMap.create();
+
+
+    @Activate
+    public void activate() {
+        ApplicationId appId = coreService.getAppId(XRAN_APP_ID);
+
+        // create ue id generator
+        ueIdGenerator = coreService.getIdGenerator("xran-ue-id");
+
+        log.info("XRAN Default Store Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        linkMap.clear();
+        cellMap.clear();
+        ueMap.clear();
+        sliceMap.clear();
+
+        controller = null;
+        ueIdGenerator = null;
+
+        log.info("XRAN Default Store Stopped");
+    }
+
+    @Override
+    public List<RnibLink> getLinks() {
+        List<RnibLink> list = Lists.newArrayList();
+        list.addAll(linkMap.values());
+        return list;
+    }
+
+    @Override
+    public List<RnibLink> getLinks(ECGI ecgi) {
+        List<RnibLink> list = Lists.newArrayList();
+        list.addAll(
+                linkMap.keySet()
+                        .stream()
+                        .filter(k -> k.getEcgi().equals(ecgi))
+                        .map(v -> linkMap.get(v))
+                        .collect(Collectors.toList()));
+        return list;
+    }
+
+    @Override
+    public List<RnibLink> getLinks(String eciHex) {
+        List<RnibLink> list = Lists.newArrayList();
+        EUTRANCellIdentifier eci = hexToEci(eciHex);
+
+        list.addAll(
+                linkMap.keySet()
+                        .stream()
+                        .filter(k -> k.getEcgi().getEUTRANcellIdentifier().equals(eci))
+                        .map(v -> linkMap.get(v))
+                        .collect(Collectors.toList()));
+
+        return list;
+    }
+
+    @Override
+    public List<RnibLink> getLinks(long euId) {
+        List<RnibLink> list = Lists.newArrayList();
+
+        list.addAll(
+                linkMap.keySet()
+                        .stream()
+                        .filter(k -> k.getUeId().equals(euId))
+                        .map(v -> linkMap.get(v))
+                        .collect(Collectors.toList()));
+
+        return list;
+    }
+
+
+    @Override
+    public Optional<RnibLink> getLink(String eciHex, long euId) {
+        EUTRANCellIdentifier eci = hexToEci(eciHex);
+
+        Optional<LinkId> first = linkMap.keySet()
+                .stream()
+                .filter(linkId -> linkId.getEcgi().getEUTRANcellIdentifier().equals(eci) &&
+                        linkId.getUeId().equals(euId))
+                .findFirst();
+
+        return first.map(linkId -> linkMap.get(linkId));
+    }
+
+    @Override
+    public void storeLink(RnibLink link) {
+        synchronized (this) {
+            if (link.getLinkId() != null) {
+                // if we add a primary link then change the primary to non serving
+                if (link.getType().equals(RnibLink.Type.SERVING_PRIMARY)) {
+                    RnibUe ue = link.getLinkId().getUe();
+                    getLinks(ue.getId())
+                            .stream()
+                            .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
+                            .forEach(l -> l.setType(RnibLink.Type.NON_SERVING));
+                }
+                linkMap.put(link.getLinkId(), link);
+            }
+        }
+    }
+
+    @Override
+    public boolean removeLink(LinkId link) {
+        return linkMap.remove(link) != null;
+    }
+
+    @Override
+    public Optional<RnibLink> getLink(ECGI ecgi, Long ueId) {
+        LinkId linkId = LinkId.valueOf(ecgi, ueId);
+        return Optional.ofNullable(linkMap.get(linkId));
+    }
+
+    @Override
+    public Optional<RnibLink> getLink(ECGI src, CRNTI dst) {
+        return getUe(src, dst).flatMap(ue -> getLink(src, ue.getId()));
+    }
+
+    @Override
+    public void modifyLinkRrmConf(RnibLink link, JsonNode rrmConf) {
+        link.modifyRrmParameters(rrmConf);
+    }
+
+    @Override
+    public List<Object> getNodes() {
+        List<Object> list = Lists.newArrayList();
+        list.addAll(cellMap.values());
+        list.addAll(ueMap.values());
+        return list;
+    }
+
+    @Override
+    public List<RnibCell> getCellNodes() {
+        List<RnibCell> list = Lists.newArrayList();
+        list.addAll(cellMap.values());
+        return list;
+    }
+
+    @Override
+    public List<RnibUe> getUeNodes() {
+        List<RnibUe> list = Lists.newArrayList();
+        list.addAll(ueMap.values());
+        return list;
+    }
+
+    @Override
+    public Optional<Object> getNode(String nodeId) {
+        try {
+            return Optional.ofNullable(getCell(nodeId));
+        } catch (Exception ignored) {
+        }
+        return Optional.ofNullable(getUe(Long.parseLong(nodeId)));
+    }
+
+    @Override
+    public void storeCell(RnibCell cell) {
+        if (cell.getEcgi() != null) {
+            cellMap.putIfAbsent(cell.getEcgi(), cell);
+        }
+    }
+
+    @Override
+    public boolean removeCell(ECGI ecgi) {
+        pciarfcnMap.inverse().remove(ecgi);
+        ctxMap.remove(ecgi);
+        return cellMap.remove(ecgi) != null;
+    }
+
+    @Override
+    public boolean removeCell(PCIARFCN pciarfcn) {
+        return removeCell(pciarfcnMap.get(pciarfcn));
+    }
+
+    @Override
+    public Optional<RnibCell> getCell(String hexeci) {
+        EUTRANCellIdentifier eci = hexToEci(hexeci);
+        Optional<ECGI> first = cellMap.keySet()
+                .stream()
+                .filter(ecgi -> ecgi.getEUTRANcellIdentifier().equals(eci))
+                .findFirst();
+        return first.map(ecgi -> cellMap.get(ecgi));
+    }
+
+    @Override
+    public Optional<RnibCell> getCell(ECGI ecgi) {
+        return Optional.ofNullable(cellMap.get(ecgi));
+    }
+
+    @Override
+    public Optional<RnibCell> getCell(PCIARFCN id) {
+        ECGI ecgi;
+        ecgi = pciarfcnMap.get(id);
+        return getCell(ecgi);
+    }
+
+    @Override
+    public void modifyCellRrmConf(RnibCell cell, JsonNode rrmConf) throws Exception {
+        List<RnibLink> linkList = getLinks(cell.getEcgi());
+        List<RnibUe> ueList = linkList.stream()
+                .map(link -> link.getLinkId().getUe())
+                .collect(Collectors.toList());
+
+        cell.modifyRrmConfig(rrmConf, ueList);
+    }
+
+    @Override
+    public Optional<RnibSlice> getSlice(long sliceId) {
+        return Optional.ofNullable(sliceMap.get(sliceId));
+    }
+
+    @Override
+    public boolean createSlice(ObjectNode attributes) {
+        return false;
+    }
+
+    @Override
+    public boolean removeCell(long sliceId) {
+        return sliceMap.remove(sliceId) != null;
+    }
+
+    @Override
+    public Optional<XranService> getController() {
+        return Optional.ofNullable(controller);
+    }
+
+    @Override
+    public void setController(XranService controller) {
+        this.controller = controller;
+    }
+
+    @Override
+    public void storeUe(RnibUe ue) {
+        long newId;
+        if (ue.getId() == null) {
+            newId = ueIdGenerator.getNewId();
+            ue.setId(newId);
+        } else {
+            newId = ue.getId();
+        }
+        ueMap.put(newId, ue);
+    }
+
+    @Override
+    public void storeUe(RnibCell cell, RnibUe ue) {
+        storeUe(ue);
+        storeCrnti(cell, ue);
+    }
+
+    @Override
+    public boolean removeUe(long ueId) {
+        log.info("removing ue {} {}", ueId, ueMap);
+        crntiMap.inverse().remove(ueId);
+        return ueMap.remove(ueId) != null;
+    }
+
+    @Override
+    public void storePciArfcn(RnibCell value) {
+        value.getOptConf().ifPresent(cfg -> {
+            PCIARFCN pciarfcn = new PCIARFCN();
+            pciarfcn.setPci(cfg.getPci());
+            pciarfcn.setEarfcnDl(cfg.getEarfcnDl());
+            pciarfcnMap.put(pciarfcn, value.getEcgi());
+        });
+    }
+
+    @Override
+    public void storeCtx(RnibCell value, ChannelHandlerContext ctx) {
+        if (value.getEcgi() != null) {
+            ctxMap.put(value.getEcgi(), ctx);
+            storeCell(value);
+        }
+    }
+
+    @Override
+    public Optional<ChannelHandlerContext> getCtx(ECGI ecgi) {
+        return Optional.ofNullable(ctxMap.get(ecgi));
+    }
+
+    @Override
+    public BiMap<EcgiCrntiPair, Long> getCrnti() {
+        return crntiMap;
+    }
+
+    @Override
+    public void storeCrnti(RnibCell cell, RnibUe ue) {
+        CRNTI crnti = ue.getCrnti();
+        ECGI ecgi = cell.getEcgi();
+
+        if (crnti != null && ecgi != null) {
+            // check if there is an ecgi, crnti pair for this UE id.
+            EcgiCrntiPair oldPair = crntiMap.inverse().get(ue.getId()),
+                    newPair = EcgiCrntiPair.valueOf(cell.getEcgi(), ue.getCrnti());
+
+            if (oldPair == null) {
+                crntiMap.put(newPair, ue.getId());
+            } else {
+                // remove old pair and add the new pair which corresponds to the primary cell.
+                crntiMap.inverse().remove(ue.getId());
+                crntiMap.put(newPair, ue.getId());
+            }
+        }
+    }
+
+    @Override
+    public void putPrimaryLink(RnibCell cell, RnibUe ue) {
+        RnibLink link = new RnibLink(cell, ue);
+        // set link to primary before storing
+        link.setType(RnibLink.Type.SERVING_PRIMARY);
+        storeLink(link);
+        storeCrnti(cell, ue);
+    }
+
+    @Override
+    public Optional<RnibLink> putNonServingLink(RnibCell cell, CRNTI crnti) {
+        return getUe(cell.getEcgi(), crnti).map(ue -> {
+            RnibLink link = new RnibLink(cell, ue);
+            storeLink(link);
+            return Optional.of(link);
+        }).orElse(Optional.empty());
+    }
+
+    @Override
+    public Optional<RnibLink> putNonServingLink(RnibCell cell, Long ueId) {
+        return getUe(ueId).map(ue -> {
+            RnibLink link = new RnibLink(cell, ue);
+            storeLink(link);
+            return Optional.of(link);
+        }).orElse(Optional.empty());
+    }
+
+    @Override
+    public Optional<CRNTI> getCrnti(Long ueId) {
+        return Optional.ofNullable(getCrnti().inverse().get(ueId).getValue());
+    }
+
+    @Override
+    public Optional<RnibCell> getPrimaryCell(RnibUe ue) {
+        // search all links for this UE and find PRIMARY.
+        Optional<RnibLink> primary = getLinks().stream()
+                .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
+                .filter(l -> l.getLinkId().getUe().equals(ue))
+                .findFirst();
+
+        return primary.flatMap(l -> Optional.of(l.getLinkId().getCell()));
+    }
+
+    @Override
+    public Optional<RnibUe> getUe(long ueId) {
+        return Optional.ofNullable(ueMap.get(ueId));
+    }
+
+    @Override
+    public Optional<RnibUe> getUe(ECGI ecgi, CRNTI crnti) {
+        return Optional.ofNullable(crntiMap.get(EcgiCrntiPair.valueOf(ecgi, crnti)))
+                .flatMap(this::getUe);
+    }
+
+    /**
+     * Get from HEX string the according ECI class object.
+     *
+     * @param eciHex HEX string
+     * @return ECI object if created successfully
+     */
+    private EUTRANCellIdentifier hexToEci(String eciHex) {
+        byte[] hexBinary = DatatypeConverter.parseHexBinary(eciHex);
+        return new EUTRANCellIdentifier(hexBinary, 28);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/XranConfig.java b/apps/xran/src/main/java/org.onosproject.xran/impl/XranConfig.java
new file mode 100644
index 0000000..adde62e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/XranConfig.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.Config;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.EUTRANCellIdentifier;
+import org.onosproject.xran.asn1lib.api.PLMNIdentity;
+import org.onosproject.xran.asn1lib.util.HexConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.DatatypeConverter;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Xran config.
+ */
+public class XranConfig extends Config<ApplicationId> {
+
+    private static final String CELLS = "active_cells";
+
+    private static final String PLMN_ID = "plmn_id";
+
+    private static final String ECI_ID = "eci";
+
+    private static final String IP_ADDR = "ip_addr";
+
+    private static final String XRANC_IP = "xranc_bind_ip";
+
+    private static final String XRANC_PORT = "xranc_port";
+
+    private static final String XRANC_CELLCONFIG_INTERVAL = "xranc_cellconfigrequest_interval_seconds";
+
+    private static final String RX_SIGNAL_MEAS_REPORT_INTERVAL = "rx_signal_meas_report_interval_ms";
+
+    private static final String L2_MEAS_REPORT_INTERVAL = "l2_meas_report_interval_ms";
+
+    private static final String ADMISSION_SUCCESS = "admission_success";
+
+    private static final String BEARER_SUCCESS = "bearer_success";
+
+    private static final String NO_MEAS_LINK_REMOVAL = "no_meas_link_removal_ms";
+
+    private static final String IDLE_UE_REMOVAL = "idle_ue_removal_ms";
+
+    private static final String NORTHBOUND_TIMEOUT = "nb_response_timeout_ms";
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Get a list of all CELLs inside the configuration file.
+     *
+     * @return Map of CELL IP to ECGI
+     */
+    public Map<IpAddress, ECGI> activeCellSet() {
+        Map<IpAddress, ECGI> cells = new ConcurrentHashMap<>();
+
+        JsonNode cellsNode = object.get(CELLS);
+        if (cellsNode == null) {
+            log.warn("no cells have been provided!");
+            return cells;
+        }
+
+        cellsNode.forEach(cellNode -> {
+            String plmnId = cellNode.get(PLMN_ID).asText();
+            String eci = cellNode.get(ECI_ID).asText();
+
+            String ipAddress = cellNode.get(IP_ADDR).asText();
+
+            ECGI ecgi = hexToEcgi(plmnId, eci);
+            cells.put(IpAddress.valueOf(ipAddress), ecgi);
+        });
+
+        return cells;
+    }
+
+    /**
+     * Get flag for ADMISSION_SUCCESS field in configuration.
+     *
+     * @return boolean value in configuration
+     */
+    public boolean admissionFlag() {
+        JsonNode flag = object.get(ADMISSION_SUCCESS);
+        return flag != null && flag.asBoolean();
+    }
+
+    /**
+     * Get flag for BEARER_SUCCESS field in configuration.
+     *
+     * @return boolean value in configuration
+     */
+    public boolean bearerFlag() {
+        JsonNode flag = object.get(BEARER_SUCCESS);
+        return flag != null && flag.asBoolean();
+    }
+
+    /**
+     * Get IP where the XranServer binds to.
+     *
+     * @return IP address in configuration
+     */
+    public IpAddress getXrancIp() {
+        return IpAddress.valueOf(object.get(XRANC_IP).asText());
+    }
+
+    /**
+     * Get port for xRAN xranServer server to bind to from configuration.
+     *
+     * @return port number
+     */
+    public int getXrancPort() {
+        return object.get(XRANC_PORT).asInt();
+    }
+
+    /**
+     * Get config request interval from configuration.
+     *
+     * @return interval in seconds
+     */
+    public int getConfigRequestInterval() {
+        return object.get(XRANC_CELLCONFIG_INTERVAL).asInt();
+    }
+
+    /**
+     * Get rx signal interval from configuration.
+     *
+     * @return interval in milliseconds
+     */
+    public int getRxSignalInterval() {
+        return object.get(RX_SIGNAL_MEAS_REPORT_INTERVAL).asInt();
+    }
+
+    /**
+     * Get l2 measurement interval from configuration.
+     *
+     * @return interval in milliseconds
+     */
+    public int getL2MeasInterval() {
+        return object.get(L2_MEAS_REPORT_INTERVAL).asInt();
+    }
+
+    /**
+     * Get removal time of link after not getting measurement from configuration.
+     *
+     * @return interval in milliseconds
+     */
+    public int getNoMeasLinkRemoval() {
+        return object.get(NO_MEAS_LINK_REMOVAL).asInt();
+    }
+
+    /**
+     * Get removal time of UE after being IDLE from configuration.
+     *
+     * @return interval in milliseconds
+     */
+    public int getIdleUeRemoval() {
+        return object.get(IDLE_UE_REMOVAL).asInt();
+    }
+
+    /**
+     * Get northbound timeout when waiting for responses from configuration.
+     *
+     * @return interval in milliseconds
+     */
+    public int getNorthBoundTimeout() {
+        return object.get(NORTHBOUND_TIMEOUT).asInt();
+    }
+
+    /**
+     * Get ECGI from HEX representation of PLMN_ID and ECI.
+     *
+     * @param plmnId HEX string of PLMN_ID
+     * @param eci    HEX string of ECI
+     * @return new ECGI object
+     */
+    private ECGI hexToEcgi(String plmnId, String eci) {
+        byte[] bytes = HexConverter.fromShortHexString(plmnId);
+        byte[] bytearray = DatatypeConverter.parseHexBinary(eci);
+
+        InputStream inputStream = new ByteArrayInputStream(bytearray);
+
+        PLMNIdentity plmnIdentity = new PLMNIdentity(bytes);
+        EUTRANCellIdentifier eutranCellIdentifier = new EUTRANCellIdentifier(bytearray, 28);
+
+        ECGI ecgi = new ECGI();
+        ecgi.setEUTRANcellIdentifier(eutranCellIdentifier);
+        ecgi.setPLMNIdentity(plmnIdentity);
+        try {
+            ecgi.decode(inputStream);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return ecgi;
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranChannelHandler.java b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranChannelHandler.java
new file mode 100644
index 0000000..e0285c3
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranChannelHandler.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.controller;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandler.Sharable;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.sctp.SctpMessage;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.pdu.XrancPdu;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.URISyntaxException;
+
+/**
+ * Xran channel handler.
+ */
+@Sharable
+public class XranChannelHandler extends ChannelInboundHandlerAdapter {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(XranChannelHandler.class);
+
+    private final XranServer xranServer;
+
+    XranChannelHandler(XranServer xranServer) {
+        this.xranServer = xranServer;
+    }
+
+    /**
+     * Given PDU construct an SCTP message.
+     *
+     * @param pdu PDU packet
+     * @return SCTP message
+     * @throws IOException IO exception
+     */
+    public static SctpMessage getSctpMessage(XrancPdu pdu)  {
+        BerByteArrayOutputStream os = new BerByteArrayOutputStream(4096);
+
+        try {
+            pdu.encode(os);
+        } catch (IOException e) {
+          log.warn(ExceptionUtils.getFullStackTrace(e));
+        }
+
+        log.debug("Sending message: {}", pdu);
+        final ByteBuf buf = Unpooled.buffer(os.getArray().length);
+        for (int i = 0; i < buf.capacity(); i++) {
+            buf.writeByte(os.getArray()[i]);
+        }
+        return new SctpMessage(0, 0, buf);
+    }
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws IOException, URISyntaxException {
+        final SocketAddress address = ctx.channel().remoteAddress();
+        if (!(address instanceof InetSocketAddress)) {
+            log.warn("Invalid client connection. Xran Cell is indentifed based on IP");
+            ctx.close();
+            return;
+        }
+
+        final InetSocketAddress inetAddress = (InetSocketAddress) address;
+        final String host = inetAddress.getHostString();
+        log.info("New client connected to the Server: {}", host);
+
+        log.info("Adding device...");
+
+        xranServer.deviceAgent.addConnectedCell(host, ctx);
+    }
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws IOException, InterruptedException {
+        SctpMessage sctpMessage = (SctpMessage) msg;
+        ByteBuf byteBuf = sctpMessage.content();
+
+        byte[] bytes = new byte[byteBuf.readableBytes()];
+        byteBuf.readBytes(bytes);
+
+        XrancPdu recvPdu = new XrancPdu();
+
+        InputStream inputStream = new ByteArrayInputStream(bytes);
+
+        recvPdu.decode(inputStream);
+
+        xranServer.packetAgent.handlePacket(recvPdu, ctx);
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) {
+        log.info("Client dropped the connection");
+
+        final SocketAddress address = ctx.channel().remoteAddress();
+        if (!(address instanceof InetSocketAddress)) {
+            log.warn("Invalid client connection. Xran Cell is indentifed based on IP");
+            ctx.close();
+            return;
+        }
+
+        final InetSocketAddress inetAddress = (InetSocketAddress) address;
+        final String host = inetAddress.getHostString();
+
+        xranServer.deviceAgent.removeConnectedCell(host);
+
+        ctx.close();
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+        // Close the connection when an exception is raised.
+        log.warn("exceptionCaught: {}", ExceptionUtils.getStackTrace(cause));
+        cause.printStackTrace();
+        ctx.close();
+    }
+}
+
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranManager.java b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranManager.java
new file mode 100644
index 0000000..0df580f
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranManager.java
@@ -0,0 +1,1485 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.controller;
+
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.sctp.SctpMessage;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.xran.XranDeviceAgent;
+import org.onosproject.xran.XranDeviceListener;
+import org.onosproject.xran.XranHostAgent;
+import org.onosproject.xran.XranHostListener;
+import org.onosproject.xran.XranPacketProcessor;
+import org.onosproject.xran.XranService;
+import org.onosproject.xran.XranStore;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.ERABID;
+import org.onosproject.xran.asn1lib.api.ERABParams;
+import org.onosproject.xran.asn1lib.api.ERABParamsItem;
+import org.onosproject.xran.asn1lib.api.Hysteresis;
+import org.onosproject.xran.asn1lib.api.MeasID;
+import org.onosproject.xran.asn1lib.api.MeasObject;
+import org.onosproject.xran.asn1lib.api.PCIARFCN;
+import org.onosproject.xran.asn1lib.api.PropScell;
+import org.onosproject.xran.asn1lib.api.QOffsetRange;
+import org.onosproject.xran.asn1lib.api.RadioRepPerServCell;
+import org.onosproject.xran.asn1lib.api.ReportConfig;
+import org.onosproject.xran.asn1lib.api.SchedMeasRepPerServCell;
+import org.onosproject.xran.asn1lib.api.TimeToTrigger;
+import org.onosproject.xran.asn1lib.api.TrafficSplitPercentage;
+import org.onosproject.xran.asn1lib.ber.types.BerBoolean;
+import org.onosproject.xran.asn1lib.ber.types.BerEnum;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+import org.onosproject.xran.asn1lib.pdu.BearerAdmissionRequest;
+import org.onosproject.xran.asn1lib.pdu.BearerAdmissionResponse;
+import org.onosproject.xran.asn1lib.pdu.BearerAdmissionStatus;
+import org.onosproject.xran.asn1lib.pdu.BearerReleaseInd;
+import org.onosproject.xran.asn1lib.pdu.CellConfigReport;
+import org.onosproject.xran.asn1lib.pdu.CellConfigRequest;
+import org.onosproject.xran.asn1lib.pdu.HOComplete;
+import org.onosproject.xran.asn1lib.pdu.HOFailure;
+import org.onosproject.xran.asn1lib.pdu.HORequest;
+import org.onosproject.xran.asn1lib.pdu.L2MeasConfig;
+import org.onosproject.xran.asn1lib.pdu.PDCPMeasReportPerUe;
+import org.onosproject.xran.asn1lib.pdu.RRCMeasConfig;
+import org.onosproject.xran.asn1lib.pdu.RRMConfig;
+import org.onosproject.xran.asn1lib.pdu.RRMConfigStatus;
+import org.onosproject.xran.asn1lib.pdu.RXSigMeasReport;
+import org.onosproject.xran.asn1lib.pdu.RadioMeasReportPerCell;
+import org.onosproject.xran.asn1lib.pdu.RadioMeasReportPerUE;
+import org.onosproject.xran.asn1lib.pdu.ScellAdd;
+import org.onosproject.xran.asn1lib.pdu.ScellAddStatus;
+import org.onosproject.xran.asn1lib.pdu.ScellDelete;
+import org.onosproject.xran.asn1lib.pdu.SchedMeasReportPerCell;
+import org.onosproject.xran.asn1lib.pdu.SchedMeasReportPerUE;
+import org.onosproject.xran.asn1lib.pdu.TrafficSplitConfig;
+import org.onosproject.xran.asn1lib.pdu.UEAdmissionRequest;
+import org.onosproject.xran.asn1lib.pdu.UEAdmissionResponse;
+import org.onosproject.xran.asn1lib.pdu.UEAdmissionStatus;
+import org.onosproject.xran.asn1lib.pdu.UECapabilityEnquiry;
+import org.onosproject.xran.asn1lib.pdu.UECapabilityInfo;
+import org.onosproject.xran.asn1lib.pdu.UEContextUpdate;
+import org.onosproject.xran.asn1lib.pdu.UEReconfigInd;
+import org.onosproject.xran.asn1lib.pdu.UEReleaseInd;
+import org.onosproject.xran.asn1lib.pdu.XrancPdu;
+import org.onosproject.xran.impl.XranConfig;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.onosproject.xran.impl.entities.RnibLink;
+import org.onosproject.xran.impl.entities.RnibUe;
+import org.onosproject.xran.impl.identifiers.ContextUpdateHandler;
+import org.onosproject.xran.impl.identifiers.EcgiCrntiPair;
+import org.onosproject.xran.impl.identifiers.LinkId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.xran.impl.controller.XranChannelHandler.getSctpMessage;
+import static org.onosproject.xran.impl.entities.RnibCell.decodeDeviceId;
+import static org.onosproject.xran.impl.entities.RnibCell.uri;
+import static org.onosproject.xran.impl.entities.RnibUe.hostIdtoUEId;
+
+/**
+ * Created by dimitris on 7/20/17.
+ */
+@Component(immediate = true)
+@Service
+public class XranManager implements XranService {
+    protected static final String XRAN_APP_ID = "org.onosproject.xran";
+    protected static final Class<XranConfig> CONFIG_CLASS = XranConfig.class;
+
+    protected static final Logger log =
+            LoggerFactory.getLogger(XranManager.class);
+
+    /* CONFIG */
+    protected final InternalNetworkConfigListener configListener =
+            new InternalNetworkConfigListener();
+
+    /* VARIABLES */
+    protected final XranServer xranServer = new XranServer();
+    protected XranConfig xranConfig;
+    protected ApplicationId appId;
+    protected int northboundTimeout;
+
+    /* Services */
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry registry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected XranStore xranStore;
+
+    protected ConfigFactory<ApplicationId, XranConfig> xranConfigFactory =
+            new ConfigFactory<ApplicationId, XranConfig>(
+                    SubjectFactories.APP_SUBJECT_FACTORY, CONFIG_CLASS, "xran") {
+                @Override
+                public XranConfig createConfig() {
+                    return new XranConfig();
+                }
+            };
+
+    /* MAPS */
+    protected ConcurrentMap<IpAddress, ECGI> legitCells = new ConcurrentHashMap<>();
+    protected ConcurrentMap<ECGI, SynchronousQueue<String>> hoMap = new ConcurrentHashMap<>();
+    protected ConcurrentMap<ECGI, SynchronousQueue<String>> rrmCellMap = new ConcurrentHashMap<>();
+    protected ConcurrentMap<CRNTI, SynchronousQueue<String>> scellAddMap = new ConcurrentHashMap<>();
+    // Map used to keep messages in pairs (HO Complete - CTX Update, Adm Status - CTX Update)
+    protected ConcurrentMap<EcgiCrntiPair, ContextUpdateHandler> contextUpdateMap = new ConcurrentHashMap<>();
+
+    /* QUEUE */
+    protected BlockingQueue<Long> ueIdQueue = new LinkedBlockingQueue<>();
+
+    /* AGENTS */
+    protected InternalXranDeviceAgent deviceAgent = new InternalXranDeviceAgent();
+    protected InternalXranHostAgent hostAgent = new InternalXranHostAgent();
+    protected InternalXranPacketAgent packetAgent = new InternalXranPacketAgent();
+
+    /* LISTENERS */
+    protected Set<XranDeviceListener> xranDeviceListeners = new CopyOnWriteArraySet<>();
+    protected Set<XranHostListener> xranHostListeners = new CopyOnWriteArraySet<>();
+    protected InternalDeviceListener deviceListener = new InternalDeviceListener();
+    protected InternalHostListener hostListener = new InternalHostListener();
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(XRAN_APP_ID);
+
+        configService.addListener(configListener);
+        registry.registerConfigFactory(xranConfigFactory);
+        deviceService.addListener(deviceListener);
+        hostService.addListener(hostListener);
+
+        xranStore.setController(this);
+
+        log.info("XRAN XranServer v5 Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        deviceService.removeListener(deviceListener);
+        hostService.removeListener(hostListener);
+        configService.removeListener(configListener);
+        registry.unregisterConfigFactory(xranConfigFactory);
+
+        cleanup();
+
+        log.info("XRAN XranServer v5 Stopped");
+    }
+
+    /**
+     * Cleanup when application is deactivated.
+     */
+    private void cleanup() {
+        xranStore.getUeNodes().forEach(ue -> xranHostListeners.forEach(l -> l.hostRemoved(ue.getHostId())));
+
+        xranStore.getCellNodes().forEach(cell -> xranDeviceListeners
+                .forEach(l -> l.deviceRemoved(deviceId(uri(cell.getEcgi())))));
+
+        xranServer.stop();
+
+        legitCells.clear();
+        hoMap.clear();
+        rrmCellMap.clear();
+        scellAddMap.clear();
+        contextUpdateMap.clear();
+        ueIdQueue.clear();
+        xranDeviceListeners.clear();
+        xranHostListeners.clear();
+    }
+
+    @Override
+    public Optional<SynchronousQueue<String>> sendHoRequest(RnibLink linkT, RnibLink linkS) {
+        ECGI ecgiT = linkT.getLinkId().getEcgi(),
+                ecgiS = linkS.getLinkId().getEcgi();
+
+        Optional<ChannelHandlerContext> ctxT = xranStore.getCtx(ecgiT),
+                ctxS = xranStore.getCtx(ecgiS);
+
+        return xranStore.getCrnti(linkT.getLinkId().getUeId()).map(crnti -> {
+            SynchronousQueue<String> queue = new SynchronousQueue<>();
+
+            XrancPdu xrancPdu = HORequest.constructPacket(crnti, ecgiS, ecgiT);
+
+            // temporary map that has ECGI source of a handoff to a queue waiting for REST response.
+            hoMap.put(ecgiS, queue);
+
+            ctxT.ifPresent(ctx -> ctx.writeAndFlush(getSctpMessage(xrancPdu)));
+            ctxS.ifPresent(ctx -> ctx.writeAndFlush(getSctpMessage(xrancPdu)));
+
+            // FIXME: only works for one HO at a time.
+            try {
+                ueIdQueue.put(linkT.getLinkId().getUeId());
+            } catch (InterruptedException e) {
+                log.error(ExceptionUtils.getFullStackTrace(e));
+            }
+
+            return Optional.of(queue);
+        }).orElse(Optional.empty());
+    }
+
+    @Override
+    public void addListener(XranDeviceListener listener) {
+        xranDeviceListeners.add(listener);
+    }
+
+    @Override
+    public void addListener(XranHostListener listener) {
+        xranHostListeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(XranDeviceListener listener) {
+        xranDeviceListeners.remove(listener);
+    }
+
+    @Override
+    public void removeListener(XranHostListener listener) {
+        xranHostListeners.remove(listener);
+    }
+
+    @Override
+    public int getNorthboundTimeout() {
+        return northboundTimeout;
+    }
+
+    @Override
+    public Optional<SynchronousQueue<String>> sendModifiedRrm(RRMConfig rrmConfig) {
+        ECGI ecgi = rrmConfig.getEcgi();
+        Optional<ChannelHandlerContext> optionalCtx = xranStore.getCtx(ecgi);
+
+        // if ctx exists then create the queue and send the message
+        return optionalCtx.flatMap(ctx -> {
+            XrancPdu pdu;
+            pdu = RRMConfig.constructPacket(rrmConfig);
+            ctx.writeAndFlush(getSctpMessage(pdu));
+            SynchronousQueue<String> queue = new SynchronousQueue<>();
+            rrmCellMap.put(ecgi, queue);
+            return Optional.of(queue);
+        });
+    }
+
+    @Override
+    public Optional<SynchronousQueue<String>> sendScellAdd(RnibLink link) {
+        RnibCell secondaryCell = link.getLinkId().getCell();
+        // find primary cell
+        return xranStore.getPrimaryCell(link.getLinkId().getUe()).flatMap(primaryCell -> {
+                    ECGI primaryEcgi = primaryCell.getEcgi();
+                    // get ctx for the primary cell
+                    return xranStore.getCtx(primaryEcgi).flatMap(ctx ->
+                            // check if configuration exists
+                            secondaryCell.getOptConf().flatMap(cellReport -> {
+                                        PCIARFCN pciarfcn = new PCIARFCN();
+                                        pciarfcn.setPci(cellReport.getPci());
+                                        pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
+
+                                        PropScell propScell = new PropScell();
+                                        propScell.setPciArfcn(pciarfcn);
+
+                                        // search crnti of specific UE
+                                        return xranStore.getCrnti(link.getLinkId().getUeId()).flatMap(crnti -> {
+                                            SynchronousQueue<String> queue;
+                                            XrancPdu pdu = ScellAdd
+                                                    .constructPacket(primaryEcgi, crnti, propScell);
+
+                                            ctx.writeAndFlush(getSctpMessage(pdu));
+                                            queue = new SynchronousQueue<>();
+                                            scellAddMap.put(crnti, queue);
+
+                                            return Optional.of(queue);
+                                        });
+                                    }
+                            )
+                    );
+                }
+        );
+    }
+
+    @Override
+    public boolean sendScellDelete(RnibLink link) {
+        RnibCell secondaryCell = link.getLinkId().getCell();
+        // find primary cell
+        return xranStore.getPrimaryCell(link.getLinkId().getUe()).map(primaryCell -> {
+            ECGI primaryEcgi = primaryCell.getEcgi();
+            // get ctx for the primary cell
+            return xranStore.getCtx(primaryEcgi).map(ctx ->
+                    // check if config exists
+                    secondaryCell.getOptConf().map(cellReport -> {
+                        PCIARFCN pciarfcn = new PCIARFCN();
+                        pciarfcn.setPci(cellReport.getPci());
+                        pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
+
+                        // check if crnti for UE exists
+                        return xranStore.getCrnti(link.getLinkId().getUeId()).map(crnti -> {
+                            XrancPdu pdu = ScellDelete.constructPacket(primaryEcgi, crnti, pciarfcn);
+                            ctx.writeAndFlush(getSctpMessage(pdu));
+                            link.setType(RnibLink.Type.NON_SERVING);
+                            return true;
+                        }).orElse(false);
+                    }).orElse(false)
+            ).orElse(false);
+        }).orElse(false);
+    }
+
+    /**
+     * Timer to delete UE after being IDLE.
+     *
+     * @param ue UE entity
+     */
+    private void restartTimer(RnibUe ue) {
+        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+        ue.setExecutor(executor);
+        executor.schedule(
+                () -> {
+                    if (ue.getState().equals(RnibUe.State.IDLE)) {
+                        hostAgent.removeConnectedHost(ue);
+                        log.info("UE is removed after {} ms of IDLE", xranConfig.getIdleUeRemoval());
+                    } else {
+                        log.info("UE not removed cause its ACTIVE");
+                    }
+                },
+                xranConfig.getIdleUeRemoval(),
+                TimeUnit.MILLISECONDS
+        );
+    }
+
+    /**
+     * Timer to delete LINK after not receiving measurements.
+     *
+     * @param link LINK entity
+     */
+    private void restartTimer(RnibLink link) {
+        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+        link.setExecutor(executor);
+        executor.schedule(
+                () -> {
+                    LinkId linkId = link.getLinkId();
+                    xranStore.removeLink(linkId);
+                    log.info("Link is removed after not receiving Meas Reports for {} ms",
+                            xranConfig.getNoMeasLinkRemoval());
+                },
+                xranConfig.getNoMeasLinkRemoval(),
+                TimeUnit.MILLISECONDS
+        );
+    }
+
+    /**
+     * Request measurement configuration field of specified UE.
+     *
+     * @param primary primary CELL
+     * @param ue      UE entity
+     */
+    // TODO
+    private void populateMeasConfig(RnibCell primary, RnibUe ue) {
+        RRCMeasConfig.MeasObjects measObjects = new RRCMeasConfig.MeasObjects();
+        RRCMeasConfig.MeasIds measIds = new RRCMeasConfig.MeasIds();
+        // get ctx for cell
+        xranStore.getCtx(primary.getEcgi()).ifPresent(ctx -> {
+            // iterate through all cells
+            final int[] index = {0};
+            xranStore.getCellNodes().forEach(cell ->
+                    // set pciarfcn if config exists
+                    cell.getOptConf().ifPresent(cellReport -> {
+                                // PCIARFCN
+                                PCIARFCN pciarfcn = new PCIARFCN();
+                                pciarfcn.setPci(cellReport.getPci());
+                                pciarfcn.setEarfcnDl(cellReport.getEarfcnDl());
+
+                                // MEAS OBJECT
+                                MeasObject measObject = new MeasObject();
+                                MeasObject.MeasCells measCells = new MeasObject.MeasCells();
+                                measObject.setMeasCells(measCells);
+                                measObject.setDlFreq(cellReport.getEarfcnDl());
+                                measCells.setPci(cellReport.getPci());
+                                measCells.setCellIndividualOffset(new QOffsetRange(0));
+                                measObjects.getMeasObject().add(measObject);
+
+                                // MEAS ID
+                                MeasID measID = new MeasID();
+                                MeasID.Action action = new MeasID.Action();
+                                action.setHototarget(new BerBoolean(false));
+                                measID.setAction(action);
+                                measID.setReportconfigId(new BerInteger(0));
+                                measID.setMeasobjectId(new BerInteger(index[0]++));
+                                measIds.getMeasID().add(measID);
+                            }
+                    )
+            );
+            // REPORT CONFIG
+
+            RRCMeasConfig.ReportConfigs reportConfigs = new RRCMeasConfig.ReportConfigs();
+            ReportConfig reportConfig = reportConfigs.getReportConfig().get(0);
+
+            reportConfig.setReportQuantity(new BerEnum(0));
+            reportConfig.setTriggerQuantity(new BerEnum(0));
+
+            ReportConfig.ReportParams reportParams = new ReportConfig.ReportParams();
+            reportParams.setHysteresis(new Hysteresis(0));
+            reportParams.setParams(new ReportConfig.ReportParams.Params());
+            reportParams.setTimetotrigger(new TimeToTrigger(0));
+
+            reportConfig.setReportParams(reportParams);
+
+            // construct a rx sig meas conf packet
+            XrancPdu xrancPdu = RRCMeasConfig.constructPacket(
+                    primary.getEcgi(),
+                    ue.getCrnti(),
+                    measObjects,
+                    reportConfigs,
+                    measIds,
+                    xranConfig.getRxSignalInterval()
+            );
+            ue.setMeasConfig(xrancPdu.getBody().getRRCMeasConfig());
+            ctx.writeAndFlush(getSctpMessage(xrancPdu));
+        });
+    }
+
+    public void panic(XrancPdu recvPdu) {
+        throw new IllegalArgumentException("Received illegal packet: " + recvPdu.toString());
+    }
+
+    /**
+     * Internal device listener.
+     */
+    class InternalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent event) {
+            log.info("Device Event {}", event);
+            switch (event.type()) {
+                case DEVICE_ADDED: {
+                    try {
+                        ECGI ecgi = decodeDeviceId(event.subject().id());
+                        // move this to a routine service
+                        xranStore.getCell(ecgi).ifPresent(cell -> {
+                            ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+                            executor.scheduleAtFixedRate(
+                                    () -> {
+                                        // populate config if it does not exist
+                                        if (!cell.getOptConf().isPresent()) {
+                                            // if channel context is present then send the config request
+                                            xranStore.getCtx(ecgi).ifPresent(ctx -> {
+                                                XrancPdu xrancPdu = CellConfigRequest.constructPacket(ecgi);
+                                                ctx.writeAndFlush(getSctpMessage(xrancPdu));
+                                            });
+                                        } else {
+                                            // iterate through all UEs
+                                            xranStore.getUeNodes().forEach(ue -> xranStore.getPrimaryCell(ue)
+                                                    .ifPresent(primaryCell -> populateMeasConfig(primaryCell, ue)));
+
+                                            // send l2 meas interval
+                                            xranStore.getCtx(ecgi).ifPresent(ctx -> {
+                                                XrancPdu xrancPdu = L2MeasConfig
+                                                        .constructPacket(ecgi, xranConfig.getL2MeasInterval());
+                                                cell.getMeasConfig().setL2MeasConfig(xrancPdu.getBody()
+                                                        .getL2MeasConfig());
+                                                SctpMessage sctpMessage = getSctpMessage(xrancPdu);
+                                                ctx.writeAndFlush(sctpMessage);
+
+                                                executor.shutdown();
+                                            });
+                                        }
+                                    },
+                                    0,
+                                    xranConfig.getConfigRequestInterval(),
+                                    TimeUnit.SECONDS
+                            );
+                        });
+                    } catch (IOException e) {
+                        log.error(ExceptionUtils.getFullStackTrace(e));
+                    }
+                    break;
+                }
+                default: {
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Internal host listener.
+     */
+    class InternalHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent event) {
+            log.info("Host Event {}", event);
+            switch (event.type()) {
+                case HOST_ADDED:
+                case HOST_MOVED: {
+                    xranStore.getUe(hostIdtoUEId(event.subject().id())).ifPresent(ue -> xranStore.getPrimaryCell(ue)
+                            .ifPresent(cell -> {
+                                ue.setMeasConfig(null);
+
+                                // move this to a routine service
+                                ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+                                executor.scheduleAtFixedRate(
+                                        () -> {
+                                            if (cell.getVersion() >= 3) {
+                                                if (!Optional.ofNullable(ue.getCapability()).isPresent()) {
+                                                    xranStore.getCtx(cell.getEcgi()).ifPresent(ctx -> {
+                                                        XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(
+                                                                cell.getEcgi(),
+                                                                ue.getCrnti());
+                                                        ctx.writeAndFlush(getSctpMessage(xrancPdu));
+                                                    });
+                                                } else {
+                                                    executor.shutdown();
+                                                }
+                                            } else {
+                                                executor.shutdown();
+                                            }
+
+                                        },
+                                        0,
+                                        xranConfig.getConfigRequestInterval(),
+                                        TimeUnit.MILLISECONDS
+                                );
+                                if (ue.getMeasConfig() == null) {
+                                    populateMeasConfig(cell, ue);
+                                }
+                            }));
+                    break;
+                }
+                default: {
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Internal xran device agent.
+     */
+    public class InternalXranDeviceAgent implements XranDeviceAgent {
+
+        private final Logger log = LoggerFactory.getLogger(InternalXranDeviceAgent.class);
+
+        @Override
+        public boolean addConnectedCell(String host, ChannelHandlerContext ctx) {
+            log.info("addConnectedCell: {}", host);
+            // check configuration if the cell is inside the accepted list
+            return Optional.ofNullable(legitCells.get(IpAddress.valueOf(host))).map(ecgi -> {
+                log.info("Device exists in configuration; registering...");
+                // check if cell is not already registered
+                if (!xranStore.getCell(ecgi).isPresent()) {
+                    RnibCell storeCell = new RnibCell();
+                    storeCell.setEcgi(ecgi);
+                    xranStore.storeCtx(storeCell, ctx);
+                    xranDeviceListeners.forEach(l -> l.deviceAdded(storeCell));
+                    return true;
+                }
+                return false;
+            }).orElseGet(() -> {
+                        log.error("Device is not a legit source; ignoring...");
+                        ctx.close();
+                        return false;
+                    }
+            );
+        }
+
+        @Override
+        public boolean removeConnectedCell(String host) {
+            log.info("removeConnectedCell: {}", host);
+            ECGI ecgi = legitCells.get(IpAddress.valueOf(host));
+
+            xranStore.getLinks(ecgi).forEach(rnibLink -> {
+                rnibLink.getLinkId().getUe().setState(RnibUe.State.IDLE);
+                restartTimer(rnibLink.getLinkId().getUe());
+                xranStore.removeLink(rnibLink.getLinkId());
+            });
+
+            if (xranStore.removeCell(ecgi)) {
+                xranDeviceListeners.forEach(l -> l.deviceRemoved(deviceId(uri(ecgi))));
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Internal xran host agent.
+     */
+    public class InternalXranHostAgent implements XranHostAgent {
+
+        @Override
+        public boolean addConnectedHost(RnibUe ue, RnibCell cell, ChannelHandlerContext ctx) {
+            log.info("addConnectedHost: {}", ue);
+            if (ue.getId() != null && xranStore.getUe(ue.getId()).isPresent()) {
+                xranStore.putPrimaryLink(cell, ue);
+
+                Set<ECGI> ecgiSet = Sets.newConcurrentHashSet();
+
+                xranStore.getLinks(ue.getId())
+                        .stream()
+                        .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
+                        .findFirst()
+                        .ifPresent(l -> ecgiSet.add(l.getLinkId().getEcgi()));
+
+                xranHostListeners.forEach(l -> l.hostAdded(ue, ecgiSet));
+                return true;
+            } else {
+                xranStore.storeUe(cell, ue);
+                xranStore.putPrimaryLink(cell, ue);
+
+                Set<ECGI> ecgiSet = Sets.newConcurrentHashSet();
+                ecgiSet.add(cell.getEcgi());
+                xranHostListeners.forEach(l -> l.hostAdded(ue, ecgiSet));
+                return true;
+            }
+
+        }
+
+        @Override
+        public boolean removeConnectedHost(RnibUe ue) {
+            log.info("removeConnectedHost: {}", ue);
+            xranStore.getLinks(ue.getId()).forEach(rnibLink -> xranStore.removeLink(rnibLink.getLinkId()));
+            if (xranStore.removeUe(ue.getId())) {
+                xranHostListeners.forEach(l -> l.hostRemoved(ue.getHostId()));
+                return true;
+            }
+            return false;
+        }
+    }
+
+    public class InternalXranPacketAgent implements XranPacketProcessor {
+        @Override
+        public void handlePacket(XrancPdu recvPdu, ChannelHandlerContext ctx)
+                throws IOException, InterruptedException {
+            int apiID = recvPdu.getHdr().getApiId().intValue();
+            log.debug("Received message: {}", recvPdu);
+            switch (apiID) {
+                // Cell Config Report
+                case 1: {
+                    CellConfigReport report = recvPdu.getBody().getCellConfigReport();
+                    handleCellconfigreport(report, recvPdu.getHdr().getVer().toString());
+                    break;
+                }
+                // UE Admission Request
+                case 2: {
+                    UEAdmissionRequest ueAdmissionRequest = recvPdu.getBody().getUEAdmissionRequest();
+                    handleUeadmissionRequest(ueAdmissionRequest, ctx);
+                    break;
+                }
+                // UE Admission Status
+                case 4: {
+                    UEAdmissionStatus ueAdmissionStatus = recvPdu.getBody().getUEAdmissionStatus();
+                    handleAdmissionStatus(ueAdmissionStatus, ctx);
+                    break;
+                }
+                // UE Context Update
+                case 5: {
+                    UEContextUpdate ueContextUpdate = recvPdu.getBody().getUEContextUpdate();
+                    handleUeContextUpdate(ueContextUpdate, ctx);
+                    break;
+                }
+                // UE Reconfig Ind
+                case 6: {
+                    UEReconfigInd ueReconfigInd = recvPdu.getBody().getUEReconfigInd();
+                    handleUeReconfigInd(ueReconfigInd);
+                    break;
+                }
+                // UE Release Ind
+                case 7: {
+                    // If xRANc wants to deactivate UE, we pass UEReleaseInd from xRANc to eNB.
+                    UEReleaseInd ueReleaseInd = recvPdu.getBody().getUEReleaseInd();
+                    handleUeReleaseInd(ueReleaseInd);
+                    break;
+                }
+                // Bearer Admission Request
+                case 8: {
+                    BearerAdmissionRequest bearerAdmissionRequest = recvPdu.getBody().getBearerAdmissionRequest();
+                    handleBearerAdmissionRequest(bearerAdmissionRequest, ctx);
+                    break;
+                }
+                // Bearer Admission Status
+                case 10: {
+                    BearerAdmissionStatus bearerAdmissionStatus = recvPdu.getBody().getBearerAdmissionStatus();
+                    // TODO: implement
+                    break;
+                }
+                // Bearer Release Ind
+                case 11: {
+                    BearerReleaseInd bearerReleaseInd = recvPdu.getBody().getBearerReleaseInd();
+                    handleBearerReleaseInd(bearerReleaseInd);
+                    break;
+                }
+                // HO Failure
+                case 13: {
+                    HOFailure hoFailure = recvPdu.getBody().getHOFailure();
+                    handleHoFailure(hoFailure);
+                    break;
+                }
+                // HO Complete
+                case 14: {
+                    HOComplete hoComplete = recvPdu.getBody().getHOComplete();
+                    handleHoComplete(hoComplete, ctx);
+                    break;
+                }
+                // RX Sig Meas Report
+                case 15: {
+                    RXSigMeasReport rxSigMeasReport = recvPdu.getBody().getRXSigMeasReport();
+                    handleRxSigMeasReport(rxSigMeasReport);
+                    break;
+                }
+                // Radio Meas Report per UE
+                case 17: {
+                    RadioMeasReportPerUE radioMeasReportPerUE = recvPdu.getBody().getRadioMeasReportPerUE();
+                    handleRadioMeasReportPerUe(radioMeasReportPerUE);
+                    break;
+                }
+                // Radio Meas Report per Cell
+                case 18: {
+                    RadioMeasReportPerCell radioMeasReportPerCell = recvPdu.getBody().getRadioMeasReportPerCell();
+                    handleRadioMeasReportPerCell(radioMeasReportPerCell);
+                    break;
+                }
+                // Sched Meas Report per UE
+                case 19: {
+                    SchedMeasReportPerUE schedMeasReportPerUE = recvPdu.getBody().getSchedMeasReportPerUE();
+                    handleSchedMeasReportPerUe(schedMeasReportPerUE);
+                    break;
+                }
+                // Sched Meas Report per Cell
+                case 20: {
+                    SchedMeasReportPerCell schedMeasReportPerCell = recvPdu.getBody().getSchedMeasReportPerCell();
+                    handleSchedMeasReportPerCell(schedMeasReportPerCell);
+                    break;
+                }
+                // PDCP Meas Report per UE
+                case 21: {
+                    PDCPMeasReportPerUe pdcpMeasReportPerUe = recvPdu.getBody().getPDCPMeasReportPerUe();
+                    handlePdcpMeasReportPerUe(pdcpMeasReportPerUe);
+                    break;
+                }
+                // UE Capability Enquiry
+                case 22: {
+                    UECapabilityEnquiry ueCapabilityEnquiry = recvPdu.getBody().getUECapabilityEnquiry();
+                    handleUecapabilityenquiry(ueCapabilityEnquiry, ctx);
+                    break;
+                }
+                // UE Capability Info
+                case 23: {
+                    UECapabilityInfo capabilityInfo = recvPdu.getBody().getUECapabilityInfo();
+                    handleCapabilityInfo(capabilityInfo);
+                    break;
+                }
+                // Scell Add Status
+                case 25: {
+                    ScellAddStatus scellAddStatus = recvPdu.getBody().getScellAddStatus();
+                    handleScellAddStatus(scellAddStatus);
+                    break;
+                }
+                // RRM Config Status
+                case 28: {
+                    // Decode RRMConfig Status
+                    RRMConfigStatus rrmConfigStatus = recvPdu.getBody().getRRMConfigStatus();
+                    handleRrmConfigStatus(rrmConfigStatus);
+                    break;
+                }
+                // SeNB Add
+                case 29: {
+                    // TODO: implement
+                    break;
+                }
+                // SeNB Add Status
+                case 30: {
+                    // TODO: implement
+                    break;
+                }
+                // SeNB Delete
+                case 31: {
+                    // TODO: implement
+                    break;
+                }
+                // Traffic Split Config
+                case 32: {
+                    TrafficSplitConfig trafficSplitConfig = recvPdu.getBody().getTrafficSplitConfig();
+                    handleTrafficSplitConfig(trafficSplitConfig);
+                    break;
+                }
+                // HO Cause
+                case 33: {
+                    // TODO: implement
+                    break;
+                }
+                case 34: {
+                    // TODO: implement
+                    break;
+                }
+                // Cell Config Request
+                case 0:
+                    // UE Admission Response
+                case 3:
+                    // Bearer Admission Response
+                case 9:
+                    // HO Request
+                case 12:
+                    // L2 Meas Config
+                case 16:
+                    // Scell Add
+                case 24:
+                    // Scell Delete
+                case 26:
+                    // RRM Config
+                case 27:
+                default: {
+                    panic(recvPdu);
+                }
+            }
+
+        }
+
+        /**
+         * Handle Cellconfigreport.
+         *
+         * @param report  CellConfigReport
+         * @param version String version ID
+         */
+        private void handleCellconfigreport(CellConfigReport report, String version) {
+            ECGI ecgi = report.getEcgi();
+
+            xranStore.getCell(ecgi).ifPresent(cell -> {
+                cell.setVersion(version);
+                cell.setConf(report);
+                xranStore.storePciArfcn(cell);
+            });
+        }
+
+        /**
+         * Handle Ueadmissionrequest.
+         *
+         * @param ueAdmissionRequest UEAdmissionRequest
+         * @param ctx                ChannelHandlerContext
+         * @throws IOException IO Exception
+         */
+        private void handleUeadmissionRequest(UEAdmissionRequest ueAdmissionRequest, ChannelHandlerContext ctx)
+                throws IOException {
+            ECGI ecgi = ueAdmissionRequest.getEcgi();
+
+            xranStore.getCell(ecgi).map(c -> {
+                CRNTI crnti = ueAdmissionRequest.getCrnti();
+                XrancPdu sendPdu = UEAdmissionResponse.constructPacket(ecgi, crnti, xranConfig.admissionFlag());
+                ctx.writeAndFlush(getSctpMessage(sendPdu));
+                return 1;
+            }).orElseGet(() -> {
+                log.warn("Could not find ECGI in registered cells: {}", ecgi);
+                return 0;
+            });
+        }
+
+        /**
+         * Handle UEAdmissionStatus.
+         *
+         * @param ueAdmissionStatus UEAdmissionStatus
+         * @param ctx               ChannelHandlerContext
+         */
+        private void handleAdmissionStatus(UEAdmissionStatus ueAdmissionStatus, ChannelHandlerContext ctx) {
+            xranStore.getUe(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti()).ifPresent(ue -> {
+                if (ueAdmissionStatus.getAdmEstStatus().value.intValue() == 0) {
+                    ue.setState(RnibUe.State.ACTIVE);
+                } else {
+                    ue.setState(RnibUe.State.IDLE);
+                }
+            });
+
+            if (ueAdmissionStatus.getAdmEstStatus().value.intValue() == 0) {
+                EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair
+                        .valueOf(ueAdmissionStatus.getEcgi(), ueAdmissionStatus.getCrnti());
+                contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
+                    if (v == null) {
+                        v = new ContextUpdateHandler();
+                    }
+                    if (v.setAdmissionStatus(ueAdmissionStatus)) {
+                        handlePairedPackets(v.getContextUpdate(), ctx, false);
+                        v.reset();
+                    }
+                    return v;
+                });
+            }
+        }
+
+        /**
+         * Handle UEContextUpdate.
+         *
+         * @param ueContextUpdate UEContextUpdate
+         * @param ctx             ChannelHandlerContext
+         */
+        private void handleUeContextUpdate(UEContextUpdate ueContextUpdate, ChannelHandlerContext ctx) {
+            EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair
+                    .valueOf(ueContextUpdate.getEcgi(), ueContextUpdate.getCrnti());
+
+            contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
+                if (v == null) {
+                    v = new ContextUpdateHandler();
+                }
+                if (v.setContextUpdate(ueContextUpdate)) {
+                    HOComplete hoComplete = v.getHoComplete();
+                    handlePairedPackets(ueContextUpdate, ctx, hoComplete != null);
+                    if (hoComplete != null) {
+                        try {
+                            hoMap.get(hoComplete.getEcgiS()).put("Hand Over Completed");
+                        } catch (InterruptedException e) {
+                            log.error(ExceptionUtils.getFullStackTrace(e));
+                        } finally {
+                            hoMap.remove(hoComplete.getEcgiS());
+                        }
+                    }
+                    v.reset();
+                }
+                return v;
+            });
+        }
+
+        /**
+         * Handle UEReconfigInd.
+         *
+         * @param ueReconfigInd UEReconfigInd
+         */
+        private void handleUeReconfigInd(UEReconfigInd ueReconfigInd) {
+            Optional<RnibUe> ue = xranStore.getUe(ueReconfigInd.getEcgi(), ueReconfigInd.getCrntiOld());
+            Optional<RnibCell> cell = xranStore.getCell(ueReconfigInd.getEcgi());
+
+            if (ue.isPresent() && cell.isPresent()) {
+                ue.get().setCrnti(ueReconfigInd.getCrntiNew());
+                xranStore.storeCrnti(cell.get(), ue.get());
+            } else {
+                log.warn("Could not find UE with this CRNTI: {}", ueReconfigInd.getCrntiOld());
+            }
+        }
+
+        /**
+         * Handle UEReleaseInd.
+         *
+         * @param ueReleaseInd UEReleaseInd
+         */
+        private void handleUeReleaseInd(UEReleaseInd ueReleaseInd) {
+            ECGI ecgi = ueReleaseInd.getEcgi();
+            CRNTI crnti = ueReleaseInd.getCrnti();
+
+            // Check if there is an ongoing handoff and only remove if ue is not part of the handoff.
+            Long peek = ueIdQueue.peek();
+            if (peek != null) {
+                EcgiCrntiPair ecgiCrntiPair = xranStore.getCrnti().inverse().get(peek);
+                if (ecgiCrntiPair != null && ecgiCrntiPair.equals(EcgiCrntiPair.valueOf(ecgi, crnti))) {
+                    return;
+                }
+            }
+
+            xranStore.getUe(ecgi, crnti).ifPresent(ue -> {
+                ue.setState(RnibUe.State.IDLE);
+                restartTimer(ue);
+            });
+        }
+
+        /**
+         * Handle BearerAdmissionRequest.
+         *
+         * @param bearerAdmissionRequest BearerAdmissionRequest
+         * @param ctx                    ChannelHandlerContext
+         */
+        private void handleBearerAdmissionRequest(BearerAdmissionRequest bearerAdmissionRequest,
+                                                  ChannelHandlerContext ctx) {
+            ECGI ecgi = bearerAdmissionRequest.getEcgi();
+            CRNTI crnti = bearerAdmissionRequest.getCrnti();
+            ERABParams erabParams = bearerAdmissionRequest.getErabParams();
+            xranStore.getLink(ecgi, crnti).ifPresent(link -> link.setBearerParameters(erabParams));
+
+            BerInteger numErabs = bearerAdmissionRequest.getNumErabs();
+            // Encode and send Bearer Admission Response
+            XrancPdu sendPdu = BearerAdmissionResponse
+                    .constructPacket(ecgi, crnti, erabParams, numErabs, xranConfig.bearerFlag());
+            ctx.writeAndFlush(getSctpMessage(sendPdu));
+        }
+
+        /**
+         * Handle BearerReleaseInd.
+         *
+         * @param bearerReleaseInd bearer release ind
+         */
+        private void handleBearerReleaseInd(BearerReleaseInd bearerReleaseInd) {
+            ECGI ecgi = bearerReleaseInd.getEcgi();
+            CRNTI crnti = bearerReleaseInd.getCrnti();
+
+            xranStore.getLink(ecgi, crnti).ifPresent(link -> {
+                List<ERABID> erabidsRelease = bearerReleaseInd.getErabIds().getERABID();
+                List<ERABParamsItem> erabParamsItem = link.getBearerParameters().getERABParamsItem();
+
+                List<ERABParamsItem> unreleased = erabParamsItem
+                        .stream()
+                        .filter(item -> {
+                            Optional<ERABID> any = erabidsRelease.stream()
+                                    .filter(id -> id.equals(item.getId())).findAny();
+                            return !any.isPresent();
+                        }).collect(Collectors.toList());
+                link.getBearerParameters().getERABParamsItem().clear();
+                link.getBearerParameters().getERABParamsItem().addAll(new ArrayList<>(unreleased));
+            });
+        }
+
+        /**
+         * Handle HOFailure.
+         *
+         * @param hoFailure HOFailure
+         * @throws InterruptedException ueIdQueue interruption
+         */
+        private void handleHoFailure(HOFailure hoFailure) throws InterruptedException {
+            try {
+                hoMap.get(hoFailure.getEcgi())
+                        .put("Hand Over Failed with cause: " + hoFailure.getCause());
+            } catch (InterruptedException e) {
+                log.error(ExceptionUtils.getFullStackTrace(e));
+            } finally {
+                hoMap.remove(hoFailure.getEcgi());
+                ueIdQueue.take();
+            }
+        }
+
+        /**
+         * Handle HOComplete.
+         *
+         * @param hoComplete HOComplete
+         * @param ctx        ChannelHandlerContext
+         */
+        private void handleHoComplete(HOComplete hoComplete, ChannelHandlerContext ctx) {
+            EcgiCrntiPair ecgiCrntiPair = EcgiCrntiPair.valueOf(hoComplete.getEcgiT(),
+                    hoComplete.getCrntiNew());
+            contextUpdateMap.compute(ecgiCrntiPair, (k, v) -> {
+                if (v == null) {
+                    v = new ContextUpdateHandler();
+                }
+                if (v.setHoComplete(hoComplete)) {
+                    handlePairedPackets(v.getContextUpdate(), ctx, true);
+
+                    try {
+                        hoMap.get(hoComplete.getEcgiS()).put("Hand Over Completed");
+                    } catch (InterruptedException e) {
+                        log.error(ExceptionUtils.getFullStackTrace(e));
+                    } finally {
+                        hoMap.remove(hoComplete.getEcgiS());
+                    }
+                    v.reset();
+                }
+                return v;
+            });
+        }
+
+        /**
+         * Handle RXSigMeasReport.
+         *
+         * @param rxSigMeasReport RXSigMeasReport
+         */
+        private void handleRxSigMeasReport(RXSigMeasReport rxSigMeasReport) {
+            rxSigMeasReport.getCellMeasReports().getSEQUENCEOF().forEach(
+                    cellMeasReport -> cellMeasReport.getRXSigReport().forEach(
+                            rxSigReport -> {
+                                rxSigMeasReport.getCrnti().getCRNTI().forEach(
+                                        crnti -> xranStore.getUe(rxSigMeasReport.getEcgi(), crnti).ifPresent(ue -> {
+                                            Long ueId = ue.getId();
+                                            xranStore.getCell(rxSigReport.getPciArfcn()).ifPresent(cell -> {
+                                                ECGI ecgi = cell.getEcgi();
+
+                                                Optional<RnibLink> link = xranStore.getLink(ecgi, ueId);
+                                                if (!link.isPresent()) {
+                                                    log.warn("Could not find link between: {}-{} " +
+                                                                    "| Creating non-serving link..",
+                                                            ecgi, ueId);
+                                                    link = xranStore.putNonServingLink(cell, ueId);
+                                                }
+
+                                                if (link.isPresent()) {
+                                                    if (link.get().getType().equals(RnibLink.Type.NON_SERVING)) {
+                                                        restartTimer(link.get());
+                                                    }
+
+//                                                    link.get().getMeasurements().setRxSigReport(
+//                                                        new RnibLink.Measurements.RXSigReport(
+//                                                                rxSigReport.getRsrq(),
+//                                                                rxSigReport.getRsrp(),
+//                                                                rxSigReport.get...
+//                                                        )
+//                                                    );
+                                                }
+                                            });
+                                        })
+                                );
+                            }
+                    )
+            );
+        }
+
+        /**
+         * Handle RadioMeasReportPerUE.
+         *
+         * @param radioMeasReportPerUE RadioMeasReportPerUE
+         */
+        private void handleRadioMeasReportPerUe(RadioMeasReportPerUE radioMeasReportPerUE) {
+            xranStore.getUe(radioMeasReportPerUE.getEcgi(), radioMeasReportPerUE.getCrnti()).ifPresent(ue -> {
+                Long ueId = ue.getId();
+                List<RadioRepPerServCell> servCells = radioMeasReportPerUE.getRadioReportServCells()
+                        .getRadioRepPerServCell();
+
+                servCells.forEach(servCell -> xranStore.getCell(servCell.getEcgi())
+                        .ifPresent(cell -> xranStore.getLink(cell.getEcgi(), ueId)
+                                .ifPresent(link -> {
+                                            RadioRepPerServCell.CqiHist cqiHist = servCell.getCqiHist();
+                                            final double[] values = {0, 0, 0};
+                                            final int[] i = {1};
+                                            cqiHist.getBerInteger().forEach(value -> {
+                                                        values[0] = Math.max(values[0], value.intValue());
+                                                        values[1] += i[0] * value.intValue();
+                                                        values[2] += value.intValue();
+                                                        i[0]++;
+                                                    }
+                                            );
+
+                                            link.getMeasurements().setRadioReport(
+                                                    new RnibLink.Measurements.RadioReport(
+                                                            new RnibLink.Measurements.RadioReport.Cqi(
+                                                                    cqiHist,
+                                                                    values[0],
+                                                                    values[1] / values[0]
+                                                            ),
+                                                            servCell.getRiHist(),
+                                                            servCell.getPucchSinrHist(),
+                                                            servCell.getPuschSinrHist()
+
+                                                    )
+                                            );
+                                        }
+                                )
+                        )
+                );
+            });
+        }
+
+        /**
+         * Handle RadioMeasReportPerCell.
+         *
+         * @param radioMeasReportPerCell RadioMeasReportPerCell
+         */
+        private void handleRadioMeasReportPerCell(RadioMeasReportPerCell radioMeasReportPerCell) {
+            xranStore.getCell(radioMeasReportPerCell.getEcgi()).ifPresent(
+                    cell -> cell.getMeasurements().setUlInterferenceMeasurement(
+                            new RnibCell.Measurements.ULInterferenceMeasurement(
+                                    radioMeasReportPerCell.getPuschIntfPowerHist(),
+                                    radioMeasReportPerCell.getPucchIntfPowerHist()
+                            )
+                    )
+            );
+        }
+
+        /**
+         * Handle SchedMeasReportPerUE.
+         *
+         * @param schedMeasReportPerUE SchedMeasReportPerUE
+         */
+        private void handleSchedMeasReportPerUe(SchedMeasReportPerUE schedMeasReportPerUE) {
+            xranStore.getUe(schedMeasReportPerUE.getEcgi(), schedMeasReportPerUE.getCrnti()).ifPresent(ue -> {
+                Long ueId = ue.getId();
+
+                List<SchedMeasRepPerServCell> servCells = schedMeasReportPerUE.getSchedReportServCells()
+                        .getSchedMeasRepPerServCell();
+
+                servCells.forEach(servCell -> xranStore.getCell(servCell.getEcgi())
+                        .ifPresent(cell -> xranStore.getLink(cell.getEcgi(), ueId)
+                                .ifPresent(link -> link.getMeasurements().setSchedMeasReport(
+                                        new RnibLink.Measurements.SchedMeasReport(
+                                                servCell.getQciVals(),
+                                                new RnibLink.Measurements.SchedMeasReport.ResourceUsage(
+                                                        servCell.getPrbUsage().getPrbUsageDl(),
+                                                        servCell.getPrbUsage().getPrbUsageUl()
+                                                ),
+                                                new RnibLink.Measurements.SchedMeasReport.Mcs(
+                                                        servCell.getMcsDl(),
+                                                        servCell.getMcsUl()
+                                                ),
+                                                new RnibLink.Measurements.SchedMeasReport.NumSchedTtis(
+                                                        servCell.getNumSchedTtisDl(),
+                                                        servCell.getNumSchedTtisUl()
+                                                ),
+                                                new RnibLink.Measurements.SchedMeasReport.DlRankStats(
+                                                        servCell.getRankDl1(),
+                                                        servCell.getRankDl2()
+                                                )
+                                        )
+                                )
+                                )
+                        )
+                );
+            });
+        }
+
+        /**
+         * Handle SchedMeasReportPerCell.
+         *
+         * @param schedMeasReportPerCell SchedMeasReportPerCell
+         */
+        private void handleSchedMeasReportPerCell(SchedMeasReportPerCell schedMeasReportPerCell) {
+            xranStore.getCell(schedMeasReportPerCell.getEcgi()).ifPresent(cell -> cell.getMeasurements().setPrbUsage(
+                    new RnibCell.Measurements.PrbUsage(
+                            schedMeasReportPerCell.getQciVals(),
+                            schedMeasReportPerCell.getPrbUsagePcell(),
+                            schedMeasReportPerCell.getPrbUsageScell()
+                    )
+            ));
+        }
+
+        /**
+         * Handle PDCPMeasReportPerUe.
+         *
+         * @param pdcpMeasReportPerUe PDCPMeasReportPerUe
+         */
+        private void handlePdcpMeasReportPerUe(PDCPMeasReportPerUe pdcpMeasReportPerUe) {
+            xranStore.getUe(pdcpMeasReportPerUe.getEcgi(), pdcpMeasReportPerUe.getCrnti()).ifPresent(ue -> {
+                Long ueId = ue.getId();
+                xranStore.getLink(pdcpMeasReportPerUe.getEcgi(), ueId).ifPresent(link ->
+                        link.getMeasurements().setPdcpMeasReport(
+                                new RnibLink.Measurements.PdcpMeasReport(
+                                        pdcpMeasReportPerUe.getQciVals(),
+                                        new RnibLink.Measurements.PdcpMeasReport.PdcpThroughput(
+                                                pdcpMeasReportPerUe.getThroughputDl(),
+                                                pdcpMeasReportPerUe.getThroughputUl()
+                                        ),
+                                        new RnibLink.Measurements.PdcpMeasReport.DataVol(
+                                                pdcpMeasReportPerUe.getDataVolDl(),
+                                                pdcpMeasReportPerUe.getDataVolUl()
+                                        ),
+                                        pdcpMeasReportPerUe.getPktDelayDl(),
+                                        pdcpMeasReportPerUe.getPktDiscardRateDl(),
+                                        new RnibLink.Measurements.PdcpMeasReport.PktLossRate(
+                                                pdcpMeasReportPerUe.getPktLossRateDl(),
+                                                pdcpMeasReportPerUe.getPktLossRateUl()
+                                        )
+                                )
+                        )
+                );
+            });
+        }
+
+        /**
+         * Handle UECapabilityInfo.
+         *
+         * @param capabilityInfo UECapabilityInfo
+         */
+        private void handleCapabilityInfo(UECapabilityInfo capabilityInfo) {
+            xranStore.getUe(capabilityInfo.getEcgi(), capabilityInfo.getCrnti())
+                    .ifPresent(
+                            ue -> ue.setCapability(capabilityInfo)
+                    );
+        }
+
+        /**
+         * Handle UECapabilityEnquiry.
+         *
+         * @param ueCapabilityEnquiry UECapabilityEnquiry
+         * @param ctx                 ChannelHandlerContext
+         */
+        private void handleUecapabilityenquiry(UECapabilityEnquiry ueCapabilityEnquiry, ChannelHandlerContext ctx) {
+            XrancPdu xrancPdu = UECapabilityEnquiry.constructPacket(ueCapabilityEnquiry.getEcgi(),
+                    ueCapabilityEnquiry.getCrnti());
+            ctx.writeAndFlush(getSctpMessage(xrancPdu));
+        }
+
+        /**
+         * Handle ScellAddStatus.
+         *
+         * @param scellAddStatus ScellAddStatus
+         */
+        private void handleScellAddStatus(ScellAddStatus scellAddStatus) {
+            xranStore.getUe(scellAddStatus.getEcgi(), scellAddStatus.getCrnti()).ifPresent(ue -> {
+                Long ueId = ue.getId();
+                try {
+                    scellAddMap.get(scellAddStatus.getCrnti()).put("Scell's status: " +
+                            scellAddStatus.getStatus());
+                    final int[] i = {0};
+                    scellAddStatus.getScellsInd().getPCIARFCN().forEach(
+                            pciarfcn -> {
+                                if (scellAddStatus.getStatus().getBerEnum().get(i[0]).value.intValue() == 0) {
+                                    xranStore.getCell(pciarfcn)
+                                            .ifPresent(cell -> xranStore.getLink(cell.getEcgi(), ueId)
+                                                    .ifPresent(link -> link.setType(RnibLink.Type.SERVING_SECONDARY_CA))
+                                            );
+                                }
+                                i[0]++;
+                            }
+                    );
+
+                } catch (InterruptedException e) {
+                    log.error(ExceptionUtils.getFullStackTrace(e));
+                } finally {
+                    scellAddMap.remove(scellAddStatus.getCrnti());
+                }
+            });
+        }
+
+        /**
+         * Handle RRMConfigStatus.
+         *
+         * @param rrmConfigStatus RRMConfigStatus
+         */
+        private void handleRrmConfigStatus(RRMConfigStatus rrmConfigStatus) {
+            try {
+                rrmCellMap.get(rrmConfigStatus.getEcgi())
+                        .put("RRM Config's status: " + rrmConfigStatus.getStatus());
+            } catch (InterruptedException e) {
+                log.error(ExceptionUtils.getFullStackTrace(e));
+            } finally {
+                rrmCellMap.remove(rrmConfigStatus.getEcgi());
+            }
+        }
+
+        /**
+         * Handle TrafficSplitConfig.
+         *
+         * @param trafficSplitConfig TrafficSplitConfig
+         */
+        private void handleTrafficSplitConfig(TrafficSplitConfig trafficSplitConfig) {
+            xranStore.getUe(trafficSplitConfig.getEcgi(), trafficSplitConfig.getCrnti()).ifPresent(ue -> {
+                Long ueId = ue.getId();
+                List<TrafficSplitPercentage> splitPercentages = trafficSplitConfig
+                        .getTrafficSplitPercent().getTrafficSplitPercentage();
+
+                splitPercentages.forEach(trafficSplitPercentage -> xranStore.getCell(trafficSplitPercentage.getEcgi())
+                        .ifPresent(cell -> xranStore.getLink(cell.getEcgi(), ueId)
+                                .ifPresent(link -> link.setTrafficPercent(trafficSplitPercentage))));
+            });
+        }
+
+        /**
+         * Handle context update depending if its handoff or not.
+         *
+         * @param contextUpdate context update packet
+         * @param ctx           channel context for the CELL
+         * @param handoff       true if we handle a Hand Off
+         */
+        private void handlePairedPackets(UEContextUpdate contextUpdate, ChannelHandlerContext ctx, boolean handoff) {
+            xranStore.getCell(contextUpdate.getEcgi()).ifPresent(cell -> {
+                        Optional<RnibUe> optionalUe;
+                        if (handoff) {
+                            try {
+                                optionalUe = xranStore.getUe(ueIdQueue.take());
+                            } catch (InterruptedException e) {
+                                log.error(ExceptionUtils.getFullStackTrace(e));
+                                optionalUe = Optional.of(new RnibUe());
+                            }
+                        } else {
+                            optionalUe = Optional.of(new RnibUe());
+                        }
+
+                        optionalUe.ifPresent(ue -> {
+                            ue.getContextIds().setMmeS1apId(contextUpdate.getMMEUES1APID());
+                            ue.getContextIds().setEnbS1apId(contextUpdate.getENBUES1APID());
+                            ue.setCrnti(contextUpdate.getCrnti());
+                            hostAgent.addConnectedHost(ue, cell, ctx);
+                        });
+                    }
+            );
+        }
+    }
+
+    /**
+     * Internal class for NetworkConfigListener.
+     */
+    class InternalNetworkConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            switch (event.type()) {
+                case CONFIG_REGISTERED:
+                    break;
+                case CONFIG_UNREGISTERED:
+                    break;
+                case CONFIG_ADDED:
+                case CONFIG_UPDATED:
+                    if (event.configClass() == CONFIG_CLASS) {
+                        handleConfigEvent(event.config());
+                    }
+                    break;
+                case CONFIG_REMOVED:
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        /**
+         * Handle config event.
+         *
+         * @param configOptional config
+         */
+        private void handleConfigEvent(Optional<Config> configOptional) {
+            configOptional.ifPresent(config -> {
+                xranConfig = (XranConfig) config;
+                northboundTimeout = xranConfig.getNorthBoundTimeout();
+                legitCells.putAll(xranConfig.activeCellSet());
+                xranServer.start(deviceAgent, hostAgent, packetAgent,
+                        xranConfig.getXrancIp(), xranConfig.getXrancPort());
+            });
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranServer.java b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranServer.java
new file mode 100644
index 0000000..8a92ffd
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/XranServer.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.controller;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.sctp.SctpChannel;
+import io.netty.channel.sctp.nio.NioSctpServerChannel;
+import io.netty.handler.logging.LogLevel;
+import io.netty.handler.logging.LoggingHandler;
+import org.onlab.packet.IpAddress;
+import org.onosproject.xran.XranDeviceAgent;
+import org.onosproject.xran.XranHostAgent;
+import org.onosproject.xran.XranPacketProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Created by dimitris on 7/27/17.
+ */
+public class XranServer {
+    protected static final Logger log = LoggerFactory.getLogger(XranServer.class);
+    protected XranDeviceAgent deviceAgent;
+    protected XranHostAgent hostAgent;
+    protected XranPacketProcessor packetAgent;
+    private EventLoopGroup bossGroup;
+    private EventLoopGroup workerGroup;
+    private ChannelFuture channel;
+    private int port = 8007;
+    private IpAddress bindAddress = IpAddress.valueOf("0.0.0.0");
+    private boolean isRunning = false;
+
+    /**
+     * Run SCTP server.
+     */
+    public void run() {
+        final XranServer ctrl = this;
+        try {
+            ServerBootstrap b = createServerBootStrap();
+            b.childHandler(new ChannelInitializer<SctpChannel>() {
+                @Override
+                public void initChannel(SctpChannel ch) throws Exception {
+                    ch.pipeline().addLast(
+                            //new LoggingHandler(LogLevel.INFO),
+                            new XranChannelHandler(ctrl)
+                    );
+                }
+            });
+            channel = b.bind(this.bindAddress.toInetAddress(), this.port).sync();
+        } catch (Exception e) {
+            log.warn(e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Create bootstrap for server.
+     *
+     * @return server bootstrap
+     */
+    private ServerBootstrap createServerBootStrap() {
+        bossGroup = new NioEventLoopGroup(1);
+        workerGroup = new NioEventLoopGroup();
+
+        ServerBootstrap b = new ServerBootstrap();
+        b.group(bossGroup, workerGroup)
+                .channel(NioSctpServerChannel.class)
+                .handler(new LoggingHandler(LogLevel.INFO));
+        return b;
+    }
+
+    /**
+     * Initialize xranServer and start SCTP server.
+     *  @param deviceAgent device agent
+     * @param hostAgent   host agent
+     * @param packetAgent packet agent
+     * @param xrancIp     xran bind IP
+     * @param port        port of server
+     */
+    public void start(XranDeviceAgent deviceAgent, XranHostAgent hostAgent, XranPacketProcessor packetAgent,
+                      IpAddress xrancIp, int port) {
+        if (isRunning && (this.port != port || !this.bindAddress.equals(xrancIp))) {
+            stop();
+            this.deviceAgent = deviceAgent;
+            this.hostAgent = hostAgent;
+            this.packetAgent = packetAgent;
+            this.port = port;
+            this.bindAddress = xrancIp;
+            run();
+        } else if (!isRunning) {
+            this.deviceAgent = deviceAgent;
+            this.hostAgent = hostAgent;
+            this.packetAgent = packetAgent;
+            this.port = port;
+            this.bindAddress = xrancIp;
+            run();
+            isRunning = true;
+        }
+    }
+
+    /**
+     * Stop SCTP server.
+     */
+    public void stop() {
+        if (isRunning) {
+            channel.channel().close();
+            bossGroup.shutdownGracefully();
+            workerGroup.shutdownGracefully();
+            isRunning = false;
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/controller/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/package-info.java
new file mode 100644
index 0000000..6b047e5
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/controller/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Created by dimitris on 7/21/17.
+ */
+package org.onosproject.xran.impl.controller;
\ No newline at end of file
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibCell.java b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibCell.java
new file mode 100644
index 0000000..6370a05
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibCell.java
@@ -0,0 +1,676 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.entities;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.PRBUsage;
+import org.onosproject.xran.asn1lib.api.XICICPA;
+import org.onosproject.xran.asn1lib.ber.BerByteArrayOutputStream;
+import org.onosproject.xran.asn1lib.ber.types.BerBitString;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+import org.onosproject.xran.asn1lib.pdu.CellConfigReport;
+import org.onosproject.xran.asn1lib.pdu.L2MeasConfig;
+import org.onosproject.xran.asn1lib.pdu.RRCMeasConfig;
+import org.onosproject.xran.asn1lib.pdu.RRMConfig;
+import org.onosproject.xran.asn1lib.pdu.RadioMeasReportPerCell;
+import org.onosproject.xran.asn1lib.pdu.SchedMeasReportPerCell;
+
+import javax.xml.bind.DatatypeConverter;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+
+/**
+ * R-NIB Cell and its properties.
+ */
+@JsonPropertyOrder({
+        "ECGI",
+        "Configuration",
+        "RRMConfiguration",
+        "MeasConfig",
+        "Measurements"
+})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RnibCell {
+    @JsonIgnore
+    private static final String SCHEME = "xran";
+
+    @JsonProperty("ECGI")
+    private ECGI ecgi;
+
+    @JsonProperty("Configuration")
+    private Optional<CellConfigReport> conf = Optional.empty();
+
+    @JsonProperty("RRMConfiguration")
+    private RRMConfig rrmConfig = new RRMConfig();
+
+    @JsonProperty("MeasConfig")
+    private MeasConfig measConfig = new MeasConfig();
+
+    @JsonProperty("Measurements")
+    private Measurements measurements = new Measurements();
+
+    @JsonIgnore
+    private String version = "5";
+
+    /**
+     * Encode ECGI and obtain its URI.
+     *
+     * @param ecgi ECGI
+     * @return URI
+     */
+    public static URI uri(ECGI ecgi) {
+        if (ecgi != null) {
+            try {
+                BerByteArrayOutputStream os = new BerByteArrayOutputStream(4096);
+                ecgi.encode(os);
+                String message = DatatypeConverter.printHexBinary(os.getArray());
+                return new URI(SCHEME, message, null);
+            } catch (URISyntaxException | IOException e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Obtain ECGI from the device ID.
+     *
+     * @param deviceId ID of the device
+     * @return ECGI
+     * @throws IOException I0 Exception for ByteArrayInputStream
+     */
+    public static ECGI decodeDeviceId(DeviceId deviceId) throws IOException {
+        String uri = deviceId.toString();
+        String hexEcgi = uri.substring(uri.lastIndexOf("xran:") + 5);
+
+        ECGI ecgi = new ECGI();
+        byte[] bytearray = DatatypeConverter.parseHexBinary(hexEcgi);
+        InputStream inputStream = new ByteArrayInputStream(bytearray);
+
+        ecgi.decode(inputStream);
+        return ecgi;
+    }
+
+    /**
+     * Get version ID.
+     *
+     * @return version ID
+     */
+    public int getVersion() {
+        return Integer.parseInt(version);
+    }
+
+    /**
+     * Set version ID.
+     *
+     * @param version version ID
+     */
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    /**
+     * Get RRMConfig.
+     *
+     * @return RRMConfig
+     */
+    public RRMConfig getRrmConfig() {
+        return rrmConfig;
+    }
+
+    /**
+     * Set RRMConfig properties.
+     *
+     * @param rrmConfig RRMConfig
+     */
+    public void setRrmConfig(RRMConfig rrmConfig) {
+        this.rrmConfig = rrmConfig;
+    }
+
+    /**
+     * Get ECGI.
+     *
+     * @return ECGI
+     */
+    public ECGI getEcgi() {
+        return ecgi;
+    }
+
+    /**
+     * Set ECGI.
+     *
+     * @param ecgi ECGI
+     */
+    public void setEcgi(ECGI ecgi) {
+        this.ecgi = ecgi;
+    }
+
+    /**
+     * Get cell config report.
+     *
+     * @return Optional CellConfig Report
+     */
+    public Optional<CellConfigReport> getOptConf() {
+        return conf;
+    }
+
+    /**
+     * Get cell config report.
+     *
+     * @return CellConfig Report
+     */
+    public CellConfigReport getConf() {
+        return conf.get();
+    }
+
+    /**
+     * Set cell config report.
+     *
+     * @param conf Cell config report
+     */
+    public void setConf(CellConfigReport conf) {
+        this.conf = Optional.ofNullable(conf);
+    }
+
+    public MeasConfig getMeasConfig() {
+        return measConfig;
+    }
+
+    public void setMeasConfig(MeasConfig measConfig) {
+        this.measConfig = measConfig;
+    }
+
+    public Measurements getMeasurements() {
+        return measurements;
+    }
+
+    public void setMeasurements(Measurements measurements) {
+        this.measurements = measurements;
+    }
+
+    /**
+     * Modify the RRM Config parameters of cell.
+     *
+     * @param rrmConfigNode RRMConfig parameters to modify obtained from REST call
+     * @param ueList        List of all UEs
+     * @throws Exception p_a size not equal to UE size
+     */
+    public void modifyRrmConfig(JsonNode rrmConfigNode, List<RnibUe> ueList) throws Exception {
+        RRMConfig.Crnti crnti = new RRMConfig.Crnti();
+        ueList.forEach(ue -> crnti.getCRNTI().add(ue.getCrnti()));
+
+        JsonNode pA = rrmConfigNode.path("p_a");
+        if (!pA.isMissingNode()) {
+            RRMConfig.Pa pa = new RRMConfig.Pa();
+            if (pA.isArray()) {
+                if (ueList.size() == pA.size()) {
+                    List<XICICPA> collect = Stream.of(pA)
+                            .map(val -> new XICICPA(val.asInt()))
+                            .collect(Collectors.toList());
+                    pa.getXICICPA().clear();
+                    pa.getXICICPA().addAll(collect);
+                } else {
+                    throw new Exception("p_a size is not the same as UE size");
+                }
+            }
+            rrmConfig.setPa(pa);
+        }
+
+        JsonNode startPrbDl1 = rrmConfigNode.path("start_prb_dl");
+        if (!startPrbDl1.isMissingNode()) {
+            RRMConfig.StartPrbDl startPrbDl = new RRMConfig.StartPrbDl();
+            if (startPrbDl1.isArray()) {
+                if (ueList.size() == startPrbDl1.size()) {
+                    List<BerInteger> collect = Stream.of(startPrbDl1)
+                            .map(val -> new BerInteger(val.asInt()))
+                            .collect(Collectors.toList());
+                    startPrbDl.getBerInteger().clear();
+                    startPrbDl.getBerInteger().addAll(collect);
+                } else {
+                    throw new Exception("start_prb_dl size is not the same as UE size");
+                }
+            }
+            rrmConfig.setStartPrbDl(startPrbDl);
+        }
+
+        JsonNode endPrbDl1 = rrmConfigNode.path("end_prb_dl");
+        if (!endPrbDl1.isMissingNode()) {
+            RRMConfig.EndPrbDl endPrbDl = new RRMConfig.EndPrbDl();
+            if (endPrbDl1.isArray()) {
+                if (ueList.size() == endPrbDl1.size()) {
+                    List<BerInteger> collect = Stream.of(endPrbDl1)
+                            .map(val -> new BerInteger(val.asInt()))
+                            .collect(Collectors.toList());
+                    endPrbDl.getBerInteger().clear();
+                    endPrbDl.getBerInteger().addAll(collect);
+                } else {
+                    throw new Exception("end_prb_dl size is not the same as UE size");
+                }
+            }
+            rrmConfig.setEndPrbDl(endPrbDl);
+        }
+
+        JsonNode frameBitmaskDl = rrmConfigNode.path("sub_frame_bitmask_dl");
+        if (!frameBitmaskDl.isMissingNode()) {
+            RRMConfig.SubframeBitmaskDl subframeBitmaskDl = new RRMConfig.SubframeBitmaskDl();
+            if (frameBitmaskDl.isArray()) {
+                List<BerBitString> collect = Stream.of(frameBitmaskDl)
+                        .map(val -> new BerBitString(DatatypeConverter.parseHexBinary(val.asText()), 10))
+                        .collect(Collectors.toList());
+                subframeBitmaskDl.getBerBitString().clear();
+                subframeBitmaskDl.getBerBitString().addAll(collect);
+            } else {
+                throw new Exception("sub_frame_bitmask_dl size is not the same as UE size");
+            }
+            rrmConfig.setSubframeBitmaskDl(subframeBitmaskDl);
+        }
+
+        JsonNode startPrbUl1 = rrmConfigNode.path("start_prb_ul");
+        if (!startPrbUl1.isMissingNode()) {
+            RRMConfig.StartPrbUl startPrbUl = new RRMConfig.StartPrbUl();
+            if (startPrbUl1.isArray()) {
+                if (ueList.size() == startPrbUl1.size()) {
+                    List<BerInteger> collect = Stream.of(startPrbUl1)
+                            .map(val -> new BerInteger(val.asInt()))
+                            .collect(Collectors.toList());
+                    startPrbUl.getBerInteger().clear();
+                    startPrbUl.getBerInteger().addAll(collect);
+                } else {
+                    throw new Exception("start_prb_ul size is not the same as UE size");
+                }
+            }
+            rrmConfig.setStartPrbUl(startPrbUl);
+        }
+
+        JsonNode endPrbUl1 = rrmConfigNode.path("end_prb_ul");
+        if (!endPrbUl1.isMissingNode()) {
+            RRMConfig.EndPrbUl endPrbUl = new RRMConfig.EndPrbUl();
+            if (endPrbUl1.isArray()) {
+                if (ueList.size() == endPrbUl1.size()) {
+                    List<BerInteger> collect = Stream.of(endPrbUl1)
+                            .map(val -> new BerInteger(val.asInt()))
+                            .collect(Collectors.toList());
+                    endPrbUl.getBerInteger().clear();
+                    endPrbUl.getBerInteger().addAll(collect);
+                } else {
+                    throw new Exception("end_prb_ul size is not the same as UE size");
+                }
+            }
+            rrmConfig.setEndPrbUl(endPrbUl);
+        }
+
+        JsonNode uePusch = rrmConfigNode.path("p0_ue_pusch");
+        if (!uePusch.isMissingNode()) {
+            RRMConfig.P0UePusch p0UePusch = new RRMConfig.P0UePusch();
+            if (uePusch.isArray()) {
+                if (ueList.size() == uePusch.size()) {
+                    List<BerInteger> collect = Stream.of(uePusch)
+                            .map(val -> new BerInteger(val.asInt()))
+                            .collect(Collectors.toList());
+                    p0UePusch.getBerInteger().clear();
+                    p0UePusch.getBerInteger().addAll(collect);
+                } else {
+                    throw new Exception("p0_ue_pusch size is not the same as UE size");
+                }
+            }
+            rrmConfig.setP0UePusch(p0UePusch);
+        }
+
+        JsonNode frameBitmaskUl = rrmConfigNode.path("sub_frame_bitmask_ul");
+        if (!frameBitmaskUl.isMissingNode()) {
+            RRMConfig.SubframeBitmaskUl subframeBitmaskUl = new RRMConfig.SubframeBitmaskUl();
+            if (frameBitmaskUl.isArray()) {
+                List<BerBitString> collect = Stream.of(frameBitmaskUl)
+                        .map(val -> new BerBitString(DatatypeConverter.parseHexBinary(val.asText()), 10))
+                        .collect(Collectors.toList());
+                subframeBitmaskUl.getBerBitString().clear();
+                subframeBitmaskUl.getBerBitString().addAll(collect);
+            } else {
+                throw new Exception("sub_frame_bitmask_ul size is not the same as UE size");
+            }
+            rrmConfig.setSubframeBitmaskUl(subframeBitmaskUl);
+        }
+
+        rrmConfig.setCrnti(crnti);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        RnibCell rnibCell = (RnibCell) o;
+
+        return ecgi.equals(rnibCell.ecgi);
+    }
+
+    @Override
+    public int hashCode() {
+        return ecgi.hashCode();
+    }
+
+    /**
+     * Object class for MeasConfig.
+     */
+    @JsonPropertyOrder({
+            "RRCMeasConfig",
+            "L2MeasConfig",
+            "timestamp"
+    })
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class MeasConfig {
+        @JsonProperty("timestamp")
+        WallClockTimestamp timestamp = new WallClockTimestamp();
+        @JsonProperty("RRCMeasConfig")
+        private RRCMeasConfig rrcMeasConfig;
+        @JsonProperty("L2MeasConfig")
+        private L2MeasConfig l2MeasConfig;
+
+        public MeasConfig() {
+        }
+
+        @JsonCreator
+        public MeasConfig(@JsonProperty("RRCMeasConfig") RRCMeasConfig rrcMeasConfig,
+                          @JsonProperty("L2MeasConfig") L2MeasConfig l2MeasConfig) {
+            this.rrcMeasConfig = rrcMeasConfig;
+            this.l2MeasConfig = l2MeasConfig;
+        }
+
+        public RRCMeasConfig getRrcMeasConfig() {
+            return rrcMeasConfig;
+        }
+
+        public void setRrcMeasConfig(RRCMeasConfig rrcMeasConfig) {
+            this.rrcMeasConfig = rrcMeasConfig;
+        }
+
+        public L2MeasConfig getL2MeasConfig() {
+            return l2MeasConfig;
+        }
+
+        public void setL2MeasConfig(L2MeasConfig l2MeasConfig) {
+            this.l2MeasConfig = l2MeasConfig;
+        }
+
+        public long getTimestamp() {
+            return new WallClockTimestamp().unixTimestamp() - timestamp.unixTimestamp();
+        }
+
+        public void setTimestamp(WallClockTimestamp timestamp) {
+            this.timestamp = timestamp;
+        }
+
+        @Override
+        public String toString() {
+            return "MeasConfig{" +
+                    "rrcMeasConfig=" + rrcMeasConfig +
+                    ", l2MeasConfig=" + l2MeasConfig +
+                    ", timestamp=" + getTimestamp() +
+                    '}';
+        }
+    }
+
+    /**
+     * Object class for PrbUsage.
+     */
+    @JsonPropertyOrder({
+            "UL-InterferenceMeasurement",
+            "PRB-Usage",
+    })
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class Measurements {
+        @JsonProperty("UL-InterferenceMeasurement")
+        ULInterferenceMeasurement ulInterferenceMeasurement = new ULInterferenceMeasurement();
+        @JsonProperty("PRB-Usage")
+        PrbUsage prbUsage = new PrbUsage();
+
+        public Measurements() {
+        }
+
+        @JsonCreator
+        public Measurements(
+                @JsonProperty("UL-InterferenceMeasurement") ULInterferenceMeasurement ulInterferenceMeasurement,
+                @JsonProperty("PRB-Usage") PrbUsage prbUsage
+        ) {
+            this.ulInterferenceMeasurement = ulInterferenceMeasurement;
+            this.prbUsage = prbUsage;
+        }
+
+        public ULInterferenceMeasurement getUlInterferenceMeasurement() {
+            return ulInterferenceMeasurement;
+        }
+
+        public void setUlInterferenceMeasurement(ULInterferenceMeasurement ulInterferenceMeasurement) {
+            this.ulInterferenceMeasurement = ulInterferenceMeasurement;
+        }
+
+        public PrbUsage getPrbUsage() {
+            return prbUsage;
+        }
+
+        public void setPrbUsage(PrbUsage prbUsage) {
+            this.prbUsage = prbUsage;
+        }
+
+        @Override
+        public String toString() {
+            return "Measurements{" +
+                    "ulInterferenceMeasurement=" + ulInterferenceMeasurement +
+                    ", prbUsage=" + prbUsage +
+                    '}';
+        }
+
+        /**
+         * Object class for PrbUsage.
+         */
+        @JsonPropertyOrder({
+                "PUSCH",
+                "PUCCH",
+                "timestamp"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class ULInterferenceMeasurement {
+            @JsonProperty("PUSCH")
+            RadioMeasReportPerCell.PuschIntfPowerHist pusch;
+            @JsonProperty("PUCCH")
+            RadioMeasReportPerCell.PucchIntfPowerHist pucch;
+            @JsonProperty("timestamp")
+            WallClockTimestamp timestamp = new WallClockTimestamp();
+
+            public ULInterferenceMeasurement() {
+            }
+
+            @JsonCreator
+            public ULInterferenceMeasurement(@JsonProperty("PUSCH") RadioMeasReportPerCell.PuschIntfPowerHist pusch,
+                                             @JsonProperty("PUCCH") RadioMeasReportPerCell.PucchIntfPowerHist pucch) {
+                this.pusch = pusch;
+                this.pucch = pucch;
+            }
+
+            public RadioMeasReportPerCell.PuschIntfPowerHist getPusch() {
+                return pusch;
+            }
+
+            public void setPusch(RadioMeasReportPerCell.PuschIntfPowerHist pusch) {
+                this.pusch = pusch;
+            }
+
+            public RadioMeasReportPerCell.PucchIntfPowerHist getPucch() {
+                return pucch;
+            }
+
+            public void setPucch(RadioMeasReportPerCell.PucchIntfPowerHist pucch) {
+                this.pucch = pucch;
+            }
+
+            public long getTimestamp() {
+                return new WallClockTimestamp().unixTimestamp() - timestamp.unixTimestamp();
+            }
+
+            public void setTimestamp(WallClockTimestamp timestamp) {
+                this.timestamp = timestamp;
+            }
+
+            @Override
+            public String toString() {
+                return "ULInterferenceMeasurement{" +
+                        "pusch=" + pusch +
+                        ", pucch=" + pucch +
+                        ", timestamp=" + getTimestamp() +
+                        '}';
+            }
+        }
+
+        /**
+         * Object class for PrbUsage.
+         */
+        @JsonPropertyOrder({
+                "QCI",
+                "primary",
+                "secondary",
+                "timestamp"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class PrbUsage {
+            @JsonProperty("QCI")
+            SchedMeasReportPerCell.QciVals qci;
+            @JsonProperty("primary")
+            PRBUsage primary;
+            @JsonProperty("secondary")
+            PRBUsage secondary;
+            @JsonProperty("timestamp")
+            WallClockTimestamp timestamp = new WallClockTimestamp();
+
+            public PrbUsage() {
+            }
+
+            @JsonCreator
+            public PrbUsage(
+                    @JsonProperty("QCI") SchedMeasReportPerCell.QciVals qci,
+                    @JsonProperty("primary") PRBUsage primary,
+                    @JsonProperty("secondary") PRBUsage secondary
+            ) {
+                this.qci = qci;
+                this.primary = primary;
+                this.secondary = secondary;
+            }
+
+            /**
+             * Get QCI
+             *
+             * @return QCI
+             */
+            public SchedMeasReportPerCell.QciVals getQci() {
+                return qci;
+            }
+
+            /**
+             * Set QCI.
+             *
+             * @param qci
+             */
+            public void setQci(SchedMeasReportPerCell.QciVals qci) {
+                this.qci = qci;
+            }
+
+            /**
+             * Get primary PrbUsage.
+             *
+             * @return PrbUsage
+             */
+            public PRBUsage getPrimary() {
+                return primary;
+            }
+
+            /**
+             * Set secondary PrbUsage.
+             *
+             * @param primary PrbUsage
+             */
+            public void setPrimary(PRBUsage primary) {
+                this.primary = primary;
+            }
+
+            /**
+             * Get secondary PrbUsage.
+             *
+             * @return PrbUsage
+             */
+            public PRBUsage getSecondary() {
+                return secondary;
+            }
+
+            /**
+             * Set secondary PrbUsage.
+             *
+             * @param secondary PrbUsage
+             */
+            public void setSecondary(PRBUsage secondary) {
+                this.secondary = secondary;
+            }
+
+            /**
+             * Get time since last update.
+             *
+             * @return long Time
+             */
+            public long getTimestamp() {
+                return new WallClockTimestamp().unixTimestamp() - timestamp.unixTimestamp();
+            }
+
+
+            /**
+             * Set time since last update.
+             *
+             * @param timestamp time since last update
+             */
+            public void setTimestamp(WallClockTimestamp timestamp) {
+                this.timestamp = timestamp;
+            }
+
+            @Override
+            public String toString() {
+                return "PrbUsage{" +
+                        "qci=" + qci +
+                        ", primary=" + primary +
+                        ", secondary=" + secondary +
+                        ", timestamp=" + getTimestamp() +
+                        '}';
+            }
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibLink.java b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibLink.java
new file mode 100644
index 0000000..8505aec
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibLink.java
@@ -0,0 +1,1418 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.entities;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Lists;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.xran.asn1lib.api.ERABParams;
+import org.onosproject.xran.asn1lib.api.PRBUsage;
+import org.onosproject.xran.asn1lib.api.RadioRepPerServCell;
+import org.onosproject.xran.asn1lib.api.SchedMeasRepPerServCell;
+import org.onosproject.xran.asn1lib.api.TrafficSplitPercentage;
+import org.onosproject.xran.asn1lib.api.XICICPA;
+import org.onosproject.xran.asn1lib.ber.types.BerBitString;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+import org.onosproject.xran.asn1lib.pdu.PDCPMeasReportPerUe;
+import org.onosproject.xran.asn1lib.pdu.RRMConfig;
+import org.onosproject.xran.asn1lib.pdu.RXSigMeasReport;
+import org.onosproject.xran.impl.identifiers.LinkId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.DatatypeConverter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * R-NIB Link and its properties.
+ */
+@JsonPropertyOrder({
+        "Link-ID",
+        "Type",
+        "RRMConfiguration",
+        "TrafficPercent",
+        "BearerParameters",
+        "Measurements"
+})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RnibLink {
+    @JsonIgnore
+    private static final Logger log =
+            LoggerFactory.getLogger(RnibLink.class);
+    @JsonProperty("Measurements")
+    private Measurements measurements = new Measurements();
+    @JsonProperty("Link-ID")
+    private LinkId linkId;
+    @JsonProperty("RRMConfiguration")
+    private RRMConfig rrmParameters;
+    @JsonProperty("TrafficPercent")
+    private TrafficSplitPercentage trafficPercent;
+    @JsonProperty("BearerParameters")
+    private ERABParams bearerParameters;
+    @JsonProperty("Type")
+    private Type type;
+    @JsonIgnore
+    private ScheduledExecutorService executor;
+
+    public RnibLink(RnibCell cell, RnibUe ue) {
+        trafficPercent = new TrafficSplitPercentage();
+        trafficPercent.setEcgi(cell.getEcgi());
+        trafficPercent.setTrafficPercentDl(new BerInteger(100));
+        trafficPercent.setTrafficPercentUl(new BerInteger(100));
+
+        executor = Executors.newSingleThreadScheduledExecutor();
+
+        type = Type.NON_SERVING;
+
+        linkId = LinkId.valueOf(cell, ue);
+
+        rrmParameters = new RRMConfig();
+        RRMConfig.Crnti crnti = new RRMConfig.Crnti();
+        crnti.getCRNTI().add(linkId.getUe().getCrnti());
+        rrmParameters.setCrnti(crnti);
+        rrmParameters.setEcgi(linkId.getEcgi());
+    }
+
+    /**
+     * Get executor.
+     *
+     * @return Timer
+     */
+    public ScheduledExecutorService getExecutor() {
+        return executor;
+    }
+
+    public void setExecutor(ScheduledExecutorService executor) {
+        this.executor.shutdown();
+        this.executor = executor;
+    }
+
+    /**
+     * Get Link ID.
+     *
+     * @return LinkID
+     */
+    @JsonProperty("Link-ID")
+    public LinkId getLinkId() {
+        return linkId;
+    }
+
+    /**
+     * Set the Link ID.
+     *
+     * @param linkId Link ID
+     */
+    @JsonProperty("Link-ID")
+    public void setLinkId(LinkId linkId) {
+        this.linkId = linkId;
+    }
+
+    /**
+     * Set the LINK ID with cell and ue.
+     *
+     * @param cell Rnib CELL
+     * @param ue   Rnib UE
+     */
+    public void setLinkId(RnibCell cell, RnibUe ue) {
+        this.linkId = LinkId.valueOf(cell, ue);
+        trafficPercent.setEcgi(cell.getEcgi());
+    }
+
+    /**
+     * Get the link type.
+     *
+     * @return Link-type
+     */
+    @JsonProperty("Type")
+    public Type getType() {
+        return type;
+    }
+
+    /**
+     * Set the link type.
+     *
+     * @param type Link-type
+     */
+    @JsonProperty("Type")
+    public void setType(Type type) {
+        this.type = type;
+    }
+
+    /**
+     * Get traffic percent.
+     *
+     * @return TrafficSplitPercentage
+     */
+    @JsonProperty("TrafficPercent")
+    public TrafficSplitPercentage getTrafficPercent() {
+        return trafficPercent;
+    }
+
+    /**
+     * Set traffic percent.
+     *
+     * @param trafficPercent TrafficSplitPercentage
+     */
+    @JsonProperty("TrafficPercent")
+    public void setTrafficPercent(TrafficSplitPercentage trafficPercent) {
+        this.trafficPercent = trafficPercent;
+    }
+
+    /**
+     * Get the Bearer Parameters.
+     *
+     * @return ERABParams
+     */
+    @JsonProperty("BearerParameters")
+    public ERABParams getBearerParameters() {
+        return bearerParameters;
+    }
+
+    /**
+     * Set the Bearer Parameters.
+     *
+     * @param bearerParameters ERABParams
+     */
+    @JsonProperty("BearerParameters")
+    public void setBearerParameters(ERABParams bearerParameters) {
+        this.bearerParameters = bearerParameters;
+    }
+
+    /**
+     * Get RRM Configuration.
+     *
+     * @return RRMConfig
+     */
+    @JsonProperty("RRMConfiguration")
+    public RRMConfig getRrmParameters() {
+        return rrmParameters;
+    }
+
+    /**
+     * Set RRM Configuration.
+     *
+     * @param rrmParameters RRMConfig
+     */
+    @JsonProperty("RRMConfiguration")
+    public void setRrmParameters(RRMConfig rrmParameters) {
+        this.rrmParameters = rrmParameters;
+    }
+
+    public Measurements getMeasurements() {
+        return measurements;
+    }
+
+    public void setMeasurements(Measurements measurements) {
+        this.measurements = measurements;
+    }
+
+    /**
+     * Modify the RRM Config parameters of link.
+     *
+     * @param rrmConfigNode RRMConfig parameters to modify obtained from REST call
+     */
+    public void modifyRrmParameters(JsonNode rrmConfigNode) {
+
+        JsonNode pA = rrmConfigNode.path("p_a");
+        if (!pA.isMissingNode()) {
+            RRMConfig.Pa pa = new RRMConfig.Pa();
+
+            List<XICICPA> collect = Lists.newArrayList();
+            collect.add(new XICICPA(pA.asInt()));
+            pa.getXICICPA().clear();
+            pa.getXICICPA().addAll(collect);
+
+            rrmParameters.setPa(pa);
+        }
+
+        JsonNode startPrbDl1 = rrmConfigNode.path("start_prb_dl");
+        if (!startPrbDl1.isMissingNode()) {
+            RRMConfig.StartPrbDl startPrbDl = new RRMConfig.StartPrbDl();
+
+            List<BerInteger> collect = Lists.newArrayList();
+            collect.add(new BerInteger(startPrbDl1.asInt()));
+            startPrbDl.getBerInteger().clear();
+            startPrbDl.getBerInteger().addAll(collect);
+
+            rrmParameters.setStartPrbDl(startPrbDl);
+        }
+
+        JsonNode endPrbDl1 = rrmConfigNode.path("end_prb_dl");
+        if (!endPrbDl1.isMissingNode()) {
+            RRMConfig.EndPrbDl endPrbDl = new RRMConfig.EndPrbDl();
+
+            List<BerInteger> collect = Lists.newArrayList();
+            collect.add(new BerInteger(endPrbDl1.asInt()));
+            endPrbDl.getBerInteger().clear();
+            endPrbDl.getBerInteger().addAll(collect);
+
+            rrmParameters.setEndPrbDl(endPrbDl);
+        }
+
+        JsonNode subFrameBitmaskDl = rrmConfigNode.path("sub_frame_bitmask_dl");
+        if (!subFrameBitmaskDl.isMissingNode()) {
+            RRMConfig.SubframeBitmaskDl subframeBitmaskDl = new RRMConfig.SubframeBitmaskDl();
+            List<BerBitString> collect = Lists.newArrayList();
+
+            byte[] hexString = DatatypeConverter.parseHexBinary(subFrameBitmaskDl.asText());
+            collect.add(new BerBitString(hexString, 10));
+            subframeBitmaskDl.getBerBitString().clear();
+            subframeBitmaskDl.getBerBitString().addAll(collect);
+
+            rrmParameters.setSubframeBitmaskDl(subframeBitmaskDl);
+        }
+
+        JsonNode startPrbUl1 = rrmConfigNode.path("start_prb_ul");
+        if (!startPrbUl1.isMissingNode()) {
+            RRMConfig.StartPrbUl startPrbUl = new RRMConfig.StartPrbUl();
+
+            List<BerInteger> collect = Lists.newArrayList();
+            collect.add(new BerInteger(startPrbUl1.asInt()));
+            startPrbUl.getBerInteger().clear();
+            startPrbUl.getBerInteger().addAll(collect);
+
+            rrmParameters.setStartPrbUl(startPrbUl);
+        }
+
+        JsonNode endPrbUl1 = rrmConfigNode.path("end_prb_ul");
+        if (!endPrbUl1.isMissingNode()) {
+            RRMConfig.EndPrbUl endPrbUl = new RRMConfig.EndPrbUl();
+
+            List<BerInteger> collect = Lists.newArrayList();
+            collect.add(new BerInteger(endPrbUl1.asInt()));
+            endPrbUl.getBerInteger().clear();
+            endPrbUl.getBerInteger().addAll(collect);
+
+            rrmParameters.setEndPrbUl(endPrbUl);
+        }
+
+
+        JsonNode p0UePusch1 = rrmConfigNode.path("p0_ue_pusch");
+        if (!p0UePusch1.isMissingNode()) {
+            RRMConfig.P0UePusch p0UePusch = new RRMConfig.P0UePusch();
+
+            List<BerInteger> collect = Lists.newArrayList();
+            collect.add(new BerInteger(p0UePusch1.asInt()));
+            p0UePusch.getBerInteger().clear();
+            p0UePusch.getBerInteger().addAll(collect);
+
+            rrmParameters.setP0UePusch(p0UePusch);
+        }
+
+        JsonNode subFrameBitmaskUl = rrmConfigNode.path("sub_frame_bitmask_ul");
+        if (!subFrameBitmaskUl.isMissingNode()) {
+            RRMConfig.SubframeBitmaskUl subframeBitmaskUl = new RRMConfig.SubframeBitmaskUl();
+            List<BerBitString> collect = Lists.newArrayList();
+
+            byte[] hexString = DatatypeConverter.parseHexBinary(subFrameBitmaskUl.asText());
+            collect.add(new BerBitString(hexString, 10));
+            subframeBitmaskUl.getBerBitString().clear();
+            subframeBitmaskUl.getBerBitString().addAll(collect);
+
+            rrmParameters.setSubframeBitmaskUl(subframeBitmaskUl);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "RnibLink{" +
+                "measurements=" + measurements +
+                ", linkId=" + linkId +
+                ", rrmParameters=" + rrmParameters +
+                ", trafficPercent=" + trafficPercent +
+                ", bearerParameters=" + bearerParameters +
+                ", type=" + type +
+                '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        RnibLink link = (RnibLink) o;
+
+        return linkId.equals(link.linkId);
+    }
+
+    @Override
+    public int hashCode() {
+        return linkId.hashCode();
+    }
+
+    /**
+     * Enum of Link-Type.
+     */
+    public enum Type {
+        SERVING_PRIMARY("serving/primary") {
+            @Override
+            public String toString() {
+                return "serving/primary";
+            }
+        },
+        SERVING_SECONDARY_CA("serving/secondary/ca") {
+            @Override
+            public String toString() {
+                return "serving/secondary/ca";
+            }
+        },
+        SERVING_SECONDARY_DC("serving/secondary/dc") {
+            @Override
+            public String toString() {
+                return "serving/secondary/dc";
+            }
+        },
+        NON_SERVING("non-serving") {
+            @Override
+            public String toString() {
+                return "non-serving";
+            }
+        };
+
+        private String name;
+
+        Type(String name) {
+            this.name = name;
+        }
+
+        /**
+         * Get enum value of link-type.
+         *
+         * @param name String representation of Enum Type
+         * @return Type
+         */
+        public static Type getEnum(String name) {
+            Optional<Type> any = Arrays.stream(Type.values()).filter(typeStr -> typeStr.name.equals(name)).findAny();
+            if (any.isPresent()) {
+                return any.get();
+            }
+            throw new IllegalArgumentException("No enum defined for string: " + name);
+        }
+    }
+
+    @JsonPropertyOrder({
+            "RXSigReport",
+            "RadioReport",
+            "SchedMeasReport",
+            "PDCPMeasReport",
+
+    })
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class Measurements {
+        @JsonProperty("RXSigReport")
+        RXSigReport rxSigReport = new RXSigReport();
+        @JsonProperty("RadioReport")
+        RadioReport radioReport = new RadioReport();
+        @JsonProperty("SchedMeasReport")
+        SchedMeasReport schedMeasReport = new SchedMeasReport();
+        @JsonProperty("PDCPMeasReport")
+        PdcpMeasReport pdcpMeasReport = new PdcpMeasReport();
+
+        public Measurements() {
+        }
+
+        @JsonCreator
+        public Measurements(@JsonProperty("RXSigReport") RXSigReport rxSigReport,
+                            @JsonProperty("RadioReport") RadioReport radioReport,
+                            @JsonProperty("SchedMeasReport") SchedMeasReport schedMeasReport,
+                            @JsonProperty("PDCPMeasReport") PdcpMeasReport pdcpMeasReport) {
+            this.rxSigReport = rxSigReport;
+            this.radioReport = radioReport;
+            this.schedMeasReport = schedMeasReport;
+            this.pdcpMeasReport = pdcpMeasReport;
+        }
+
+        public RXSigReport getRxSigReport() {
+            return rxSigReport;
+        }
+
+        public void setRxSigReport(RXSigReport rxSigReport) {
+            this.rxSigReport = rxSigReport;
+        }
+
+        public RadioReport getRadioReport() {
+            return radioReport;
+        }
+
+        public void setRadioReport(RadioReport radioReport) {
+            this.radioReport = radioReport;
+        }
+
+        public SchedMeasReport getSchedMeasReport() {
+            return schedMeasReport;
+        }
+
+        public void setSchedMeasReport(SchedMeasReport schedMeasReport) {
+            this.schedMeasReport = schedMeasReport;
+        }
+
+        public PdcpMeasReport getPdcpMeasReport() {
+            return pdcpMeasReport;
+        }
+
+        public void setPdcpMeasReport(PdcpMeasReport pdcpMeasReport) {
+            this.pdcpMeasReport = pdcpMeasReport;
+        }
+
+        @Override
+        public String toString() {
+            return "Measurements{" +
+                    "rxSigReport=" + rxSigReport +
+                    ", radioReport=" + radioReport +
+                    ", schedMeasReport=" + schedMeasReport +
+                    ", pdcpMeasReport=" + pdcpMeasReport +
+                    '}';
+        }
+
+        @JsonPropertyOrder({
+                "RSRP",
+                "RSRQ",
+                "meas-id",
+                "timestamp"
+        })
+        public static class RXSigReport {
+            @JsonProperty("RSRP")
+            double rsrp;
+            @JsonProperty("RSRQ")
+            double rsrq;
+            @JsonProperty("meas-id")
+            RXSigMeasReport.CellMeasReports measReports;
+            @JsonProperty("timestamp")
+            WallClockTimestamp timesincelastupdate = new WallClockTimestamp();
+
+            public RXSigReport() {
+            }
+
+            @JsonCreator
+            public RXSigReport(@JsonProperty("RSRP") double rsrp,
+                               @JsonProperty("RSRQ") double rsrq,
+                               @JsonProperty("meas-id") RXSigMeasReport.CellMeasReports measReports
+            ) {
+                this.rsrp = rsrp;
+                this.rsrq = rsrq;
+                this.measReports = measReports;
+            }
+
+            /**
+             * Get rsrp.
+             *
+             * @return double rsrp
+             */
+            public double getRsrp() {
+                return rsrp;
+            }
+
+            /**
+             * Set rsrp.
+             *
+             * @param rsrp rsrp
+             */
+            public void setRsrp(double rsrp) {
+                this.rsrp = rsrp;
+            }
+
+            /**
+             * Get rsrq.
+             *
+             * @return double rsrq
+             */
+            public double getRsrq() {
+                return rsrq;
+            }
+
+            /**
+             * Set rsrq.
+             *
+             * @param rsrq rsrq
+             */
+            public void setRsrq(double rsrq) {
+                this.rsrq = rsrq;
+            }
+
+            /**
+             * Get time since last update.
+             *
+             * @return long Time
+             */
+            public long getTimesincelastupdate() {
+                return new WallClockTimestamp().unixTimestamp() - timesincelastupdate.unixTimestamp();
+            }
+
+            /**
+             * Set time since last update.
+             *
+             * @param timesincelastupdate time since last update
+             */
+            public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+                this.timesincelastupdate = timesincelastupdate;
+            }
+
+            public RXSigMeasReport.CellMeasReports getMeasReports() {
+                return measReports;
+            }
+
+            public void setMeasReports(RXSigMeasReport.CellMeasReports measReports) {
+                this.measReports = measReports;
+            }
+
+            @Override
+            public String toString() {
+                return "RXSigReport{" +
+                        "rsrp=" + rsrp +
+                        ", rsrq=" + rsrq +
+                        ", measReports=" + measReports +
+                        ", timestamp=" + getTimesincelastupdate() +
+                        '}';
+            }
+        }
+
+        @JsonPropertyOrder({
+                "CQI",
+                "Rank_hist",
+                "Pusch_sinr_hist",
+                "Pucch_sinr_hist",
+                "timestamp"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class RadioReport {
+            @JsonProperty("CQI")
+            Cqi cqi = new Cqi();
+            @JsonProperty("Rank_hist")
+            RadioRepPerServCell.RiHist riHist;
+            @JsonProperty("Pucch_sinr_hist")
+            RadioRepPerServCell.PucchSinrHist pucchSinrHist;
+            @JsonProperty("Pusch_sinr_hist")
+            RadioRepPerServCell.PuschSinrHist puschSinrHist;
+            @JsonProperty("timestamp")
+            WallClockTimestamp timesincelastupdate = new WallClockTimestamp();
+
+            public RadioReport() {
+            }
+
+            @JsonCreator
+            public RadioReport(@JsonProperty("CQI") Cqi cqi,
+                               @JsonProperty("Rank_hist") RadioRepPerServCell.RiHist riHist,
+                               @JsonProperty("Pucch_sinr_hist") RadioRepPerServCell.PucchSinrHist pucchSinrHist,
+                               @JsonProperty("Pusch_sinr_hist") RadioRepPerServCell.PuschSinrHist puschSinrHist) {
+                this.cqi = cqi;
+                this.riHist = riHist;
+                this.pucchSinrHist = pucchSinrHist;
+                this.puschSinrHist = puschSinrHist;
+            }
+
+            public Cqi getCqi() {
+                return cqi;
+            }
+
+            public void setCqi(Cqi cqi) {
+                this.cqi = cqi;
+            }
+
+            public RadioRepPerServCell.RiHist getRiHist() {
+                return riHist;
+            }
+
+            public void setRiHist(RadioRepPerServCell.RiHist riHist) {
+                this.riHist = riHist;
+            }
+
+            public RadioRepPerServCell.PucchSinrHist getPucchSinrHist() {
+                return pucchSinrHist;
+            }
+
+            public void setPucchSinrHist(RadioRepPerServCell.PucchSinrHist pucchSinrHist) {
+                this.pucchSinrHist = pucchSinrHist;
+            }
+
+            public RadioRepPerServCell.PuschSinrHist getPuschSinrHist() {
+                return puschSinrHist;
+            }
+
+            public void setPuschSinrHist(RadioRepPerServCell.PuschSinrHist puschSinrHist) {
+                this.puschSinrHist = puschSinrHist;
+            }
+
+            /**
+             * Get time since last update.
+             *
+             * @return long Time
+             */
+            public long getTimesincelastupdate() {
+                return new WallClockTimestamp().unixTimestamp() - timesincelastupdate.unixTimestamp();
+            }
+
+            public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+                this.timesincelastupdate = timesincelastupdate;
+            }
+
+            @Override
+            public String toString() {
+                return "RadioReport{" +
+                        "cqi=" + cqi +
+                        ", riHist=" + riHist +
+                        ", pucchSinrHist=" + pucchSinrHist +
+                        ", puschSinrHist=" + puschSinrHist +
+                        ", timestamp=" + getTimesincelastupdate() +
+                        '}';
+            }
+
+            @JsonPropertyOrder({
+                    "Hist",
+                    "Mode",
+                    "Mean",
+                    "timestamp"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class Cqi {
+                @JsonProperty("Hist")
+                RadioRepPerServCell.CqiHist hist;
+                @JsonProperty("Mode")
+                double mode;
+                @JsonProperty("Mean")
+                double mean;
+
+                public Cqi() {
+                }
+
+                @JsonCreator
+                public Cqi(@JsonProperty("Hist") RadioRepPerServCell.CqiHist hist,
+                           @JsonProperty("Mode") double mode,
+                           @JsonProperty("Mean") double mean) {
+                    this.hist = hist;
+                    this.mode = mode;
+                    this.mean = mean;
+                }
+
+                /**
+                 * Get CQIHist.
+                 *
+                 * @return CqiHist
+                 */
+                public RadioRepPerServCell.CqiHist getHist() {
+                    return hist;
+                }
+
+                /**
+                 * Get CQIHist.
+                 *
+                 * @param hist CqiHist
+                 */
+                public void setHist(RadioRepPerServCell.CqiHist hist) {
+                    this.hist = hist;
+                }
+
+                /**
+                 * Get mode.
+                 *
+                 * @return double mode
+                 */
+                public double getMode() {
+                    return mode;
+                }
+
+                /**
+                 * Set mode.
+                 *
+                 * @param mode mode
+                 */
+                public void setMode(double mode) {
+                    this.mode = mode;
+                }
+
+                /**
+                 * Get mean.
+                 *
+                 * @return double mean
+                 */
+                public double getMean() {
+                    return mean;
+                }
+
+                /**
+                 * Set mean.
+                 *
+                 * @param mean mean
+                 */
+                public void setMean(double mean) {
+                    this.mean = mean;
+                }
+
+                @Override
+                public String toString() {
+                    return "Cqi{" +
+                            "hist=" + hist +
+                            ", mode=" + mode +
+                            ", mean=" + mean +
+                            '}';
+                }
+            }
+        }
+
+        @JsonPropertyOrder({
+                "QCI",
+                "ResourceUsage",
+                "MCS",
+                "Num_Sched_TTIs",
+                "DL_rank_stats",
+                "timestamp"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class SchedMeasReport {
+            @JsonProperty("QCI")
+            SchedMeasRepPerServCell.QciVals qci;
+            @JsonProperty("ResourceUsage")
+            ResourceUsage resourceUsage = new ResourceUsage();
+            @JsonProperty("MCS")
+            Mcs mcs = new Mcs();
+            @JsonProperty("Num_Sched_TTIs")
+            NumSchedTtis numSchedTtis = new NumSchedTtis();
+            @JsonProperty("DL_rank_stats")
+            DlRankStats dlRankStats = new DlRankStats();
+            @JsonProperty("timestamp")
+            WallClockTimestamp timesincelastupdate = new WallClockTimestamp();
+
+            public SchedMeasReport() {
+            }
+
+            @JsonCreator
+            public SchedMeasReport(
+                    @JsonProperty("QCI") SchedMeasRepPerServCell.QciVals qci,
+                    @JsonProperty("ResourceUsage") ResourceUsage resourceUsage,
+                    @JsonProperty("MCS") Mcs mcs,
+                    @JsonProperty("Num_Sched_TTIs") NumSchedTtis numSchedTtis,
+                    @JsonProperty("DL_rank_stats") DlRankStats dlRankStats
+            ) {
+                this.qci = qci;
+                this.resourceUsage = resourceUsage;
+                this.mcs = mcs;
+                this.numSchedTtis = numSchedTtis;
+                this.dlRankStats = dlRankStats;
+            }
+
+            public SchedMeasRepPerServCell.QciVals getQci() {
+                return qci;
+            }
+
+            public void setQci(SchedMeasRepPerServCell.QciVals qci) {
+                this.qci = qci;
+            }
+
+            public ResourceUsage getResourceUsage() {
+                return resourceUsage;
+            }
+
+            public void setResourceUsage(ResourceUsage resourceUsage) {
+                this.resourceUsage = resourceUsage;
+            }
+
+            public Mcs getMcs() {
+                return mcs;
+            }
+
+            public void setMcs(Mcs mcs) {
+                this.mcs = mcs;
+            }
+
+            public NumSchedTtis getNumSchedTtis() {
+                return numSchedTtis;
+            }
+
+            public void setNumSchedTtis(NumSchedTtis numSchedTtis) {
+                this.numSchedTtis = numSchedTtis;
+            }
+
+            public DlRankStats getDlRankStats() {
+                return dlRankStats;
+            }
+
+            public void setDlRankStats(DlRankStats dlRankStats) {
+                this.dlRankStats = dlRankStats;
+            }
+
+            public long getTimesincelastupdate() {
+                return new WallClockTimestamp().unixTimestamp() - timesincelastupdate.unixTimestamp();
+            }
+
+            public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+                this.timesincelastupdate = timesincelastupdate;
+            }
+
+            @Override
+            public String toString() {
+                return "SchedMeasReport{" +
+                        "qci=" + qci +
+                        ", resourceUsage=" + resourceUsage +
+                        ", mcs=" + mcs +
+                        ", numSchedTtis=" + numSchedTtis +
+                        ", dlRankStats=" + dlRankStats +
+                        ", timesincelastupdate=" + getTimesincelastupdate() +
+                        '}';
+            }
+
+            @JsonPropertyOrder({
+                    "dl",
+                    "ul"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class ResourceUsage {
+                @JsonProperty("dl")
+                PRBUsage.PrbUsageDl dl;
+                @JsonProperty("ul")
+                PRBUsage.PrbUsageUl ul;
+
+                public ResourceUsage() {
+                }
+
+                @JsonCreator
+                public ResourceUsage(@JsonProperty("dl") PRBUsage.PrbUsageDl dl,
+                                     @JsonProperty("ul") PRBUsage.PrbUsageUl ul) {
+                    this.dl = dl;
+                    this.ul = ul;
+                }
+
+                /**
+                 * Get DL.
+                 *
+                 * @return Dl
+                 */
+                public PRBUsage.PrbUsageDl getDl() {
+                    return dl;
+                }
+
+                /**
+                 * Set DL.
+                 *
+                 * @param dl DL
+                 */
+                public void setDl(PRBUsage.PrbUsageDl dl) {
+                    this.dl = dl;
+                }
+
+                /**
+                 * Get UL.
+                 *
+                 * @return Ul
+                 */
+                public PRBUsage.PrbUsageUl getUl() {
+                    return ul;
+                }
+
+                /**
+                 * Set UL.
+                 *
+                 * @param ul Ul
+                 */
+                public void setUl(PRBUsage.PrbUsageUl ul) {
+                    this.ul = ul;
+                }
+
+                @Override
+                public String toString() {
+                    return "ResourceUsage{" +
+                            "dl=" + dl +
+                            ", ul=" + ul +
+                            '}';
+                }
+            }
+
+            @JsonPropertyOrder({
+                    "dl",
+                    "ul"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class Mcs {
+                SchedMeasRepPerServCell.McsDl dl;
+                SchedMeasRepPerServCell.McsUl ul;
+
+                public Mcs() {
+                }
+
+                @JsonCreator
+                public Mcs(@JsonProperty("dl") SchedMeasRepPerServCell.McsDl dl,
+                           @JsonProperty("ul") SchedMeasRepPerServCell.McsUl ul) {
+                    this.dl = dl;
+                    this.ul = ul;
+                }
+
+                /**
+                 * Get DL.
+                 *
+                 * @return Dl
+                 */
+                public SchedMeasRepPerServCell.McsDl getDl() {
+                    return dl;
+                }
+
+                /**
+                 * Set DL.
+                 *
+                 * @param dl DL
+                 */
+                public void setDl(SchedMeasRepPerServCell.McsDl dl) {
+                    this.dl = dl;
+                }
+
+                /**
+                 * Get UL.
+                 *
+                 * @return Ul
+                 */
+                public SchedMeasRepPerServCell.McsUl getUl() {
+                    return ul;
+                }
+
+                /**
+                 * Set UL.
+                 *
+                 * @param ul Ul
+                 */
+                public void setUl(SchedMeasRepPerServCell.McsUl ul) {
+                    this.ul = ul;
+                }
+
+                @Override
+                public String toString() {
+                    return "mcs{" +
+                            "dl=" + dl +
+                            ", ul=" + ul +
+                            '}';
+                }
+            }
+
+            @JsonPropertyOrder({
+                    "dl",
+                    "ul"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class NumSchedTtis {
+                @JsonProperty("dl")
+                SchedMeasRepPerServCell.NumSchedTtisDl dl;
+                @JsonProperty("ul")
+                SchedMeasRepPerServCell.NumSchedTtisUl ul;
+
+                public NumSchedTtis() {
+                }
+
+                @JsonCreator
+                public NumSchedTtis(@JsonProperty("dl") SchedMeasRepPerServCell.NumSchedTtisDl dl,
+                                    @JsonProperty("ul") SchedMeasRepPerServCell.NumSchedTtisUl ul) {
+                    this.dl = dl;
+                    this.ul = ul;
+                }
+
+                public SchedMeasRepPerServCell.NumSchedTtisDl getDl() {
+                    return dl;
+                }
+
+                public void setDl(SchedMeasRepPerServCell.NumSchedTtisDl dl) {
+                    this.dl = dl;
+                }
+
+                public SchedMeasRepPerServCell.NumSchedTtisUl getUl() {
+                    return ul;
+                }
+
+                public void setUl(SchedMeasRepPerServCell.NumSchedTtisUl ul) {
+                    this.ul = ul;
+                }
+
+                @Override
+                public String toString() {
+                    return "NumSchedTtis{" +
+                            "dl=" + dl +
+                            ", ul=" + ul +
+                            '}';
+                }
+            }
+
+            @JsonPropertyOrder({
+                    "Rank-1",
+                    "Rank-2"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class DlRankStats {
+                @JsonProperty("Rank-1")
+                SchedMeasRepPerServCell.RankDl1 rankDl1;
+                @JsonProperty("Rank-2")
+                SchedMeasRepPerServCell.RankDl2 rankDl2;
+
+                public DlRankStats() {
+                }
+
+                @JsonCreator
+                public DlRankStats(@JsonProperty("Rank-1") SchedMeasRepPerServCell.RankDl1 rankDl1,
+                                   @JsonProperty("Rank-2") SchedMeasRepPerServCell.RankDl2 rankDl2) {
+                    this.rankDl1 = rankDl1;
+                    this.rankDl2 = rankDl2;
+                }
+
+                public SchedMeasRepPerServCell.RankDl1 getRankDl1() {
+                    return rankDl1;
+                }
+
+                public void setRankDl1(SchedMeasRepPerServCell.RankDl1 rankDl1) {
+                    this.rankDl1 = rankDl1;
+                }
+
+                public SchedMeasRepPerServCell.RankDl2 getRankDl2() {
+                    return rankDl2;
+                }
+
+                public void setRankDl2(SchedMeasRepPerServCell.RankDl2 rankDl2) {
+                    this.rankDl2 = rankDl2;
+                }
+
+                @Override
+                public String toString() {
+                    return "DlRankStats{" +
+                            "rankDl1=" + rankDl1 +
+                            ", rankDl2=" + rankDl2 +
+                            '}';
+                }
+            }
+        }
+
+        @JsonPropertyOrder({
+                "QCI",
+                "PDCPThroughput",
+                "Data_vol",
+                "Pkt_delay_dl",
+                "Pkt_discard_rate_dl",
+                "Pkt_loss_rate",
+                "timestamp"
+        })
+        @JsonIgnoreProperties(ignoreUnknown = true)
+        public static class PdcpMeasReport {
+            @JsonProperty("QCI")
+            PDCPMeasReportPerUe.QciVals qci = new PDCPMeasReportPerUe.QciVals();
+            @JsonProperty("PDCPThroughput")
+            PdcpThroughput pdcpThroughput = new PdcpThroughput();
+            @JsonProperty("Data_vol")
+            DataVol dataVol = new DataVol();
+            @JsonProperty("Pkt_delay_dl")
+            PDCPMeasReportPerUe.PktDelayDl pktDelayDl;
+            @JsonProperty("Pkt_discard_rate_dl")
+            PDCPMeasReportPerUe.PktDiscardRateDl pktDiscardRateDl;
+            @JsonProperty("Pkt_loss_rate")
+            PktLossRate pktLossRate = new PktLossRate();
+            @JsonProperty("timestamp")
+            WallClockTimestamp timesincelastupdate = new WallClockTimestamp();
+
+            public PdcpMeasReport() {
+            }
+
+            @JsonCreator
+            public PdcpMeasReport(
+                    @JsonProperty("QCI") PDCPMeasReportPerUe.QciVals qci,
+                    @JsonProperty("PDCPThroughput") PdcpThroughput pdcpThroughput,
+                    @JsonProperty("Data_vol") DataVol dataVol,
+                    @JsonProperty("Pkt_delay_dl") PDCPMeasReportPerUe.PktDelayDl pktDelayDl,
+                    @JsonProperty("Pkt_discard_rate_dl") PDCPMeasReportPerUe.PktDiscardRateDl pktDiscardRateDl,
+                    @JsonProperty("Pkt_loss_rate") PktLossRate pktLossRate
+            ) {
+                this.qci = qci;
+                this.pdcpThroughput = pdcpThroughput;
+                this.dataVol = dataVol;
+                this.pktDelayDl = pktDelayDl;
+                this.pktDiscardRateDl = pktDiscardRateDl;
+                this.pktLossRate = pktLossRate;
+            }
+
+            public PDCPMeasReportPerUe.QciVals getQci() {
+                return qci;
+            }
+
+            public void setQci(PDCPMeasReportPerUe.QciVals qci) {
+                this.qci = qci;
+            }
+
+            public PdcpThroughput getPdcpThroughput() {
+                return pdcpThroughput;
+            }
+
+            public void setPdcpThroughput(PdcpThroughput pdcpThroughput) {
+                this.pdcpThroughput = pdcpThroughput;
+            }
+
+            public DataVol getDataVol() {
+                return dataVol;
+            }
+
+            public void setDataVol(DataVol dataVol) {
+                this.dataVol = dataVol;
+            }
+
+            public PDCPMeasReportPerUe.PktDelayDl getPktDelayDl() {
+                return pktDelayDl;
+            }
+
+            public void setPktDelayDl(PDCPMeasReportPerUe.PktDelayDl pktDelayDl) {
+                this.pktDelayDl = pktDelayDl;
+            }
+
+            public PDCPMeasReportPerUe.PktDiscardRateDl getPktDiscardRateDl() {
+                return pktDiscardRateDl;
+            }
+
+            public void setPktDiscardRateDl(PDCPMeasReportPerUe.PktDiscardRateDl pktDiscardRateDl) {
+                this.pktDiscardRateDl = pktDiscardRateDl;
+            }
+
+            public PktLossRate getPktLossRate() {
+                return pktLossRate;
+            }
+
+            public void setPktLossRate(PktLossRate pktLossRate) {
+                this.pktLossRate = pktLossRate;
+            }
+
+            public long getTimesincelastupdate() {
+                return new WallClockTimestamp().unixTimestamp() - timesincelastupdate.unixTimestamp();
+            }
+
+            public void setTimesincelastupdate(WallClockTimestamp timesincelastupdate) {
+                this.timesincelastupdate = timesincelastupdate;
+            }
+
+            @Override
+            public String toString() {
+                return "PdcpMeasReport{" +
+                        "qci=" + qci +
+                        ", pdcpThroughput=" + pdcpThroughput +
+                        ", dataVol=" + dataVol +
+                        ", pktDelayDl=" + pktDelayDl +
+                        ", pktDiscardRateDl=" + pktDiscardRateDl +
+                        ", pktLossRate=" + pktLossRate +
+                        ", timesincelastupdate=" + getTimesincelastupdate() +
+                        '}';
+            }
+
+            @JsonPropertyOrder({
+                    "dl",
+                    "ul"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class PdcpThroughput {
+                @JsonProperty("dl")
+                private PDCPMeasReportPerUe.ThroughputDl dl;
+                @JsonProperty("ul")
+                private PDCPMeasReportPerUe.ThroughputUl ul;
+
+                public PdcpThroughput() {
+                }
+
+                @JsonCreator
+                public PdcpThroughput(@JsonProperty("dl") PDCPMeasReportPerUe.ThroughputDl dl,
+                                      @JsonProperty("ul") PDCPMeasReportPerUe.ThroughputUl ul) {
+                    this.dl = dl;
+                    this.ul = ul;
+                }
+
+                /**
+                 * Get DL.
+                 *
+                 * @return Dl
+                 */
+                public PDCPMeasReportPerUe.ThroughputDl getDl() {
+                    return dl;
+                }
+
+                /**
+                 * Set DL.
+                 *
+                 * @param dl DL
+                 */
+                public void setDl(PDCPMeasReportPerUe.ThroughputDl dl) {
+                    this.dl = dl;
+                }
+
+                /**
+                 * Get UL.
+                 *
+                 * @return Ul
+                 */
+                public PDCPMeasReportPerUe.ThroughputUl getUl() {
+                    return ul;
+                }
+
+                /**
+                 * Set UL.
+                 *
+                 * @param ul Ul
+                 */
+                public void setUl(PDCPMeasReportPerUe.ThroughputUl ul) {
+                    this.ul = ul;
+                }
+
+                @Override
+                public String
+                toString() {
+                    return "PdcpThroughput{" +
+                            "dl=" + dl +
+                            ", ul=" + ul +
+                            '}';
+                }
+            }
+
+            @JsonPropertyOrder({
+                    "dl",
+                    "ul"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class DataVol {
+                @JsonProperty("dl")
+                private PDCPMeasReportPerUe.DataVolDl dl;
+                @JsonProperty("ul")
+                private PDCPMeasReportPerUe.DataVolUl ul;
+
+                public DataVol() {
+                }
+
+                @JsonCreator
+                public DataVol(@JsonProperty("dl") PDCPMeasReportPerUe.DataVolDl dl,
+                               @JsonProperty("ul") PDCPMeasReportPerUe.DataVolUl ul) {
+                    this.dl = dl;
+                    this.ul = ul;
+                }
+
+                /**
+                 * Get DL.
+                 *
+                 * @return Dl
+                 */
+                public PDCPMeasReportPerUe.DataVolDl getDl() {
+                    return dl;
+                }
+
+                /**
+                 * Set DL.
+                 *
+                 * @param dl DL
+                 */
+                public void setDl(PDCPMeasReportPerUe.DataVolDl dl) {
+                    this.dl = dl;
+                }
+
+                /**
+                 * Get UL.
+                 *
+                 * @return Ul
+                 */
+                public PDCPMeasReportPerUe.DataVolUl getUl() {
+                    return ul;
+                }
+
+                /**
+                 * Set UL.
+                 *
+                 * @param ul Ul
+                 */
+                public void setUl(PDCPMeasReportPerUe.DataVolUl ul) {
+                    this.ul = ul;
+                }
+
+                @Override
+                public String
+                toString() {
+                    return "PdcpThroughput{" +
+                            "dl=" + dl +
+                            ", ul=" + ul +
+                            '}';
+                }
+            }
+
+            @JsonPropertyOrder({
+                    "dl",
+                    "ul"
+            })
+            @JsonIgnoreProperties(ignoreUnknown = true)
+            public static class PktLossRate {
+                @JsonProperty("dl")
+                PDCPMeasReportPerUe.PktLossRateDl dl;
+                @JsonProperty("ul")
+                PDCPMeasReportPerUe.PktLossRateUl ul;
+
+                public PktLossRate() {
+                }
+
+                @JsonCreator
+                public PktLossRate(@JsonProperty("dl") PDCPMeasReportPerUe.PktLossRateDl dl,
+                                   @JsonProperty("ul") PDCPMeasReportPerUe.PktLossRateUl ul) {
+                    this.dl = dl;
+                    this.ul = ul;
+                }
+
+                /**
+                 * Get DL.
+                 *
+                 * @return Dl
+                 */
+                public PDCPMeasReportPerUe.PktLossRateDl getDl() {
+                    return dl;
+                }
+
+                /**
+                 * Set DL.
+                 *
+                 * @param dl DL
+                 */
+                public void setDl(PDCPMeasReportPerUe.PktLossRateDl dl) {
+                    this.dl = dl;
+                }
+
+                /**
+                 * Get UL.
+                 *
+                 * @return Ul
+                 */
+                public PDCPMeasReportPerUe.PktLossRateUl getUl() {
+                    return ul;
+                }
+
+                /**
+                 * Set UL.
+                 *
+                 * @param ul Ul
+                 */
+                public void setUl(PDCPMeasReportPerUe.PktLossRateUl ul) {
+                    this.ul = ul;
+                }
+
+                @Override
+                public String toString() {
+                    return "PdcpPacketdelay{" +
+                            "dl=" + dl +
+                            ", ul=" + ul +
+                            '}';
+                }
+            }
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibSlice.java b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibSlice.java
new file mode 100644
index 0000000..f8cb470
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibSlice.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.entities;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+import java.util.Set;
+
+/**
+ * Created by dimitris on 7/22/17.
+ */
+@JsonPropertyOrder({
+        "Identifier",
+        "Description",
+        "UE-IDs",
+        "Links",
+        "ValidityPeriod",
+        "DesiredKPIs",
+        "DeliveredKPIs",
+        "RRMConfiguration"
+})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RnibSlice {
+    @JsonProperty("Identifier")
+    private long sliceId;
+    @JsonProperty("Description")
+    private String description;
+    @JsonProperty("UE-IDs")
+    private Set<Long> ueID;
+    @JsonProperty("Links")
+    private Set<RnibLink> links;
+    @JsonProperty("ValidityPeriod")
+    private long validityPeriod;
+    @JsonProperty("DesiredKPIs")
+    private Object desiredKpis;
+    @JsonProperty("DeliveredKPIs")
+    private Object deliveredKpis;
+    @JsonProperty("RRMConfiguration")
+    private Object rrmConfiguration;
+
+    public long getSliceId() {
+        return sliceId;
+    }
+
+    public void setSliceId(long sliceId) {
+        this.sliceId = sliceId;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Set<Long> getUeID() {
+        return ueID;
+    }
+
+    public void setUeID(Set<Long> ueID) {
+        this.ueID = ueID;
+    }
+
+    public Set<RnibLink> getLinks() {
+        return links;
+    }
+
+    public void setLinks(Set<RnibLink> links) {
+        this.links = links;
+    }
+
+    public long getValidityPeriod() {
+        return validityPeriod;
+    }
+
+    public void setValidityPeriod(long validityPeriod) {
+        this.validityPeriod = validityPeriod;
+    }
+
+    public Object getDesiredKpis() {
+        return desiredKpis;
+    }
+
+    public void setDesiredKpis(Object desiredKpis) {
+        this.desiredKpis = desiredKpis;
+    }
+
+    public Object getDeliveredKpis() {
+        return deliveredKpis;
+    }
+
+    public void setDeliveredKpis(Object deliveredKpis) {
+        this.deliveredKpis = deliveredKpis;
+    }
+
+    public Object getRrmConfiguration() {
+        return rrmConfiguration;
+    }
+
+    public void setRrmConfiguration(Object rrmConfiguration) {
+        this.rrmConfiguration = rrmConfiguration;
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibUe.java b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibUe.java
new file mode 100644
index 0000000..714182c
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/RnibUe.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.entities;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.HostId;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ENBUES1APID;
+import org.onosproject.xran.asn1lib.api.MMEUES1APID;
+import org.onosproject.xran.asn1lib.pdu.RRCMeasConfig;
+import org.onosproject.xran.asn1lib.pdu.UECapabilityInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.onosproject.net.HostId.hostId;
+
+/**
+ * R-NIB UE and its properties.
+ */
+@JsonPropertyOrder({
+        "Identifier",
+        "Context-IDs",
+        "RAN-ID",
+        "State",
+        "Capability",
+        "MeasurementConfiguration"
+})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class RnibUe {
+    @JsonIgnore
+    private static final Logger log =
+            LoggerFactory.getLogger(RnibUe.class);
+
+    @JsonProperty("Identifier")
+    private Long id;
+    @JsonProperty("Context-IDs")
+    private ContextIds contextIds = new ContextIds();
+    @JsonProperty("RAN-ID")
+    private CRNTI crnti;
+    @JsonProperty("State")
+    private State state = State.ACTIVE;
+    @JsonProperty("Capability")
+    private UECapabilityInfo capability;
+    @JsonProperty("MeasurementConfiguration")
+    private RRCMeasConfig measConfig;
+    @JsonIgnore
+    private ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
+
+    /**
+     * Convert Host ID to UE ID.
+     *
+     * @param hostId hostID
+     * @return Long UE ID
+     */
+    public static Long hostIdtoUEId(HostId hostId) {
+        String mac = hostId.mac().toString();
+        mac = mac.replace(":", "");
+        return Long.parseLong(mac, 16);
+    }
+
+    /**
+     * Get timer.
+     *
+     * @return Timer
+     */
+    public ScheduledExecutorService getExecutor() {
+        return executor;
+    }
+
+    /**
+     * Set executor.
+     *
+     * @param executor executor
+     */
+    public void setExecutor(ScheduledExecutorService executor) {
+        this.executor.shutdown();
+        this.executor = executor;
+    }
+
+    /**
+     * Get CRNTI.
+     *
+     * @return CRNTI
+     */
+    public CRNTI getCrnti() {
+        return crnti;
+    }
+
+    /**
+     * Set CRNTI.
+     *
+     * @param crnti CRNTI
+     */
+    public void setCrnti(CRNTI crnti) {
+        this.crnti = crnti;
+    }
+
+    /**
+     * Get Host ID.
+     *
+     * @return HostId
+     */
+    @JsonIgnore
+    public HostId getHostId() {
+        try {
+            String text = Long.toHexString(this.id),
+                    res = "";
+            int charsLeft = 12 - text.length();
+            if (charsLeft > 0) {
+                res += Stream.generate(() -> "0").limit(charsLeft).collect(Collectors.joining(""));
+            } else if (charsLeft < 0) {
+                return null;
+            }
+            res += text;
+
+            String insert = ":";
+            int period = 2;
+
+            StringBuilder builder = new StringBuilder(
+                    res.length() + insert.length() * (res.length() / period) + 1);
+
+            int index = 0;
+            String prefix = "";
+            while (index < res.length()) {
+                // Don't putPrimaryLink the insert in the very first iteration.
+                // This is easier than appending it *after* each substring
+                builder.append(prefix);
+                prefix = insert;
+                builder.append(res.substring(index,
+                        Math.min(index + period, res.length())));
+                index += period;
+            }
+
+            return hostId(MacAddress.valueOf(builder.toString()));
+        } catch (Exception e) {
+            log.error(e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * Get RXMeasConfig Report.
+     *
+     * @return RXSigMeasConfig
+     */
+    public RRCMeasConfig getMeasConfig() {
+        return measConfig;
+    }
+
+    /**
+     * Set RXMeasConfig Report.
+     *
+     * @param measConfig RXSigMeasConfig
+     */
+    public void setMeasConfig(RRCMeasConfig measConfig) {
+        this.measConfig = measConfig;
+    }
+
+    /**
+     * Get UE Capability Info.
+     *
+     * @return UECapabilityInfo
+     */
+    public UECapabilityInfo getCapability() {
+        return capability;
+    }
+
+    /**
+     * Set UE Capability Info.
+     *
+     * @param capability UECapabilityInfo
+     */
+    public void setCapability(UECapabilityInfo capability) {
+        this.capability = capability;
+    }
+
+    /**
+     * Get State.
+     *
+     * @return State
+     */
+    public State getState() {
+        return state;
+    }
+
+    /**
+     * Set State.
+     *
+     * @param state State
+     */
+    public void setState(State state) {
+        this.state = state;
+    }
+
+    /**
+     * Get UE ID.
+     *
+     * @return Long UE ID
+     */
+    public Long getId() {
+        return id;
+    }
+
+    /**
+     * Set UE ID.
+     *
+     * @param id Long UE ID
+     */
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public ContextIds getContextIds() {
+        return contextIds;
+    }
+
+    public void setContextIds(ContextIds contextIds) {
+        this.contextIds = contextIds;
+    }
+
+    @Override
+    public String toString() {
+        return "RnibUe{" +
+                "id=" + id +
+                ", contextIds=" + contextIds +
+                ", crnti=" + crnti +
+                ", state=" + state +
+                ", capability=" + capability +
+                ", measConfig=" + measConfig +
+                '}';
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        RnibUe rnibUe = (RnibUe) o;
+        return Objects.equals(id, rnibUe.id);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+
+
+    /**
+     * Enum of State of UE.
+     */
+    public enum State {
+        ACTIVE {
+            @Override
+            public String toString() {
+                return "ACTIVE";
+            }
+        },
+        IDLE {
+            @Override
+            public String toString() {
+                return "IDLE";
+            }
+        }
+    }
+
+    /**
+     * Context IDs.
+     */
+    @JsonPropertyOrder({
+            "IMSI",
+            "ENBUES1APID",
+            "MMEUES1APID",
+    })
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class ContextIds {
+        @JsonProperty("IMSI")
+        private String imsi = "";
+        @JsonProperty("ENBUES1APID")
+        private ENBUES1APID enbS1apId;
+        @JsonProperty("MMEUES1APID")
+        private MMEUES1APID mmeS1apId;
+
+        public ContextIds() {
+        }
+
+        @JsonCreator
+        public ContextIds(
+                @JsonProperty("ENBUES1APID") ENBUES1APID enbS1apId,
+                @JsonProperty("MMEUES1APID") MMEUES1APID mmeS1apId
+        ) {
+            this.enbS1apId = enbS1apId;
+            this.mmeS1apId = mmeS1apId;
+        }
+
+        public ContextIds(String imsi, ENBUES1APID enbS1apId, MMEUES1APID mmeS1apId) {
+            this.imsi = imsi;
+            this.enbS1apId = enbS1apId;
+            this.mmeS1apId = mmeS1apId;
+        }
+
+        /**
+         * Get MMEUES1APID.
+         *
+         * @return MMEUES1APID
+         */
+        public MMEUES1APID getMmeS1apId() {
+            return mmeS1apId;
+        }
+
+        /**
+         * Set MMEUES1APID.
+         *
+         * @param mmeS1apId MMEUES1APID
+         */
+        public void setMmeS1apId(MMEUES1APID mmeS1apId) {
+            this.mmeS1apId = mmeS1apId;
+        }
+
+        /**
+         * Get ENBUES1APID.
+         *
+         * @return ENBUES1APID
+         */
+        public ENBUES1APID getEnbS1apId() {
+            return enbS1apId;
+        }
+
+        /**
+         * Set ENBUES1APID.
+         *
+         * @param enbS1apId ENBUES1APID
+         */
+        public void setEnbS1apId(ENBUES1APID enbS1apId) {
+            this.enbS1apId = enbS1apId;
+        }
+
+        /**
+         * Get IMSI.
+         *
+         * @return IMSI
+         */
+        public String getImsi() {
+            return imsi;
+        }
+
+        /**
+         * Set IMSI.
+         *
+         * @param imsi IMSI
+         */
+        public void setImsi(String imsi) {
+            this.imsi = imsi;
+        }
+
+        @Override
+        public String toString() {
+            return "ContextIds{" +
+                    "imsi='" + imsi + '\'' +
+                    ", enbS1apId=" + enbS1apId +
+                    ", mmeS1apId=" + mmeS1apId +
+                    '}';
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/entities/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/package-info.java
new file mode 100644
index 0000000..0817620
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/entities/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Created by dimitris on 7/22/17.
+ */
+package org.onosproject.xran.impl.entities;
\ No newline at end of file
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/ContextUpdateHandler.java b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/ContextUpdateHandler.java
new file mode 100644
index 0000000..2209825
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/ContextUpdateHandler.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.identifiers;
+
+import org.onosproject.xran.asn1lib.pdu.HOComplete;
+import org.onosproject.xran.asn1lib.pdu.UEAdmissionStatus;
+import org.onosproject.xran.asn1lib.pdu.UEContextUpdate;
+
+/**
+ * Class to handle UE Context Update packet.
+ */
+public class ContextUpdateHandler {
+    private UEContextUpdate contextUpdate;
+    private UEAdmissionStatus admissionStatus;
+    private HOComplete hoComplete;
+
+    /**
+     * Get Context Update.
+     * @return UEContextUpdate
+     */
+    public UEContextUpdate getContextUpdate() {
+        return contextUpdate;
+    }
+
+    /**
+     * Set Context Update.
+     * @param contextUpdate UEContextUpdate
+     * @return boolean to check context update was for admissionStatus packet or HOComplete packet
+     */
+    public boolean setContextUpdate(UEContextUpdate contextUpdate) {
+        synchronized (this) {
+            this.contextUpdate = contextUpdate;
+
+            return admissionStatus != null || hoComplete != null;
+        }
+    }
+
+    /**
+     * Get UEAdmissionStatus.
+     * @return UEAdmissionStatus
+     */
+    public UEAdmissionStatus getAdmissionStatus() {
+        return admissionStatus;
+    }
+
+    /**
+     * Set UEAdmissionStatus.
+     * @param admissionStatus UEAdmissionStatus
+     * @return boolean contextUpdate exists or not
+     */
+    public boolean setAdmissionStatus(UEAdmissionStatus admissionStatus) {
+        synchronized (this) {
+            this.admissionStatus = admissionStatus;
+
+            return contextUpdate != null;
+        }
+    }
+
+    /**
+     * Get HOComplete.
+     * @return HOComplete
+     */
+    public HOComplete getHoComplete() {
+        return hoComplete;
+    }
+
+    /**
+     * Set HOComplete.
+     * @param hoComplete HOComplete
+     * @return boolean contextUpdate exists or not
+     */
+    public boolean setHoComplete(HOComplete hoComplete) {
+        synchronized (this) {
+            this.hoComplete = hoComplete;
+
+            return contextUpdate != null;
+        }
+    }
+
+    /**
+     * Reset the values of the variables.
+     *
+     */
+    public void reset() {
+        synchronized (this) {
+            this.hoComplete = null;
+            this.admissionStatus = null;
+            this.contextUpdate = null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "ContextUpdateHandler{" +
+                "contextUpdate=" + (contextUpdate != null) +
+                ", admissionStatus=" + (admissionStatus != null) +
+                ", hoComplete=" + (hoComplete != null) +
+                '}';
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/EcgiCrntiPair.java b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/EcgiCrntiPair.java
new file mode 100644
index 0000000..7e78bfa
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/EcgiCrntiPair.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.identifiers;
+
+import com.google.common.base.Objects;
+import javafx.util.Pair;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+
+/**
+ * Class to maintain pair of ECGI and CRNTI.
+ */
+public class EcgiCrntiPair extends Pair<ECGI, CRNTI> {
+
+    /**
+     * Creates a new pair.
+     *
+     * @param key   The key for this pair
+     * @param value The value to use for this pair
+     */
+    public EcgiCrntiPair(ECGI key, CRNTI value) {
+        super(key, value);
+    }
+
+    /**
+     * Return a new EcgiCrntiPair.
+     *
+     * @param key ECGI
+     * @param value CRNTI
+     * @return EcgiCrntiPair
+     */
+    public static EcgiCrntiPair valueOf(ECGI key, CRNTI value) {
+        return new EcgiCrntiPair(key, value);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(getKey(), getValue());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof EcgiCrntiPair) {
+            return ((EcgiCrntiPair) o).getKey().equals(getKey()) &&
+                    ((EcgiCrntiPair) o).getValue().equals(getValue());
+        }
+        return super.equals(o);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/LinkId.java b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/LinkId.java
new file mode 100644
index 0000000..a439461
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/LinkId.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.identifiers;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.onosproject.xran.impl.entities.RnibUe;
+
+/**
+ * Class for LinkId.
+ */
+@JsonPropertyOrder({
+        "ECGI",
+        "UEID"
+})
+@JsonIgnoreProperties(ignoreUnknown = true)
+public final class LinkId {
+    @JsonIgnore
+    private RnibCell cell;
+    @JsonIgnore
+    private RnibUe ue;
+
+    private LinkId(RnibCell cell, RnibUe ue) {
+        this.cell = cell;
+        this.ue = ue;
+    }
+
+    /**
+     * Create new LinkId.
+     * @param cell Cell
+     * @param ue UE
+     * @return new LinkId
+     */
+    public static LinkId valueOf(RnibCell cell, RnibUe ue) {
+        return new LinkId(cell, ue);
+    }
+
+    /**
+     * Create new LinkID with ECGI and UE ID given.
+     * @param ecgi ECGI of new cell
+     * @param ueId UE ID of new UE
+     * @return LinkId
+     */
+    public static LinkId valueOf(ECGI ecgi, Long ueId) {
+        RnibCell cell = new RnibCell();
+        RnibUe ue = new RnibUe();
+
+        cell.setEcgi(ecgi);
+        ue.setId(ueId);
+        return new LinkId(cell, ue);
+    }
+
+    /**
+     * Get ECGI.
+     * @return ECGI
+     */
+    @JsonProperty("ECGI")
+    public ECGI getEcgi() {
+        return cell.getEcgi();
+    }
+
+    /**
+     * Set ECGI.
+     * @param sourceId ECGI
+     */
+    @JsonProperty("ECGI")
+    public void setEcgi(ECGI sourceId) {
+        cell.setEcgi(sourceId);
+    }
+
+    /**
+     * Get UE ID.
+     * @return long UE ID
+     */
+    @JsonProperty("UEID")
+    public Long getUeId() {
+        return ue.getId();
+    }
+
+    /**
+     * Set UE ID.
+     * @param destinationId long UE ID
+     */
+    @JsonProperty("UEID")
+    public void setUeId(Long destinationId) {
+        ue.setId(destinationId);
+    }
+
+    /**
+     * Get Cell.
+     * @return Cell
+     */
+    @JsonIgnore
+    public RnibCell getCell() {
+        return cell;
+    }
+
+    /**
+     * Set Cell.
+     * @param cell Cell
+     */
+    @JsonIgnore
+    public void setCell(RnibCell cell) {
+        this.cell = cell;
+    }
+
+    /**
+     * Get UE.
+     * @return UE
+     */
+    @JsonIgnore
+    public RnibUe getUe() {
+        return ue;
+    }
+
+    /**
+     * Set UE.
+     * @param ue UE
+     */
+    @JsonIgnore
+    public void setUe(RnibUe ue) {
+        this.ue = ue;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#equals()
+     */
+    @Override
+    public boolean equals(Object o) {
+        return this == o ||
+                o != null &&
+                        o instanceof LinkId &&
+                        cell.getEcgi().equals(((LinkId) o).cell.getEcgi()) &&
+                        ue.getId().equals(((LinkId) o).ue.getId());
+
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        int result = cell.getEcgi().hashCode();
+        result = 31 * result + ue.getId().hashCode();
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{\n")
+                .append(cell != null ? "\"cell\":" + cell : "")
+                .append(ue != null ? ",\n\"ue\":" + ue : "")
+                .append("\n}\n");
+        return sb.toString();
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/package-info.java
new file mode 100644
index 0000000..f5227c7
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/identifiers/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Created by dimitris on 7/22/17.
+ */
+package org.onosproject.xran.impl.identifiers;
\ No newline at end of file
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/impl/package-info.java
new file mode 100644
index 0000000..66ce0b7
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Created by dimitris on 7/23/17.
+ */
+package org.onosproject.xran.impl;
\ No newline at end of file
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/providers/CellDeviceProvider.java b/apps/xran/src/main/java/org.onosproject.xran/impl/providers/CellDeviceProvider.java
new file mode 100644
index 0000000..33b49d6
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/providers/CellDeviceProvider.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.providers;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.ChassisId;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.xran.XranService;
+import org.onosproject.xran.XranDeviceListener;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.slf4j.Logger;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.xran.impl.entities.RnibCell.uri;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Cell device provider.
+ */
+@Component(immediate = true)
+public class CellDeviceProvider extends AbstractProvider implements DeviceProvider {
+
+    private static final Logger log = getLogger(CellDeviceProvider.class);
+    private final InternalDeviceListener listener = new InternalDeviceListener();
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceProviderRegistry providerRegistry;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected XranService controller;
+    private DeviceProviderService providerService;
+
+    public CellDeviceProvider() {
+        super(new ProviderId("xran", "org.onosproject.providers.cell"));
+    }
+
+    @Activate
+    public void activate() {
+        providerService = providerRegistry.register(this);
+        controller.addListener(listener);
+
+        log.info("XRAN Device Provider Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        controller.removeListener(listener);
+        providerRegistry.unregister(this);
+
+        providerService = null;
+        log.info("XRAN Device Provider Stopped");
+    }
+
+    @Override
+    public void triggerProbe(DeviceId deviceId) {
+
+    }
+
+    @Override
+    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
+
+    }
+
+    @Override
+    public boolean isReachable(DeviceId deviceId) {
+        return true;
+    }
+
+    @Override
+    public void changePortState(DeviceId deviceId, PortNumber portNumber, boolean enable) {
+
+    }
+
+    /**
+     * Internal device listener.
+     */
+    private class InternalDeviceListener implements XranDeviceListener {
+
+        @Override
+        public void deviceAdded(RnibCell cell) {
+            if (providerService == null) {
+                return;
+            }
+
+            // use ECGI as device ID URI
+            DeviceId id = deviceId(uri(cell.getEcgi()));
+
+            ChassisId cId = new ChassisId(id.hashCode());
+
+            Device.Type type = Device.Type.OTHER;
+            SparseAnnotations annotations = DefaultAnnotations.builder()
+                    .set(AnnotationKeys.NAME, "eNodeB " + cell.getEcgi().getEUTRANcellIdentifier())
+                    .set(AnnotationKeys.PROTOCOL, "SCTP")
+                    .set(AnnotationKeys.CHANNEL_ID, "xxx")
+                    .set(AnnotationKeys.MANAGEMENT_ADDRESS, "127.0.0.1")
+                    .set(AnnotationKeys.UI_TYPE, "basestation")
+                    .build();
+
+            DeviceDescription descBase =
+                    new DefaultDeviceDescription(id.uri(), type,
+                            "xran", "0.1", "0.1", id.uri().toString(),
+                            cId);
+            DeviceDescription desc = new DefaultDeviceDescription(descBase, annotations);
+
+            providerService.deviceConnected(id, desc);
+        }
+
+        @Override
+        public void deviceRemoved(DeviceId id) {
+            providerService.deviceDisconnected(id);
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/providers/UeProvider.java b/apps/xran/src/main/java/org.onosproject.xran/impl/providers/UeProvider.java
new file mode 100644
index 0000000..e618e3b
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/providers/UeProvider.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.providers;
+
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.xran.XranService;
+import org.onosproject.xran.XranHostListener;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.impl.entities.RnibUe;
+import org.slf4j.Logger;
+
+import java.util.Set;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.xran.impl.entities.RnibCell.uri;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * UE Provider.
+ */
+@Component(immediate = true)
+public class UeProvider extends AbstractProvider implements HostProvider {
+
+    private static final Logger log = getLogger(UeProvider.class);
+    private final InternalHostListener listener = new InternalHostListener();
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private HostProviderRegistry providerRegistry;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private XranService controller;
+    private HostProviderService providerService;
+
+    public UeProvider() {
+        super(new ProviderId("xran", "org.onosproject.providers.ue"));
+    }
+
+    @Activate
+    public void activate() {
+        providerService = providerRegistry.register(this);
+        controller.addListener(listener);
+
+        log.info("XRAN Host Provider Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        controller.removeListener(listener);
+        providerRegistry.unregister(this);
+
+        providerService = null;
+        log.info("XRAN Host Provider Stopped");
+    }
+
+    @Override
+    public void triggerProbe(Host host) {
+
+    }
+
+    /**
+     * Internal host listener.
+     */
+    class InternalHostListener implements XranHostListener {
+
+        @Override
+        public void hostAdded(RnibUe ue, Set<ECGI> ecgiSet) {
+            if (providerService == null) {
+                return;
+            }
+
+            if (ue == null) {
+                log.error("UE is not found");
+                return;
+            }
+
+            try {
+                Set<HostLocation> hostLocations = Sets.newConcurrentHashSet();
+
+                ecgiSet.forEach(ecgi -> hostLocations
+                        .add(new HostLocation(deviceId(uri(ecgi)),
+                                PortNumber.portNumber(0), 0)));
+
+                SparseAnnotations annotations = DefaultAnnotations.builder()
+                        .set(AnnotationKeys.NAME, "UE " + ue.getId())
+                        .set(AnnotationKeys.UI_TYPE, "mobile")
+                        .build();
+
+                // Host ID is calculated from UE ID with some hacky function to represent a MAC address.
+                DefaultHostDescription desc = new DefaultHostDescription(
+                        ue.getHostId().mac(),
+                        VlanId.vlanId(VlanId.UNTAGGED),
+                        hostLocations,
+                        Sets.newConcurrentHashSet(),
+                        true,
+                        annotations
+                );
+
+                providerService.hostDetected(ue.getHostId(), desc, false);
+            } catch (Exception e) {
+                log.warn(e.getMessage());
+                e.printStackTrace();
+            }
+        }
+
+        @Override
+        public void hostRemoved(HostId id) {
+            providerService.hostVanished(id);
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/providers/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/impl/providers/package-info.java
new file mode 100644
index 0000000..d4679ba
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/providers/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Created by dimitris on 7/27/17.
+ */
+package org.onosproject.xran.impl.providers;
\ No newline at end of file
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/rest/CellWebResource.java b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/CellWebResource.java
new file mode 100644
index 0000000..81ada71
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/CellWebResource.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.xran.impl.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.xran.XranService;
+import org.onosproject.xran.XranStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.PATCH;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Cell web resource.
+ */
+@Path("cell")
+public class CellWebResource extends AbstractWebResource {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(CellWebResource.class);
+
+    private XranStore xranStore;
+    private XranService xranService;
+
+    public CellWebResource() {
+        xranStore = get(XranStore.class);
+        xranService = get(XranService.class);
+    }
+
+    /**
+     * Lists the cell with {cellid}.
+     *
+     * @param eciHex EutranCellIdentifier in binary
+     * @return Response
+     */
+    @GET
+    @Path("{cellid}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND")
+    })
+    public Response getCell(@PathParam("cellid") String eciHex) {
+        return xranStore.getCell(eciHex).map(cell -> {
+            try {
+                JsonNode jsonNode = mapper().valueToTree(cell);
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_OK,
+                        jsonNode
+                );
+
+            } catch (Exception e) {
+                String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+                log.error(fullStackTrace);
+                e.printStackTrace();
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_INTERNAL_ERROR,
+                        "Exception",
+                        fullStackTrace
+                );
+            }
+        }).orElse(ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_NOT_FOUND,
+                "Not Found",
+                "Cell with " + eciHex + " was not found"
+        ));
+    }
+
+    /**
+     * Modify the RRMConfig parameters of the cell.
+     *
+     * @param eciHex EutranCellIdentifier in binary
+     * @param stream Parameters that you want to modify
+     * @return Response
+     */
+    @PATCH
+    @Path("{cellid}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 408, message = "HTTP_CLIENT_TIMEOUT"),
+            @ApiResponse(code = 400, message = "HTTP_BAD_REQUEST"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND")
+
+    })
+    public Response patchCell(@PathParam("cellid") String eciHex, InputStream stream) {
+        return xranStore.getCell(eciHex).map(cell -> {
+            try {
+                ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+
+                JsonNode rrmConf = jsonTree.path("RRMConf");
+                if (!rrmConf.isMissingNode()) {
+                    xranStore.modifyCellRrmConf(cell, rrmConf);
+
+                    return xranService.sendModifiedRrm(cell.getRrmConfig())
+                            .flatMap(queue -> {
+                                try {
+                                    return Optional.ofNullable(queue.poll(xranService
+                                            .getNorthboundTimeout(), TimeUnit.MILLISECONDS));
+                                } catch (InterruptedException e) {
+                                    log.error(ExceptionUtils.getFullStackTrace(e));
+                                    return Optional.empty();
+                                }
+                            }).map(p ->
+                                    ResponseHelper.getResponse(
+                                            mapper(),
+                                            HttpURLConnection.HTTP_OK,
+                                            "Handoff Response",
+                                            p
+                                    )
+                            ).orElse(
+                                    ResponseHelper.getResponse(
+                                            mapper(),
+                                            HttpURLConnection.HTTP_CLIENT_TIMEOUT,
+                                            "Handoff Timeout",
+                                            "eNodeB did not send a HOComplete/HOFailure on time"
+                                    )
+                            );
+                }
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_BAD_REQUEST,
+                        "Bad Request",
+                        "The command you specified is not implemented or doesn't exist. We support " +
+                                "RRMConf commands."
+                );
+            } catch (Exception e) {
+                String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+                log.error(fullStackTrace);
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_INTERNAL_ERROR,
+                        "Exception",
+                        fullStackTrace
+                );
+            }
+        }).orElse(ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_NOT_FOUND,
+                "Not Found",
+                "Cell " + eciHex + " was not found"
+        ));
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/rest/LinkWebResource.java b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/LinkWebResource.java
new file mode 100644
index 0000000..1c91bac
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/LinkWebResource.java
@@ -0,0 +1,519 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.xran.impl.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Lists;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.xran.XranService;
+import org.onosproject.xran.XranStore;
+import org.onosproject.xran.asn1lib.ber.types.BerInteger;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.onosproject.xran.impl.entities.RnibLink;
+import org.onosproject.xran.impl.entities.RnibUe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.PATCH;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Link web resource.
+ */
+@Path("links")
+public class LinkWebResource extends AbstractWebResource {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(LinkWebResource.class);
+
+    private XranStore xranStore;
+    private XranService xranService;
+
+    public LinkWebResource() {
+        xranStore = get(XranStore.class);
+        xranService = get(XranService.class);
+    }
+
+    /**
+     * List all the links originating or terminating at cell/UE OR list the link connecting between cell and UE.
+     *
+     * @param eciHex EutranCellIdentifier in binary
+     * @param ue     UE ID
+     * @return Response
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND")
+    })
+    public Response getLinksBetween(@DefaultValue("") @QueryParam("cell") String eciHex,
+                                    @DefaultValue("-1") @QueryParam("ue") long ue) {
+        List<RnibLink> list = Lists.newArrayList();
+        if (!eciHex.isEmpty() && ue != -1) {
+            xranStore.getLink(eciHex, ue).ifPresent(list::add);
+        } else if (!eciHex.isEmpty()) {
+            list.addAll(xranStore.getLinks(eciHex));
+        } else if (ue != -1) {
+            list.addAll(xranStore.getLinks(ue));
+        } else {
+            list.addAll(xranStore.getLinks());
+        }
+
+        if (list.size() > 0) {
+            try {
+                JsonNode jsonNode = mapper().valueToTree(list);
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_OK,
+                        jsonNode
+                );
+            } catch (Exception e) {
+                String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+                log.error(fullStackTrace);
+                e.printStackTrace();
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_INTERNAL_ERROR,
+                        "Exception",
+                        fullStackTrace
+                );
+            }
+        }
+
+        return ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_NOT_FOUND,
+                "Not Found",
+                "Specified links not found"
+        );
+    }
+
+    /**
+     * Modify the link.
+     *
+     * @param src    CELL ECI in binary
+     * @param dst    UE ID
+     * @param stream Parameter on basis of which link is to be modified
+     * @return Response
+     */
+    @PATCH
+    @Path("{src},{dst}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 501, message = "HTTP_NOT_IMPLEMENTED"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND"),
+            @ApiResponse(code = 400, message = "HTTP_BAD_REQUEST"),
+            @ApiResponse(code = 408, message = "HTTP_CLIENT_TIMEOUT")
+    })
+    public Response patchLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
+        return xranStore.getLink(src, dst).map(link -> {
+            try {
+                ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+
+                // Modify link based on Type
+                JsonNode type = jsonTree.path("type");
+                if (!type.isMissingNode()) {
+                    RnibLink.Type anEnum = RnibLink.Type.getEnum(type.asText());
+                    return handleTypeChange(link, anEnum);
+                }
+
+                // Modify link based on traffic percent
+                JsonNode trafficpercent = jsonTree.path("trafficpercent");
+                if (!trafficpercent.isMissingNode()) {
+                    return handleTrafficChange(link, trafficpercent);
+                }
+
+                // Modify link based on RRMConf
+                JsonNode rrmConf = jsonTree.path("RRMConf");
+                if (!rrmConf.isMissingNode()) {
+                    return handleRrmChange(link, rrmConf);
+                }
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_NOT_IMPLEMENTED,
+                        "Not Implemented",
+                        "The command you specified is not implemented or doesn't exist. We support " +
+                                "type/RRMConf/traficpercent commands."
+                );
+
+            } catch (Exception e) {
+                String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+                log.error(fullStackTrace);
+                e.printStackTrace();
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_INTERNAL_ERROR,
+                        "Exception",
+                        fullStackTrace
+                );
+            }
+        }).orElse(ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_NOT_FOUND,
+                "Not Found",
+                "Link not found use POST request"
+        ));
+    }
+
+    /**
+     * Create link based on Type of the link.
+     *
+     * @param src    CELL ECI in binary
+     * @param dst    UE ID
+     * @param stream LinkType
+     * @return Response
+     */
+    @POST
+    @Path("{src},{dst}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 501, message = "HTTP_NOT_IMPLEMENTED"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND"),
+            @ApiResponse(code = 400, message = "HTTP_BAD_REQUEST"),
+            @ApiResponse(code = 408, message = "HTTP_CLIENT_TIMEOUT"),
+    })
+    public Response postLinks(@PathParam("src") String src, @PathParam("dst") long dst, InputStream stream) {
+        Optional<RnibCell> cellOptional = xranStore.getCell(src);
+        Optional<RnibUe> ueOptional = xranStore.getUe(dst);
+
+        if (!cellOptional.isPresent()) {
+            return ResponseHelper.getResponse(
+                    mapper(),
+                    HttpURLConnection.HTTP_NOT_FOUND,
+                    "Not Found",
+                    "Cell " + src + " was not found"
+            );
+        }
+
+        if (!ueOptional.isPresent()) {
+            return ResponseHelper.getResponse(
+                    mapper(),
+                    HttpURLConnection.HTTP_NOT_FOUND,
+                    "Not Found",
+                    "Ue with " + dst + " was not found"
+            );
+        }
+
+        if (xranStore.getLink(cellOptional.get().getEcgi(), ueOptional.get().getId()) != null) {
+            return ResponseHelper.getResponse(
+                    mapper(),
+                    HttpURLConnection.HTTP_BAD_REQUEST,
+                    "Bad Request",
+                    "Link already exists use PATCH to modify"
+            );
+        }
+
+        try {
+            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+
+            JsonNode type = jsonTree.path("type");
+
+            RnibLink link = new RnibLink(cellOptional.get(), ueOptional.get());
+            // store it as non-serving when creating link
+            xranStore.storeLink(link);
+            if (!type.isMissingNode()) {
+                return handleTypeChange(link, RnibLink.Type.getEnum(type.asText()));
+            }
+
+            JsonNode trafficpercent = jsonTree.path("trafficpercent");
+            if (!trafficpercent.isMissingNode()) {
+                return handleTrafficChange(link, trafficpercent);
+            }
+
+            JsonNode rrmConf = jsonTree.path("RRMConf");
+            if (!rrmConf.isMissingNode()) {
+                return handleRrmChange(link, rrmConf);
+            }
+
+        } catch (Exception e) {
+            String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+            log.error(fullStackTrace);
+            e.printStackTrace();
+
+            return ResponseHelper.getResponse(
+                    mapper(),
+                    HttpURLConnection.HTTP_INTERNAL_ERROR,
+                    "Exception",
+                    fullStackTrace
+            );
+        }
+
+        return ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_BAD_REQUEST,
+                "Bad Request",
+                "The command you specified is not implemented " +
+                        "or doesn't exist. We support " +
+                        "type/RRMConf/traficpercent commands."
+        );
+    }
+
+
+    /**
+     * Change link based on type of the link.
+     *
+     * @param link    Link
+     * @param newType LinkType
+     * @return Response
+     * @throws InterruptedException Interrupted queue
+     */
+
+    private Response handleTypeChange(RnibLink link, RnibLink.Type newType)
+            throws InterruptedException {
+        if (newType.equals(RnibLink.Type.SERVING_PRIMARY)) {
+            switch (link.getType()) {
+                case SERVING_PRIMARY: {
+                    return ResponseHelper.getResponse(
+                            mapper(),
+                            HttpURLConnection.HTTP_BAD_REQUEST,
+                            "Bad Request",
+                            "Link is already a primary link"
+                    );
+                }
+                case SERVING_SECONDARY_CA:
+                case SERVING_SECONDARY_DC:
+                case NON_SERVING: {
+                    List<RnibLink> linksByUeId = xranStore
+                            .getLinks(link.getLinkId().getUeId());
+
+                    return linksByUeId.stream()
+                            .filter(l -> l.getType().equals(RnibLink.Type.SERVING_PRIMARY))
+                            .findFirst().map(primaryLink -> xranService.sendHoRequest(link, primaryLink)
+                                    .flatMap(q -> {
+                                        try {
+                                            return Optional.ofNullable(q.poll(xranService
+                                                    .getNorthboundTimeout(), TimeUnit.MILLISECONDS));
+                                        } catch (InterruptedException e) {
+                                            log.error(ExceptionUtils.getFullStackTrace(e));
+                                            return Optional.empty();
+                                        }
+                                    }).map(poll ->
+                                            ResponseHelper.getResponse(
+                                                    mapper(),
+                                                    HttpURLConnection.HTTP_OK,
+                                                    "Handoff Response",
+                                                    poll
+                                            )
+                                    ).orElse(
+                                            ResponseHelper.getResponse(
+                                                    mapper(),
+                                                    HttpURLConnection.HTTP_CLIENT_TIMEOUT,
+                                                    "Handoff Timeout",
+                                                    "eNodeB did not send a HOComplete/HOFailure on time"
+                                            )
+                                    )
+                            )
+                            .orElseGet(
+                                    () -> {
+                                        link.setType(RnibLink.Type.SERVING_PRIMARY);
+                                        return ResponseHelper.getResponse(
+                                                mapper(),
+                                                HttpURLConnection.HTTP_OK,
+                                                "OK",
+                                                "Link set to primary"
+                                        );
+                                    }
+                            );
+                }
+                default:
+            }
+        } else if (newType.equals(RnibLink.Type.NON_SERVING)) {
+            switch (link.getType()) {
+                case NON_SERVING: {
+                    return ResponseHelper.getResponse(
+                            mapper(),
+                            HttpURLConnection.HTTP_BAD_REQUEST,
+                            "Bad Request",
+                            "Link is already a primary link"
+                    );
+                }
+                case SERVING_PRIMARY: {
+                    return ResponseHelper.getResponse(
+                            mapper(),
+                            HttpURLConnection.HTTP_BAD_REQUEST,
+                            "Bad Request",
+                            "Cannot modify a primary link"
+                    );
+                }
+                case SERVING_SECONDARY_CA:
+                case SERVING_SECONDARY_DC: {
+                    if (xranService.sendScellDelete(link)) {
+                        return ResponseHelper.getResponse(
+                                mapper(),
+                                HttpURLConnection.HTTP_OK,
+                                "OK",
+                                "Link set to non-serving"
+                        );
+                    } else {
+                        return ResponseHelper.getResponse(
+                                mapper(),
+                                HttpURLConnection.HTTP_NOT_FOUND,
+                                "Not Found",
+                                "Could not find cell config report to construct Scell Delete"
+                        );
+                    }
+                }
+                default:
+            }
+        } else if (newType.equals(RnibLink.Type.SERVING_SECONDARY_CA)) {
+            switch (link.getType()) {
+                case SERVING_PRIMARY: {
+                    return ResponseHelper.getResponse(
+                            mapper(),
+                            HttpURLConnection.HTTP_BAD_REQUEST,
+                            "Bad Request",
+                            "Cannot modify a primary link"
+                    );
+                }
+                case SERVING_SECONDARY_DC:
+                case NON_SERVING: {
+                    return xranService.sendScellAdd(link).flatMap(queue -> {
+                        try {
+                            return Optional.ofNullable(queue.poll(xranService
+                                    .getNorthboundTimeout(), TimeUnit.MILLISECONDS));
+                        } catch (InterruptedException e) {
+                            log.error(ExceptionUtils.getFullStackTrace(e));
+                            return Optional.empty();
+                        }
+                    }).map(poll ->
+                            ResponseHelper.getResponse(
+                                    mapper(),
+                                    HttpURLConnection.HTTP_OK,
+                                    "ScellAdd Response",
+                                    poll
+                            )
+                    ).orElse(
+                            ResponseHelper.getResponse(
+                                    mapper(),
+                                    HttpURLConnection.HTTP_CLIENT_TIMEOUT,
+                                    "ScellAdd Timeout",
+                                    "eNodeB did not send a ScellAddStatus on time"
+                            )
+                    );
+                }
+                case SERVING_SECONDARY_CA: {
+                    return ResponseHelper.getResponse(
+                            mapper(),
+                            HttpURLConnection.HTTP_BAD_REQUEST,
+                            "Bad Request",
+                            "Link is already a secondary CA link"
+                    );
+                }
+                default:
+            }
+        }
+
+        return ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_BAD_REQUEST,
+                "Bad Request",
+                "The command you specified is not implemented or doesn't exist."
+        );
+    }
+
+    /**
+     * Modify link based on the traffic percent.
+     *
+     * @param link           Link
+     * @param trafficpercent Traffic Percent of the link to be modified
+     * @return Response
+     */
+    private Response handleTrafficChange(RnibLink link, JsonNode trafficpercent) {
+        JsonNode jsonNode = trafficpercent.path("traffic-percent-dl");
+        if (!jsonNode.isMissingNode()) {
+            link.getTrafficPercent().setTrafficPercentDl(new BerInteger(jsonNode.asInt()));
+        }
+
+        jsonNode = trafficpercent.path("traffic-percent-ul");
+        if (!jsonNode.isMissingNode()) {
+            link.getTrafficPercent().setTrafficPercentUl(new BerInteger(jsonNode.asInt()));
+        }
+
+        return ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_OK,
+                "OK",
+                "Traffic Percent changed"
+        );
+    }
+
+    /**
+     * Modify link based on RRMConf parameters.
+     *
+     * @param link    Link
+     * @param rrmConf RRMConfig of the Link to be modified
+     * @return Response
+     * @throws InterruptedException Interrupted queue
+     */
+    private Response handleRrmChange(RnibLink link, JsonNode rrmConf) throws InterruptedException {
+        xranStore.modifyLinkRrmConf(link, rrmConf);
+
+        return xranService.sendModifiedRrm(link.getRrmParameters()).flatMap(queue -> {
+            try {
+                return Optional.ofNullable(queue.poll(xranService
+                        .getNorthboundTimeout(), TimeUnit.MILLISECONDS));
+            } catch (InterruptedException e) {
+                log.error(ExceptionUtils.getFullStackTrace(e));
+                return Optional.empty();
+            }
+        }).map(poll ->
+                ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_OK,
+                        "RRMConfig Response",
+                        poll
+                )
+        ).orElse(
+                ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_CLIENT_TIMEOUT,
+                        "RRMConfig Timeout",
+                        "eNodeB did not send a RRMConfingStatus on time"
+                )
+        );
+
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/rest/NodeWebResource.java b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/NodeWebResource.java
new file mode 100644
index 0000000..6c74d95
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/NodeWebResource.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.xran.impl.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.xran.XranStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.HttpURLConnection;
+import java.util.List;
+
+/**
+ * Node web resource.
+ */
+@Path("nodes")
+public class NodeWebResource extends AbstractWebResource {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(NodeWebResource.class);
+
+    public NodeWebResource() {
+    }
+
+    /**
+     * List all the nodes in the R-NIB.
+     *
+     * @param type Type of node (cell/ue)
+     * @return Response
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND")
+    })
+    public Response getNodes(@DefaultValue("") @QueryParam("type") String type) {
+        JsonNode jsonNode;
+        try {
+            List<? extends Object> nodes;
+            // List cell type of nodes or UE type of nodes.
+            if (StringUtils.isBlank(type)) {
+                nodes = get(XranStore.class).getNodes();
+            } else if (type.equals("cell")) {
+                nodes = get(XranStore.class).getCellNodes();
+            } else if (type.equals("ue")) {
+                nodes = get(XranStore.class).getUeNodes();
+            } else {
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_NOT_FOUND,
+                        "Not Found",
+                        "Type of node was not found"
+                );
+            }
+
+            if (nodes.size() == 0) {
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_NOT_FOUND,
+                        "Not Found",
+                        "No nodes found"
+                );
+            }
+
+            jsonNode = mapper().valueToTree(nodes);
+        } catch (Exception e) {
+            String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+            log.error(fullStackTrace);
+
+            return ResponseHelper.getResponse(
+                    mapper(),
+                    HttpURLConnection.HTTP_INTERNAL_ERROR,
+                    "Exception",
+                    fullStackTrace
+            );
+        }
+
+        return ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_OK,
+                jsonNode
+        );
+    }
+
+    /**
+     * List the node with a specific node id.
+     *
+     * @param nodeid ID of the node
+     * @return Response
+     */
+    @GET
+    @Path("{nodeid}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND")
+    })
+    public Response getNodeid(@PathParam("nodeid") String nodeid) {
+        Object node = get(XranStore.class).getNode(nodeid);
+
+        if (node != null) {
+            try {
+                JsonNode jsonNode = mapper().valueToTree(node);
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_OK,
+                        jsonNode
+                );
+            } catch (Exception e) {
+                String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+                log.error(fullStackTrace);
+                e.printStackTrace();
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_INTERNAL_ERROR,
+                        "Exception",
+                        fullStackTrace
+                );
+            }
+        }
+
+        return ResponseHelper.getResponse(
+                mapper(),
+                HttpURLConnection.HTTP_NOT_FOUND,
+                "Not Found",
+                "Node " + nodeid + " was not found"
+        );
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/rest/ResponseHelper.java b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/ResponseHelper.java
new file mode 100644
index 0000000..0a3abad
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/ResponseHelper.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import javax.ws.rs.core.Response;
+
+/**
+ * Various types of responses.
+ */
+public final class ResponseHelper {
+
+    private ResponseHelper() {
+    }
+
+    public static Response getResponse(ObjectMapper mapper, int status, String title, String detail) {
+        ObjectNode rootNode = mapper.createObjectNode();
+
+        switch (status) {
+            case 200: {
+                ArrayNode data = rootNode.putArray("data");
+                ObjectNode addObject = data.addObject();
+                addObject.put("status", status);
+                addObject.put("title", title);
+                addObject.put("detail", detail);
+                return Response.status(status)
+                        .entity(rootNode.toString())
+                        .build();
+            }
+            case 400:
+            case 501:
+            case 408:
+            case 500:
+            case 404: {
+                ArrayNode errors = rootNode.putArray("errors");
+                ObjectNode addObject = errors.addObject();
+                addObject.put("status", status);
+                addObject.put("title", title);
+                addObject.put("detail", detail);
+                return Response.status(status)
+                        .entity(rootNode.toString())
+                        .build();
+            }
+            default:
+                return Response.noContent().build();
+        }
+    }
+
+    public static Response getResponse(ObjectMapper mapper, int status, JsonNode node) {
+        ObjectNode rootNode = mapper.createObjectNode();
+
+        switch (status) {
+            case 200:
+            case 400:
+            case 501:
+            case 408:
+            case 500:
+            case 404: {
+                ArrayNode data = rootNode.putArray("data");
+                data.add(node);
+                return Response.status(status)
+                        .entity(rootNode.toString())
+                        .build();
+            }
+            default:
+                return Response.noContent().build();
+        }
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/rest/SliceWebResource.java b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/SliceWebResource.java
new file mode 100644
index 0000000..10fcc5e
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/SliceWebResource.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.xran.impl.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.xran.XranStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+
+/**
+ * Slice web resource.
+ */
+@Path("slice")
+public class SliceWebResource extends AbstractWebResource {
+
+    private static final Logger log =
+            LoggerFactory.getLogger(SliceWebResource.class);
+
+    public SliceWebResource() {
+    }
+
+    /**
+     * List the slice with the given slice ID.
+     *
+     * @param sliceid ID of the slice
+     * @return Response
+     */
+    @GET
+    @Path("{sliceid}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 404, message = "HTTP_NOT_FOUND")
+    })
+    public Response getSlice(@PathParam("sliceid") long sliceid) {
+        return get(XranStore.class).getSlice(sliceid).map(slice -> {
+            try {
+                JsonNode jsonNode = mapper().valueToTree(slice);
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_OK,
+                        jsonNode
+                );
+            } catch (Exception e) {
+                String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+                log.error(fullStackTrace);
+
+                return ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_INTERNAL_ERROR,
+                        "Exception",
+                        fullStackTrace
+                );
+            }
+        }).orElse(
+                ResponseHelper.getResponse(
+                        mapper(),
+                        HttpURLConnection.HTTP_NOT_FOUND,
+                        "Not Found",
+                        "Slice " + sliceid + " not found"
+                )
+        );
+    }
+
+    /**
+     * Create slice with the corresponding attributes.
+     *
+     * @param stream Attributes to create slice
+     * @return Response
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @ApiResponses(value = {
+            @ApiResponse(code = 200, message = "HTTP_OK"),
+            @ApiResponse(code = 500, message = "HTTP_INTERNAL_ERROR"),
+            @ApiResponse(code = 501, message = "HTTP_NOT_IMPLEMENTED")
+    })
+    public Response postSlice(InputStream stream) {
+        try {
+//            ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream);
+//            get(XranStore.class).createSlice(jsonTree);
+
+            // FIXME: change when implemented
+            return ResponseHelper.getResponse(
+                    mapper(),
+                    HttpURLConnection.HTTP_NOT_IMPLEMENTED,
+                    "Not Implemented",
+                    "POST Slice not implemented"
+            );
+        } catch (Exception e) {
+            String fullStackTrace = ExceptionUtils.getFullStackTrace(e);
+            log.error(fullStackTrace);
+            e.printStackTrace();
+
+            return ResponseHelper.getResponse(
+                    mapper(),
+                    HttpURLConnection.HTTP_INTERNAL_ERROR,
+                    "Exception",
+                    fullStackTrace
+            );
+        }
+    }
+
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/rest/XranWebApplication.java b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/XranWebApplication.java
new file mode 100644
index 0000000..add727d
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/XranWebApplication.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl.rest;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * Sample REST API web application.
+ */
+public class XranWebApplication extends AbstractWebApplication {
+    @Override
+    public Set<Class<?>> getClasses() {
+        return getClasses(
+                LinkWebResource.class,
+                NodeWebResource.class,
+                CellWebResource.class,
+                SliceWebResource.class);
+    }
+}
diff --git a/apps/xran/src/main/java/org.onosproject.xran/impl/rest/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/package-info.java
new file mode 100644
index 0000000..7c5ca9a
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/impl/rest/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Created by dimitris on 7/20/17.
+ */
+package org.onosproject.xran.impl.rest;
\ No newline at end of file
diff --git a/apps/xran/src/main/java/org.onosproject.xran/package-info.java b/apps/xran/src/main/java/org.onosproject.xran/package-info.java
new file mode 100644
index 0000000..6e177d0
--- /dev/null
+++ b/apps/xran/src/main/java/org.onosproject.xran/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Created by dimitris on 7/20/17.
+ */
+package org.onosproject.xran;
diff --git a/apps/xran/src/main/webapp/WEB-INF/web.xml b/apps/xran/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..724584c
--- /dev/null
+++ b/apps/xran/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Foundation
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         id="ONOS" version="2.5">
+    <display-name>Sample App REST API v1.0</display-name>
+
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Secured</web-resource-name>
+            <url-pattern>/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>admin</role-name>
+        </auth-constraint>
+    </security-constraint>
+
+    <security-role>
+        <role-name>admin</role-name>
+    </security-role>
+
+    <login-config>
+        <auth-method>BASIC</auth-method>
+        <realm-name>karaf</realm-name>
+    </login-config>
+
+    <servlet>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.onosproject.xran.impl.rest.XranWebApplication</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>JAX-RS Service</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/apps/xran/src/test/java/org.onosproject.xran/org/onosproject/xran/impl/DefaultXranStoreTest.java b/apps/xran/src/test/java/org.onosproject.xran/org/onosproject/xran/impl/DefaultXranStoreTest.java
new file mode 100644
index 0000000..3e49869
--- /dev/null
+++ b/apps/xran/src/test/java/org.onosproject.xran/org/onosproject/xran/impl/DefaultXranStoreTest.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.xran.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.xran.asn1lib.api.CRNTI;
+import org.onosproject.xran.asn1lib.api.ECGI;
+import org.onosproject.xran.asn1lib.api.EUTRANCellIdentifier;
+import org.onosproject.xran.asn1lib.api.PLMNIdentity;
+import org.onosproject.xran.asn1lib.util.HexConverter;
+import org.onosproject.xran.impl.entities.RnibCell;
+import org.onosproject.xran.impl.entities.RnibLink;
+import org.onosproject.xran.impl.entities.RnibUe;
+
+import javax.xml.bind.DatatypeConverter;
+import java.util.List;
+import java.util.function.Supplier;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultXranStoreTest {
+    private static final CRNTI CRNTI0 = new CRNTI(new byte[]{(byte) 0xFF, (byte) 0xFF}, 16);
+    private static final CRNTI CRNTI1 = new CRNTI(new byte[]{(byte) 0xFA, (byte) 0xAF}, 16);
+
+    private static final RnibUe UE0 = new RnibUe();
+    private static final RnibUe UE1 = new RnibUe();
+
+    private static final RnibCell CELL0 = new RnibCell();
+    private static final RnibCell CELL1 = new RnibCell();
+    private static final String ECI0 = "00000010";
+    private static final String ECI1 = "00000020";
+    private static final long UEID0 = 0L;
+    private static final long UEID1 = 1L;
+
+    private static DefaultXranStore store = new DefaultXranStore();
+
+    private static RnibLink primaryLink0;
+    private static RnibLink primaryLink1;
+    private static RnibLink nonServingLink0;
+    private static RnibLink nonServingLink1;
+
+    private Supplier exception = () -> {
+        throw new IllegalArgumentException("item not found");
+    };
+
+    @Before
+    public void setUp() throws Exception {
+        CELL0.setEcgi(hexToEcgi("000001", ECI0));
+        CELL1.setEcgi(hexToEcgi("000002", ECI1));
+
+        UE0.setCrnti(CRNTI0);
+        UE0.setId(UEID0);
+
+        UE1.setCrnti(CRNTI1);
+        UE1.setId(UEID1);
+
+        store.storeCell(CELL0);
+        store.storeCell(CELL1);
+
+        store.storeUe(CELL0, UE0);
+        store.storeUe(CELL1, UE1);
+
+        store.putPrimaryLink(CELL0, UE0);
+        store.putPrimaryLink(CELL1, UE1);
+
+        store.putNonServingLink(CELL0, UEID1);
+        store.putNonServingLink(CELL1, UEID0);
+
+        primaryLink0 = store.getLink(CELL0.getEcgi(), UEID0).orElseThrow(exception);
+        primaryLink1 = store.getLink(CELL1.getEcgi(), UEID1).orElseThrow(exception);
+
+        nonServingLink0 = store.getLink(CELL0.getEcgi(), UEID1).orElseThrow(exception);
+        nonServingLink1 = store.getLink(CELL1.getEcgi(), UEID0).orElseThrow(exception);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        assertEquals("wrong remove", true, store.removeCell(CELL0.getEcgi()));
+        assertEquals("wrong remove", true, store.removeCell(CELL1.getEcgi()));
+
+        assertEquals("wrong remove", true, store.removeUe(UEID0));
+        assertEquals("wrong remove", true, store.removeUe(UEID1));
+
+        assertEquals("wrong remove", true, store.removeLink(primaryLink0.getLinkId()));
+        assertEquals("wrong remove", true, store.removeLink(primaryLink1.getLinkId()));
+
+        assertEquals("wrong remove", true, store.removeLink(nonServingLink0.getLinkId()));
+        assertEquals("wrong remove", true, store.removeLink(nonServingLink1.getLinkId()));
+
+        assertEquals("wrong len", 0, store.getCellNodes().size());
+        assertEquals("wrong len", 0, store.getUeNodes().size());
+        assertEquals("wrong len", 0, store.getNodes().size());
+        assertEquals("wrong len", 0, store.getLinks().size());
+    }
+
+    private ECGI hexToEcgi(String plmnId, String eci) throws Exception {
+        byte[] bytes = HexConverter.fromShortHexString(plmnId);
+        byte[] bytearray = DatatypeConverter.parseHexBinary(eci);
+
+        PLMNIdentity plmnIdentity = new PLMNIdentity(bytes);
+        EUTRANCellIdentifier eutranCellIdentifier = new EUTRANCellIdentifier(bytearray, 28);
+
+        ECGI ecgi = new ECGI();
+        ecgi.setEUTRANcellIdentifier(eutranCellIdentifier);
+        ecgi.setPLMNIdentity(plmnIdentity);
+
+        return ecgi;
+    }
+
+    @Test
+    public void getPrimaryLink() throws Exception {
+        assertEquals("wrong cell", CELL0, store.getPrimaryCell(UE0).orElseThrow(exception));
+        assertEquals("wrong cell", CELL1, store.getPrimaryCell(UE1).orElseThrow(exception));
+    }
+
+    @Test
+    public void mapSize() throws Exception {
+        assertEquals("wrong len", 2, store.getCellNodes().size());
+        assertEquals("wrong len", 2, store.getUeNodes().size());
+        assertEquals("wrong len", 4, store.getNodes().size());
+        assertEquals("wrong len", 4, store.getLinks().size());
+    }
+
+    @Test
+    public void getUe() throws Exception {
+        // GET FROM ID
+        assertEquals("wrong ue", UE0, store.getUe(UEID0).orElseThrow(exception));
+        assertEquals("wrong ue", UE1, store.getUe(UEID1).orElseThrow(exception));
+
+        // GET FROM ECGI-CRNTI
+        assertEquals("wrong ue", UE0, store.getUe(CELL0.getEcgi(), CRNTI0).orElseThrow(exception));
+        assertEquals("wrong ue", UE1, store.getUe(CELL1.getEcgi(), CRNTI1).orElseThrow(exception));
+
+        // GET FROM CRNTI
+        assertEquals("wrong crnti", CRNTI0, store.getCrnti(UEID0).orElseThrow(exception));
+        assertEquals("wrong crnti", CRNTI1, store.getCrnti(UEID1).orElseThrow(exception));
+    }
+
+    @Test
+    public void getLink() throws Exception {
+        // GET FROM ID
+        assertEquals("wrong link", primaryLink0, store.getLink(CELL0.getEcgi(), UEID0).orElseThrow(exception));
+        assertEquals("wrong link", primaryLink1, store.getLink(CELL1.getEcgi(), UEID1).orElseThrow(exception));
+        assertEquals("wrong link", nonServingLink0, store.getLink(CELL0.getEcgi(), UEID1).orElseThrow(exception));
+        assertEquals("wrong link", nonServingLink1, store.getLink(CELL1.getEcgi(), UEID0).orElseThrow(exception));
+
+        // GET FROM CRNTI
+        assertEquals("wrong link", primaryLink0, store.getLink(CELL0.getEcgi(), CRNTI0).orElseThrow(exception));
+        assertEquals("wrong link", primaryLink1, store.getLink(CELL1.getEcgi(), CRNTI1).orElseThrow(exception));
+        // GET FROM ECIHEX
+        assertEquals("wrong link", primaryLink0, store.getLink(ECI0, UEID0).orElseThrow(exception));
+        assertEquals("wrong link", primaryLink1, store.getLink(ECI1, UEID1).orElseThrow(exception));
+        assertEquals("wrong link", nonServingLink0, store.getLink(ECI0, UEID1).orElseThrow(exception));
+        assertEquals("wrong link", nonServingLink1, store.getLink(ECI1, UEID0).orElseThrow(exception));
+
+        // LINKS SIZE
+        assertEquals("wrong link", 2, store.getLinks(CELL0.getEcgi()).size());
+        assertEquals("wrong link", 2, store.getLinks(ECI0).size());
+        assertEquals("wrong link", 2, store.getLinks(UEID0).size());
+        assertEquals("wrong link", 2, store.getLinks(CELL1.getEcgi()).size());
+        assertEquals("wrong link", 2, store.getLinks(ECI1).size());
+        assertEquals("wrong link", 2, store.getLinks(UEID1).size());
+    }
+
+    @Test
+    public void getNodes() throws Exception {
+        List<RnibCell> cellNodes = store.getCellNodes();
+
+        assertEquals("wrong nodes", true, cellNodes.contains(CELL0));
+        assertEquals("wrong nodes", true, cellNodes.contains(CELL1));
+
+        List<RnibUe> ueNodes = store.getUeNodes();
+
+        assertEquals("wrong nodes", true, ueNodes.contains(UE0));
+        assertEquals("wrong nodes", true, ueNodes.contains(UE1));
+    }
+
+    @Test
+    public void crntiMap() throws Exception {
+        store.getCrnti().forEach(
+                (ecgiCrntiPair, aLong) -> assertEquals("wrong primary",
+                        store.getCell(ecgiCrntiPair.getKey()).get(),
+                        store.getPrimaryCell(store.getUe(aLong).orElseThrow(exception)).get()
+                )
+        );
+    }
+}
\ No newline at end of file
diff --git a/apps/xran/xran-cfg.json b/apps/xran/xran-cfg.json
new file mode 100644
index 0000000..e2f4dec
--- /dev/null
+++ b/apps/xran/xran-cfg.json
@@ -0,0 +1,30 @@
+{
+  "apps": {
+    "org.onosproject.xran": {
+      "xran": {
+        "active_cells": [
+          {
+            "plmn_id": "000001",
+            "eci": "00000010",
+            "ip_addr": "1.1.1.2"
+          },
+          {
+            "plmn_id": "000002",
+            "eci": "00000020",
+            "ip_addr": "1.1.1.3"
+          }
+        ],
+        "l2_meas_report_interval_ms": 5000,
+        "rx_signal_meas_report_interval_ms": 7000,
+        "xranc_cellconfigrequest_interval_seconds": 10,
+        "xranc_bind_ip": "1.1.1.1",
+        "xranc_port": 7891,
+        "admission_success": true,
+        "bearer_success": true,
+        "no_meas_link_removal_ms": 1000000,
+        "idle_ue_removal_ms": 1,
+        "nb_response_timeout_ms": 10000
+      }
+    }
+  }
+}