Add R5 content to master

Change-Id: I9cfea303b24612dd4ed8406e5f7f5304dee620af
Signed-off-by: ss412g <shuky.har-noy@intl.att.com>
diff --git a/RIC-E2-TERMINATION/3rdparty/asnTextFiles/E2SM-KPM-v01.00.asn b/RIC-E2-TERMINATION/3rdparty/asnTextFiles/E2SM-KPM-v01.00.asn
new file mode 100644
index 0000000..21f8fcf
--- /dev/null
+++ b/RIC-E2-TERMINATION/3rdparty/asnTextFiles/E2SM-KPM-v01.00.asn
@@ -0,0 +1,427 @@
+-- ASN1START
+-- **************************************************************
+-- E2SM-KPM
+-- Information Element Definitions
+--
+-- **************************************************************
+
+
+E2SM-KPM-IEs {
+iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 53148 e2(1) version1 (1) e2sm(2) e2sm-KPMMON-IEs (2)}
+
+DEFINITIONS AUTOMATIC TAGS ::=
+
+BEGIN
+
+-- **************************************************************
+-- IEs
+-- **************************************************************
+
+-- **************************************************************
+
+GlobalKPMnode-ID ::= CHOICE{
+	gNB					GlobalKPMnode-gNB-ID,
+	en-gNB				GlobalKPMnode-en-gNB-ID,
+	ng-eNB				GlobalKPMnode-ng-eNB-ID,
+	eNB					GlobalKPMnode-eNB-ID,
+	...
+}
+
+-- **************************************************************
+
+GlobalKPMnode-gNB-ID ::= SEQUENCE{
+	global-gNB-ID		GlobalgNB-ID,
+	gNB-CU-UP-ID		GNB-CU-UP-ID	OPTIONAL,
+	gNB-DU-ID			GNB-DU-ID		OPTIONAL,
+	...
+}
+
+GlobalgNB-ID	::= SEQUENCE {
+	plmn-id				PLMN-Identity,
+	gnb-id				GNB-ID-Choice,
+	...
+}
+
+GNB-CU-UP-ID ::= 	INTEGER (0..68719476735)
+GNB-DU-ID ::= 		INTEGER (0..68719476735)
+
+GNB-ID-Choice ::= CHOICE {
+	gnb-ID					BIT STRING (SIZE(22..32)),
+	...
+}
+
+-- **************************************************************
+
+GlobalKPMnode-en-gNB-ID ::= SEQUENCE{
+	global-gNB-ID		GlobalenGNB-ID,
+	...
+}
+
+GlobalenGNB-ID ::= SEQUENCE {
+	pLMN-Identity		PLMN-Identity,
+	gNB-ID				ENGNB-ID,
+	...
+}
+
+ENGNB-ID ::= CHOICE {
+	gNB-ID	BIT STRING (SIZE (22..32)),
+	...
+}
+
+-- **************************************************************
+
+GlobalKPMnode-ng-eNB-ID ::= SEQUENCE{
+	global-ng-eNB-ID	GlobalngeNB-ID,
+	...
+}
+
+GlobalngeNB-ID ::= SEQUENCE {
+	plmn-id			PLMN-Identity,
+	enb-id			ENB-ID-Choice,
+	...
+}
+
+ENB-ID-Choice ::= CHOICE {
+	enb-ID-macro			BIT STRING (SIZE(20)),
+	enb-ID-shortmacro		BIT STRING (SIZE(18)),
+	enb-ID-longmacro		BIT STRING (SIZE(21)),
+	...
+}
+
+-- **************************************************************
+
+GlobalKPMnode-eNB-ID ::= SEQUENCE{
+	global-eNB-ID		GlobalENB-ID,
+	...
+}
+
+GlobalENB-ID ::= SEQUENCE {
+	pLMN-Identity		PLMN-Identity,
+	eNB-ID				ENB-ID,
+	...
+}
+
+ENB-ID ::= CHOICE {
+	macro-eNB-ID			BIT STRING (SIZE (20)),
+	home-eNB-ID				BIT STRING (SIZE (28)),
+	... ,
+	short-Macro-eNB-ID		BIT STRING (SIZE(18)),
+	long-Macro-eNB-ID		BIT STRING (SIZE(21))
+}
+
+
+NRCGI ::= SEQUENCE {
+	pLMN-Identity			PLMN-Identity,
+	nRCellIdentity			NRCellIdentity
+}
+
+PLMN-Identity ::= OCTET STRING (SIZE(3))
+
+NRCellIdentity ::= BIT STRING (SIZE(36))
+
+SNSSAI ::= SEQUENCE {
+	sST			OCTET STRING (SIZE(1)),
+	sD			OCTET STRING (SIZE(3)) 	OPTIONAL
+}
+
+-- **************************************************************
+--
+-- Lists
+--
+-- **************************************************************
+
+maxofMessageProtocolTests			INTEGER ::= 15
+maxofRICstyles						INTEGER ::= 63
+maxnoofQCI                          INTEGER ::= 256
+maxnoofQoSFlows                     INTEGER ::= 64
+maxnoofSliceItems                   INTEGER ::= 1024
+maxnoofContainerListItems           INTEGER ::=  3
+maxCellingNBDU                      INTEGER ::= 512
+maxofContainers                     INTEGER ::= 8
+maxPLMN                             INTEGER ::= 12 -- Maximum number of PLMNs broadcast and reported by UE at establisghment
+
+RIC-Style-Type ::= INTEGER
+
+RIC-Style-Name ::= PrintableString(SIZE(1..150,...))
+
+RIC-Format-Type ::= INTEGER
+
+
+-- **************************************************************
+-- E2SM-KPM Service model IEs
+-- **************************************************************
+
+-- **************************************************************
+-- Event Trigger Definition OCTET STRING contents
+-- **************************************************************
+
+-- E2SM-KPM-EventTriggerDefinition IE
+E2SM-KPM-EventTriggerDefinition ::= CHOICE{
+	eventDefinition-Format1		E2SM-KPM-EventTriggerDefinition-Format1,
+	...
+}
+
+-- E2SM-KPM-EventTriggerDefinition IE is used for Event Trigger Definition Format 1
+E2SM-KPM-EventTriggerDefinition-Format1 ::= SEQUENCE{
+	policyTest-List	SEQUENCE (SIZE(1..maxofMessageProtocolTests)) OF Trigger-ConditionIE-Item OPTIONAL,
+	...
+}
+
+-- **************************************************************
+-- Action Definition OCTET STRING contents
+-- **************************************************************
+
+-- E2SM-KPM-ActionDefinition IE
+E2SM-KPM-ActionDefinition ::= SEQUENCE{
+	ric-Style-Type				RIC-Style-Type,
+	...
+}
+
+-- **************************************************************
+-- Indication Header OCTET STRING contents
+-- **************************************************************
+
+-- E2SM-KPM-IndicationHeader IE
+E2SM-KPM-IndicationHeader ::= CHOICE{
+	indicationHeader-Format1		E2SM-KPM-IndicationHeader-Format1,
+	...
+}
+
+-- E2SM-KPM-IndicationHeader Format 1
+E2SM-KPM-IndicationHeader-Format1 ::= SEQUENCE{
+	id-GlobalKPMnode-ID			GlobalKPMnode-ID  OPTIONAL,
+	nRCGI                       NRCGI            OPTIONAL,
+    pLMN-Identity			PLMN-Identity    OPTIONAL,
+	sliceID		SNSSAI           OPTIONAL,
+	fiveQI					INTEGER (0..255) OPTIONAL,
+    qci                         INTEGER (0..255) OPTIONAL,
+    ...
+}
+
+-- **************************************************************
+-- Indication Message OCTET STRING contents
+-- **************************************************************
+
+-- E2SM-KPM-IndicationMessage IE
+E2SM-KPM-IndicationMessage ::= CHOICE{
+	ric-Style-Type				RIC-Style-Type,
+	indicationMessage-Format1		E2SM-KPM-IndicationMessage-Format1,
+	...
+}
+
+-- E2SM-KPM-IndicationMessage-Format 1 IE
+E2SM-KPM-IndicationMessage-Format1 ::= SEQUENCE{
+    pm-Containers SEQUENCE (SIZE(1..maxCellingNBDU)) OF PM-Containers-List,
+    ...
+}
+
+PM-Containers-List ::= SEQUENCE{
+	performanceContainer	    PF-Container    OPTIONAL,
+	theRANContainer     	    RAN-Container   OPTIONAL,
+	...
+}
+
+-- ***************************************************************
+-- RAN Function Description OCTET STRING contents
+-- ***************************************************************
+
+-- E2SM-KPM-RANfunction-Description
+E2SM-KPM-RANfunction-Description ::= SEQUENCE{
+	ranFunction-Name	RANfunction-Name,
+    e2SM-KPM-RANfunction-Item SEQUENCE{
+	    ric-EventTriggerStyle-List	SEQUENCE (SIZE(1..maxofRICstyles)) OF RIC-EventTriggerStyle-List OPTIONAL,
+	    ric-ReportStyle-List		SEQUENCE (SIZE(1..maxofRICstyles)) OF RIC-ReportStyle-List OPTIONAL,
+	    ...
+    },
+	...
+}
+
+
+-- ***************************************************************
+-- commmon IEs
+-- ***************************************************************
+
+NI-Type ::= ENUMERATED{
+    x2-u,
+    xn-u,
+    f1-u,
+    ...
+}
+
+RAN-Container ::= OCTET STRING
+
+Trigger-ConditionIE-Item ::= SEQUENCE{
+	report-Period-IE		RT-Period-IE,
+	...
+}
+
+RT-Period-IE ::= ENUMERATED{ ms10, ms20, ms32, ms40, ms60, ms64, ms70, ms80, ms128, ms160, ms256, ms320, ms512, ms640, ms1024, ms1280, ms2048, ms2560, ms5120, ms10240, ...}
+
+RANcallProcess-ID-string ::= PrintableString(SIZE(1..150,...))
+
+RANfunction-Name ::= SEQUENCE{
+    ranFunction-ShortName       PrintableString(SIZE(1..150,...)),
+    ranFunction-E2SM-OID		PrintableString(SIZE(1..1000,...)),
+    ranFunction-Description     PrintableString(SIZE(1..150,...)),
+    ranFunction-Instance        INTEGER OPTIONAL,
+    ...
+}
+
+RIC-EventTriggerStyle-List ::= SEQUENCE{
+	ric-EventTriggerStyle-Type			RIC-Style-Type,
+	ric-EventTriggerStyle-Name			RIC-Style-Name,
+	ric-EventTriggerFormat-Type			RIC-Format-Type,
+	...
+}
+
+RIC-ReportStyle-List ::= SEQUENCE{
+	ric-ReportStyle-Type				RIC-Style-Type,
+	ric-ReportStyle-Name				RIC-Style-Name,
+	ric-IndicationHeaderFormat-Type		RIC-Format-Type,
+	ric-IndicationMessageFormat-Type	RIC-Format-Type,
+	...
+}
+
+PF-Container ::= CHOICE {
+	oDU		ODU-PF-Container,
+	oCU-CP	OCUCP-PF-Container,
+    oCU-UP       OCUUP-PF-Container
+}
+
+GNB-CU-CP-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-DU-Name ::= PrintableString(SIZE(1..150,...))
+
+GNB-CU-UP-Name ::= PrintableString(SIZE(1..150,...))
+
+
+-- **************************************************************
+-- O-DU Container IEs
+-- **************************************************************
+
+
+ODU-PF-Container ::= SEQUENCE{
+    cellResourceReportList SEQUENCE (SIZE(1..maxCellingNBDU)) OF CellResourceReportListItem,
+    ...
+}
+
+CellResourceReportListItem ::= SEQUENCE{
+    nRCGI                       NRCGI,
+    dl-TotalofAvailablePRBs     INTEGER (0..100) OPTIONAL,
+    ul-TotalofAvailablePRBs     INTEGER (0..100) OPTIONAL,
+    servedPlmnPerCellList       SEQUENCE (SIZE(1..maxPLMN)) OF ServedPlmnPerCellListItem,
+    ...
+}
+
+ServedPlmnPerCellListItem ::= SEQUENCE{
+	pLMN-Identity			PLMN-Identity,
+    du-PM-5GC               FGC-DU-PM-Container OPTIONAL,
+    du-PM-EPC               EPC-DU-PM-Container OPTIONAL,
+    ...
+}
+
+FGC-DU-PM-Container ::= SEQUENCE{
+    slicePerPlmnPerCellList SEQUENCE (SIZE(1..maxnoofSliceItems)) OF SlicePerPlmnPerCellListItem,
+    ...
+}
+
+SlicePerPlmnPerCellListItem ::= SEQUENCE{
+    sliceID		SNSSAI,
+    fQIPERSlicesPerPlmnPerCellList SEQUENCE (SIZE(1..maxnoofQoSFlows)) OF FQIPERSlicesPerPlmnPerCellListItem,
+    ...
+}
+
+FQIPERSlicesPerPlmnPerCellListItem ::= SEQUENCE{
+    fiveQI				   INTEGER (0..255),
+    dl-PRBUsage            INTEGER (0..100) OPTIONAL,
+    ul-PRBUsage            INTEGER (0..100) OPTIONAL,
+    ...
+}
+
+EPC-DU-PM-Container ::= SEQUENCE{
+    perQCIReportList SEQUENCE (SIZE(1..maxnoofQCI)) OF PerQCIReportListItem,
+    ...
+}
+
+PerQCIReportListItem ::= SEQUENCE{
+    qci                    INTEGER (0..255),
+    dl-PRBUsage            INTEGER (0..100) OPTIONAL,
+    ul-PRBUsage            INTEGER (0..100) OPTIONAL,
+    ...
+}
+
+-- **************************************************************
+-- O-CUCP Container IEs
+-- **************************************************************
+
+
+OCUCP-PF-Container ::= SEQUENCE{
+    gNB-CU-CP-Name GNB-CU-CP-Name OPTIONAL,
+    cu-CP-Resource-Status SEQUENCE {
+        numberOfActive-UEs  INTEGER (1..65536, ...) OPTIONAL
+    }
+}
+
+-- **************************************************************
+-- O-CU-UP Container IEs
+-- **************************************************************
+
+OCUUP-PF-Container ::= SEQUENCE{
+    gNB-CU-UP-Name        GNB-CU-UP-Name OPTIONAL,
+    pf-ContainerList      SEQUENCE (SIZE(1..maxnoofContainerListItems)) OF PF-ContainerListItem,
+    ...
+}
+
+PF-ContainerListItem ::= SEQUENCE{
+    interface-type				  NI-Type,
+    o-CU-UP-PM-Container          CUUPMeasurement-Container,
+    ...
+}
+
+CUUPMeasurement-Container ::= SEQUENCE{
+    plmnList SEQUENCE (SIZE(1.. maxPLMN)) OF PlmnID-List,
+    ...
+}
+
+PlmnID-List ::= SEQUENCE{
+	pLMN-Identity			 PLMN-Identity,
+    cu-UP-PM-5GC             FGC-CUUP-PM-Format OPTIONAL,
+    cu-UP-PM-EPC             EPC-CUUP-PM-Format OPTIONAL,
+    ...
+}
+
+FGC-CUUP-PM-Format ::= SEQUENCE{
+    sliceToReportList SEQUENCE (SIZE(1..maxnoofSliceItems)) OF SliceToReportListItem,
+    ...
+}
+
+SliceToReportListItem ::= SEQUENCE{
+    sliceID		SNSSAI,
+    fQIPERSlicesPerPlmnList SEQUENCE (SIZE(1..maxnoofQoSFlows)) OF FQIPERSlicesPerPlmnListItem,
+    ...
+}
+
+FQIPERSlicesPerPlmnListItem ::= SEQUENCE{
+     fiveQI					INTEGER (0..255),
+     pDCPBytesDL            INTEGER (0..10000000000,...) OPTIONAL,
+     pDCPBytesUL            INTEGER (0..10000000000,...) OPTIONAL,
+     ...
+}
+
+EPC-CUUP-PM-Format ::= SEQUENCE{
+    perQCIReportList SEQUENCE (SIZE(1..maxnoofQCI)) OF PerQCIReportListItemFormat,
+    ...
+}
+
+PerQCIReportListItemFormat ::= SEQUENCE{
+    qci                    INTEGER (0..255),
+    pDCPBytesDL            INTEGER (0..10000000000,...) OPTIONAL,
+    pDCPBytesUL            INTEGER (0..10000000000,...) OPTIONAL,
+    ...
+}
+
+
+END
+
+-- ASN1STOP
+
diff --git a/RIC-E2-TERMINATION/BuildRunName.h b/RIC-E2-TERMINATION/BuildRunName.h
index 801f365..e6eaccd 100644
--- a/RIC-E2-TERMINATION/BuildRunName.h
+++ b/RIC-E2-TERMINATION/BuildRunName.h
@@ -43,10 +43,10 @@
 
     int j = 0;
     if (mnc3 != 15) {
-        j = snprintf(plmnId, 20, "%s%1d%1d%1d-%1d%1d%1d", type, mcc1, mcc2, mcc3, mnc1, mnc2, mnc3);
+        j = snprintf(plmnId, 20, "%s%1d%1d%1d_%1d%1d%1d", type, mcc1, mcc2, mcc3, mnc1, mnc2, mnc3);
     }
     else {
-        j = snprintf(plmnId, 20, "%s%1d%1d%1d-0%1d%1d", type, mcc1, mcc2, mcc3, mnc1, mnc2);
+        j = snprintf(plmnId, 20, "%s%1d%1d%1d_0%1d%1d", type, mcc1, mcc2, mcc3, mnc1, mnc2);
     }
 
     return j;
@@ -55,7 +55,7 @@
 static int translateBitStringToChar(char *ranName, BIT_STRING_t &data) {
     // dont care of last unused bits
     char buffer[256] {};
-    auto j = snprintf(buffer, 256, "%s-", ranName);
+    auto j = snprintf(buffer, 256, "%s_", ranName);
     memcpy(ranName, buffer, j);
 
     unsigned b1 = 0;
@@ -77,7 +77,7 @@
     switch (ie->value.choice.GlobalE2node_ID.present) {
         case GlobalE2node_ID_PR_gNB: {
             auto *gnb = ie->value.choice.GlobalE2node_ID.choice.gNB;
-            translatePlmnId(ranName, (const unsigned char *)gnb->global_gNB_ID.plmn_id.buf, (const char *)"gnb:");
+            translatePlmnId(ranName, (const unsigned char *)gnb->global_gNB_ID.plmn_id.buf, (const char *)"gnb_");
             if (gnb->global_gNB_ID.gnb_id.present == GNB_ID_Choice_PR_gnb_ID) {
                 translateBitStringToChar(ranName, gnb->global_gNB_ID.gnb_id.choice.gnb_ID);
             }
@@ -87,7 +87,7 @@
             auto *enGnb = ie->value.choice.GlobalE2node_ID.choice.en_gNB;
             translatePlmnId(ranName,
                             (const unsigned char *)enGnb->global_gNB_ID.pLMN_Identity.buf,
-                            (const char *)"en-gnb:");
+                            (const char *)"en_gnb_");
             if (enGnb->global_gNB_ID.gNB_ID.present == ENGNB_ID_PR_gNB_ID) {
                 translateBitStringToChar(ranName, enGnb->global_gNB_ID.gNB_ID.choice.gNB_ID);
             }
@@ -100,17 +100,17 @@
             BIT_STRING_t *data = nullptr;
             switch (ngEnb->global_ng_eNB_ID.enb_id.present) {
                 case ENB_ID_Choice_PR_enb_ID_macro: {
-                    strncpy(str, (const char *)"ng-enB-macro:", 13);
+                    strncpy(str, (const char *)"ng_enB_macro_", 13);
                     data = &ngEnb->global_ng_eNB_ID.enb_id.choice.enb_ID_macro;
                     break;
                 }
                 case ENB_ID_Choice_PR_enb_ID_shortmacro: {
-                    strncpy(str, (const char *)"ng-enB-shortmacro:", 18);
+                    strncpy(str, (const char *)"ng_enB_shortmacro_", 18);
                     data = &ngEnb->global_ng_eNB_ID.enb_id.choice.enb_ID_shortmacro;
                     break;
                 }
                 case ENB_ID_Choice_PR_enb_ID_longmacro: {
-                    strncpy(str, (const char *)"ng-enB-longmacro:", 17);
+                    strncpy(str, (const char *)"ng_enB_longmacro_", 17);
                     data = &ngEnb->global_ng_eNB_ID.enb_id.choice.enb_ID_longmacro;
                 }
                 case ENB_ID_Choice_PR_NOTHING: {
@@ -131,22 +131,22 @@
 
             switch (enb->global_eNB_ID.eNB_ID.present) {
                 case ENB_ID_PR_macro_eNB_ID: {
-                    strncpy(str, (const char *)"enB-macro:", 10);
+                    strncpy(str, (const char *)"enB_macro_", 10);
                     data = &enb->global_eNB_ID.eNB_ID.choice.macro_eNB_ID;
                     break;
                 }
                 case ENB_ID_PR_home_eNB_ID: {
-                    strncpy(str, (const char *)"enB-home:", 9);
+                    strncpy(str, (const char *)"enB_home_", 9);
                     data = &enb->global_eNB_ID.eNB_ID.choice.home_eNB_ID;
                     break;
                 }
                 case ENB_ID_PR_short_Macro_eNB_ID: {
-                    strncpy(str, (const char *)"enB-shortmacro:", 15);
+                    strncpy(str, (const char *)"enB_shortmacro_", 15);
                     data = &enb->global_eNB_ID.eNB_ID.choice.short_Macro_eNB_ID;
                     break;
                 }
                 case ENB_ID_PR_long_Macro_eNB_ID: {
-                    strncpy(str, (const char *)"enB-longmacro:", 14);
+                    strncpy(str, (const char *)"enB_longmacro_", 14);
                     data = &enb->global_eNB_ID.eNB_ID.choice.long_Macro_eNB_ID;
                     break;
                 }
diff --git a/RIC-E2-TERMINATION/BuildXml.h b/RIC-E2-TERMINATION/BuildXml.h
index beca88b..e71fa4d 100644
--- a/RIC-E2-TERMINATION/BuildXml.h
+++ b/RIC-E2-TERMINATION/BuildXml.h
@@ -21,6 +21,7 @@
 
 #ifndef E2_BUILDXML_H
 #define E2_BUILDXML_H
+
 #include <iostream>
 #include <iosfwd>
 #include <vector>
@@ -42,32 +43,6 @@
         result.append(static_cast<const char *>(data), size);
     }
 };
-// end::code[]
-
-//struct xml_memory_writer : pugi::xml_writer {
-//    char *buffer;
-//    size_t capacity;
-//    size_t result;
-//
-//    xml_memory_writer() : buffer(nullptr), capacity(0), result(0) {
-//    }
-//
-//    xml_memory_writer(char *buffer, size_t capacity) : buffer(buffer), capacity(capacity), result(0) {
-//    }
-//
-//    [[nodiscard]] size_t written_size() const {
-//        return result < capacity ? result : capacity;
-//    }
-//
-//    void write(const void *data, size_t size) override {
-//        if (result < capacity) {
-//            size_t chunk = (capacity - result < size) ? capacity - result : size;
-//
-//            memcpy(buffer + result, data, chunk);
-//        }
-//        result += size;
-//    }
-//};
 
 std::string node_to_string(pugi::xml_node node) {
     xml_string_writer writer;
@@ -76,15 +51,24 @@
     return writer.result;
 }
 
+string buildXmlData(const string &messageName,
+        const string &ieName,
+        vector<string> &RANfunctionsAdded,
+        vector<string> &RANfunctionsModified,
+        unsigned char *buffer,
+        size_t size) {
+    pugi::xml_document *doc = new pugi::xml_document();
 
-int buildXmlData(const string &messageName, const string &ieName, vector<string> &RANfunctionsAdded, unsigned char *buffer, size_t size) {
-    pugi::xml_document doc;
+    char RANfunctionsAddedID[8];
+    snprintf(RANfunctionsAddedID, 8, "%d", (int) ProtocolIE_ID_id_RANfunctionsAdded);
+    char RANfunctionsModifiedID[8];
+    snprintf(RANfunctionsModifiedID, 8, "%d", (int) ProtocolIE_ID_id_RANfunctionsModified);
+    char GlobalE2nodeID[8];
+    snprintf(GlobalE2nodeID, 8, "%d", (int) ProtocolIE_ID_id_GlobalE2node_ID);
 
-    doc.reset();
-    pugi::xml_parse_result result = doc.load_buffer((const char *)buffer, size);
+    pugi::xml_parse_result result = doc->load_buffer((const char *) buffer, size);
     if (result) {
-        unsigned int index = 0;
-        for (auto tool : doc.child("E2AP-PDU")
+        for (auto tool : doc->child("E2AP-PDU")
                 .child("initiatingMessage")
                 .child("value")
                 .child(messageName.c_str())
@@ -94,14 +78,14 @@
             auto node = tool.child("id");  // get the id to identify the type of the contained message
             if (node.empty()) {
                 mdclog_write(MDCLOG_ERR, "Failed to find ID node in the XML. File %s, line %d",
-                        __FILE__, __LINE__);
+                             __FILE__, __LINE__);
                 continue;
             }
-            if (strcmp(node.name(), "id") == 0 && strcmp(node.child_value(), "10") == 0) {
+            if (strcmp(node.name(), "id") == 0 && strcmp(node.child_value(), RANfunctionsAddedID) == 0) {
                 auto nodea = tool.child("value").
                         child("RANfunctions-List").
                         children("ProtocolIE-SingleContainer");
-
+                unsigned int index = 0;
                 for (auto n1 : nodea) {
                     auto n2 = n1.child("value").child("RANfunction-Item").child("ranFunctionDefinition");
                     n2.remove_children();
@@ -112,22 +96,41 @@
                         mdclog_write(MDCLOG_DEBUG, "entry %s Replaced with : %s", n2.name(), n2.child_value());
                     }
                 }
+            } else if (strcmp(node.name(), "id") == 0 && strcmp(node.child_value(), RANfunctionsModifiedID) == 0) {
+                auto nodea = tool.child("value").
+                        child("RANfunctions-List").
+                        children("ProtocolIE-SingleContainer");
+                unsigned int index = 0;
+                for (auto n1 : nodea) {
+                    auto n2 = n1.child("value").child("RANfunction-Item").child("ranFunctionDefinition");
+                    n2.remove_children();
+                    string val = RANfunctionsModified.at(index++);
+                    // here we get vector with counter
+                    n2.append_child(pugi::node_pcdata).set_value(val.c_str());
+                    if (mdclog_level_get() >= MDCLOG_DEBUG) {
+                        mdclog_write(MDCLOG_DEBUG, "entry %s Replaced with : %s", n2.name(), n2.child_value());
+                    }
+                }
+            } else if (strcmp(node.name(), "id") == 0 && strcmp(node.child_value(), GlobalE2nodeID) == 0) {
+                continue;
             } else {
                 if (mdclog_level_get() >= MDCLOG_DEBUG) {
-                    mdclog_write(MDCLOG_DEBUG, "Entry %s = value %s skipped", node.name(), node.child_value());
+                    mdclog_write(MDCLOG_DEBUG, "Entry name :%s  with entry of %s skipped", node.name(), node.child_value());
                 }
                 continue;
             }
         }
-
-        auto res = node_to_string(doc);
-        memcpy(buffer, res.c_str(), res.length());
-        doc.reset();
     } else {
-        mdclog_write(MDCLOG_ERR, "Error loading xml string");
-        return -1;
+        mdclog_write(MDCLOG_ERR,
+                     "Error loading xml string");
+        delete doc;
+        return string("");
     }
-    return 0;
+    auto res = node_to_string(*doc);
+    res.erase(std::remove(res.begin(), res.end(), '\n'), res.end());
+    res.erase(std::remove(res.begin(), res.end(), '\t'), res.end());
+    delete doc;
+    return res;
 
 }
 
diff --git a/RIC-E2-TERMINATION/CMakeLists.txt b/RIC-E2-TERMINATION/CMakeLists.txt
index 75f27b1..fbb9a12 100644
--- a/RIC-E2-TERMINATION/CMakeLists.txt
+++ b/RIC-E2-TERMINATION/CMakeLists.txt
@@ -44,6 +44,8 @@
         RIC-E2-TERMINATION/3rdparty/oranE2
         RIC-E2-TERMINATION/3rdparty/oranE2SM
         RIC-E2-TERMINATION/3rdparty/cxxopts/include
+        RIC-E2-TERMINATION/3rdparty/prometheus-cpp
+        RIC-E2-TERMINATION/3rdparty/prometheus-cpp/core/include
         RIC-E2-TERMINATION/3rdparty
         cmake-modules)
 
@@ -99,6 +101,11 @@
         tbb
         boost_filesystem
         cgreen
+        prometheus-cpp-core
+        prometheus-cpp-pull
+        prometheus-cpp-push
+        z
+        curl
         pthread)
 
 add_executable(e2 RIC-E2-TERMINATION/sctpThread.cpp
@@ -109,7 +116,6 @@
         RIC-E2-TERMINATION/base64.cpp
         RIC-E2-TERMINATION/ReadConfigFile.h
         RIC-E2-TERMINATION/BuildRunName.h
-        RIC-E2-TERMINATION/statCollector.h
         RIC-E2-TERMINATION/3rdparty/pugixml/src/pugiconfig.hpp
         RIC-E2-TERMINATION/3rdparty/pugixml/src/pugixml.cpp
         RIC-E2-TERMINATION/3rdparty/pugixml/src/pugixml.hpp
@@ -119,6 +125,9 @@
 target_link_libraries(e2 libicui18n.a)
 target_link_libraries(e2 libicuuc.a)
 target_link_libraries(e2 libicudata.a)
+target_link_libraries(e2 prometheus-cpp-core.a)
+target_link_libraries(e2 prometheus-cpp-pull.a)
+target_link_libraries(e2 prometheus-cpp-push.a)
 
 #target_link_libraries(e2 libnng.a)
 
@@ -147,7 +156,6 @@
         )
 target_link_libraries(sctpClient libpistache.a)
 target_link_libraries(sctpClient librmr_si.a)
-#target_link_libraries(sctpClient libnng.a)
 
 add_executable(setUpMessages
         RIC-E2-TERMINATION/TEST/testAsn/setUpMessages/SetUpMessages.cpp
diff --git a/RIC-E2-TERMINATION/Dockerfile b/RIC-E2-TERMINATION/Dockerfile
index f617363..bbef135 100644
--- a/RIC-E2-TERMINATION/Dockerfile
+++ b/RIC-E2-TERMINATION/Dockerfile
@@ -50,8 +50,9 @@
     && cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DPISTACHE_BUILD_DOCS=false \
        -DPISTACHE_USE_SSL=false -DPISTACHE_BUILD_TESTS=false -DCMAKE_INSTALL_PREFIX=/usr/local ../ \
     && make -j && make install && ldconfig \
-#    && git clone http://gerrit.o-ran-sc.org/r/com/log \
-#    && cd log && ./autogen.sh && ./configure && make && make install && ldconfig \
+    && cd /opt/e2/RIC-E2-TERMINATION/3rdparty && git clone -v https://github.com/jupp0r/prometheus-cpp.git \
+    && cd prometheus-cpp && git submodule init && git submodule update && mkdir build && cd build \
+    && cmake .. -DBUILD_SHARED_LIBS=OFF && make -j 4  && make install && ldconfig \
     && cd /opt/e2/RIC-E2-TERMINATION/3rdparty && git clone https://github.com/jarro2783/cxxopts.git \
     && cd /opt/e2/RIC-E2-TERMINATION/3rdparty && git clone https://github.com/Tencent/rapidjson.git \
     && cd /opt/e2/RIC-E2-TERMINATION/3rdparty && git clone https://github.com/zeux/pugixml.git \
@@ -141,6 +142,11 @@
 
 COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/lib/libstdc++.so.6
 
+COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4.5.0 /usr/lib/libcurl-gnutls.so.4.5.0
+COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4 /usr/lib/libcurl-gnutls.so.4
+COPY --from=ubuntu /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so /usr/lib/libcurl-gnutls.so
+
+
 WORKDIR /opt/e2/
 ENV LD_LIBRARY_PATH=/usr/local/lib
 ENV RMR_SEED_RT=dockerRouter.txt
diff --git a/RIC-E2-TERMINATION/TEST/T1/E2Builder.h b/RIC-E2-TERMINATION/TEST/T1/E2Builder.h
index a82d246..af2f39e 100644
--- a/RIC-E2-TERMINATION/TEST/T1/E2Builder.h
+++ b/RIC-E2-TERMINATION/TEST/T1/E2Builder.h
@@ -33,6 +33,7 @@
 #include <3rdparty/oranE2SM/RIC-InsertStyle-List.h>
 #include <3rdparty/oranE2SM/RANparameterDef-Item.h>
 #include <3rdparty/oranE2/GlobalE2node-en-gNB-ID.h>
+#include <3rdparty/oranE2/RICsubsequentAction.h>
 
 
 //#include <mdclog/mdclog.h>
@@ -571,8 +572,6 @@
     ranFlistIEs->id = ProtocolIE_ID_id_RANfunctionsAdded;
     ranFlistIEs->value.present = E2setupRequestIEs__value_PR_RANfunctions_List;
 
-    auto *itemIes = (RANfunction_ItemIEs_t *)calloc(1, sizeof(RANfunction_ItemIEs_t));
-    ASN_STRUCT_RESET(asn_DEF_RANfunction_ItemIEs, itemIes);
 
 
     E2SM_gNB_NRT_RANfunction_Definition_t ranFunDef;
@@ -621,6 +620,9 @@
     ASN_SEQUENCE_ADD(&ranFunDef.ric_InsertStyle_List->list, &insertStyleList);
     //ranFunDef.ric_InsertStyle_List.
 
+    auto *itemIes = (RANfunction_ItemIEs_t *)calloc(1, sizeof(RANfunction_ItemIEs_t));
+    ASN_STRUCT_RESET(asn_DEF_RANfunction_ItemIEs, itemIes);
+
     uint8_t buffer[8192];
     size_t buffer_size = 8192;
     auto *ranDef = &itemIes->value.choice.RANfunction_Item.ranFunctionDefinition;
@@ -638,8 +640,6 @@
         memcpy(ranDef->buf, buffer, ranDef->size);
     }
 
-
-
     itemIes->id = ProtocolIE_ID_id_RANfunction_Item;
     itemIes->criticality = Criticality_reject;
     itemIes->value.present = RANfunction_ItemIEs__value_PR_RANfunction_Item;
@@ -672,7 +672,109 @@
 }
 
 
+void buildSubsReq(E2AP_PDU_t *pdu) {
+    ASN_STRUCT_RESET(asn_DEF_E2AP_PDU, pdu);
 
+    pdu->choice.initiatingMessage = (InitiatingMessage_t *)calloc(1, sizeof(InitiatingMessage_t));
+    pdu->present = E2AP_PDU_PR_initiatingMessage;
+
+    auto *initMsg = pdu->choice.initiatingMessage;
+    ASN_STRUCT_RESET(asn_DEF_InitiatingMessage, initMsg);
+    initMsg->procedureCode = ProcedureCode_id_RICsubscription;
+    initMsg->criticality = Criticality_reject;
+    initMsg->value.present = InitiatingMessage__value_PR_RICsubscriptionRequest;
+
+    auto *subReq = &(initMsg->value.choice.RICsubscriptionRequest);
+    ASN_STRUCT_RESET(asn_DEF_RICsubscriptionRequest, subReq);
+
+    { // RICrequestID
+        auto *e = (RICsubscriptionRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionRequest_IEs_t));
+        ASN_STRUCT_RESET(asn_DEF_RICsubscriptionRequest_IEs, e);
+        e->id = ProtocolIE_ID_id_RICrequestID;
+        e->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID;
+        e->value.choice.RICrequestID.ricRequestorID = 88;
+        e->value.choice.RICrequestID.ricInstanceID = 5;
+        ASN_SEQUENCE_ADD(&subReq->protocolIEs.list, e);
+    }
+    { // RANfunctionID
+        auto *e = (RICsubscriptionRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionRequest_IEs_t));
+        ASN_STRUCT_RESET(asn_DEF_RICsubscriptionRequest_IEs, e);
+        e->id = ProtocolIE_ID_id_RANfunctionID;
+        e->criticality = Criticality_reject;
+        e->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID;
+        e->value.choice.RANfunctionID = 8;
+        ASN_SEQUENCE_ADD(&subReq->protocolIEs.list, e);
+    }
+    { // RICrequestID
+        auto *e = (RICsubscriptionRequest_IEs_t *)calloc(1, sizeof(RICsubscriptionRequest_IEs_t));
+        ASN_STRUCT_RESET(asn_DEF_RICsubscriptionRequest_IEs, e);
+        e->id = ProtocolIE_ID_id_RICsubscriptionDetails;
+        e->criticality = Criticality_reject;
+        e->value.present = RICsubscriptionRequest_IEs__value_PR_RICsubscriptionDetails;
+
+        uint8_t buf[10] = {1,2,3,4,5,6,7,8,9,0} ;
+        e->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.size = 10;
+        e->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf = (uint8_t *)calloc(1, 10);
+        memcpy(e->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.buf,
+                buf,
+                e->value.choice.RICsubscriptionDetails.ricEventTriggerDefinition.size);
+        { // item 1
+            auto ie = (RICaction_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(RICaction_ToBeSetup_ItemIEs_t));
+            ASN_STRUCT_RESET(asn_DEF_RICaction_ToBeSetup_ItemIEs, ie);
+            ie->id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item;
+            ie->criticality = Criticality_ignore;
+            ie->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
+            ie->value.choice.RICaction_ToBeSetup_Item.ricActionID = 22;
+            ie->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_report;
+
+            auto *ad = (RICactionDefinition_t *)calloc(1, sizeof(RICactionDefinition_t));
+            ASN_STRUCT_RESET(asn_DEF_RICactionDefinition, ad);
+            ad->size = 10;
+            uint8_t buf[10] = {1,2,3,4,5,6,7,8,9,0} ;
+            ad->buf = (uint8_t *)calloc(1, ad->size);
+            memcpy(ad->buf, buf, ad->size);
+            ie->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition = ad;
+
+            auto *sa = (RICsubsequentAction_t *) calloc(1, sizeof(RICsubsequentAction_t));
+            ASN_STRUCT_RESET(asn_DEF_RICsubsequentAction, sa);
+
+            sa->ricTimeToWait = RICtimeToWait_w500ms;
+            sa->ricSubsequentActionType = RICsubsequentActionType_continue;
+
+            ie->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = sa;
+            ASN_SEQUENCE_ADD(&e->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.list, ie);
+        }
+
+        { // item 2
+            auto ie = (RICaction_ToBeSetup_ItemIEs_t *)calloc(1, sizeof(RICaction_ToBeSetup_ItemIEs_t));
+            ASN_STRUCT_RESET(asn_DEF_RICaction_ToBeSetup_ItemIEs, ie);
+            ie->id = ProtocolIE_ID_id_RICaction_ToBeSetup_Item;
+            ie->criticality = Criticality_ignore;
+            ie->value.present = RICaction_ToBeSetup_ItemIEs__value_PR_RICaction_ToBeSetup_Item;
+            ie->value.choice.RICaction_ToBeSetup_Item.ricActionID = 47;
+            ie->value.choice.RICaction_ToBeSetup_Item.ricActionType = RICactionType_policy;
+
+            auto *ad = (RICactionDefinition_t *)calloc(1, sizeof(RICactionDefinition_t));
+            ASN_STRUCT_RESET(asn_DEF_RICactionDefinition, ad);
+            ad->size = 10;
+            uint8_t buf[10] = {1,2,3,4,5,6,7,8,9,0} ;
+            ad->buf = (uint8_t *)calloc(1, ad->size);
+            memcpy(ad->buf, buf, ad->size);
+            ie->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition = ad;
+
+            auto *sa = (RICsubsequentAction_t *) calloc(1, sizeof(RICsubsequentAction_t));
+            ASN_STRUCT_RESET(asn_DEF_RICsubsequentAction, sa);
+
+            sa->ricTimeToWait = RICtimeToWait_w5s;
+            sa->ricSubsequentActionType = RICsubsequentActionType_wait;
+
+            ie->value.choice.RICaction_ToBeSetup_Item.ricSubsequentAction = sa;
+            ASN_SEQUENCE_ADD(&e->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.list, ie);
+        }
+
+        ASN_SEQUENCE_ADD(&subReq->protocolIEs.list, e);
+    }
+}
 
 
 void buildSetupSuccsessfulResponse(E2AP_PDU_t *pdu, int mcc, int mnc, uint8_t *data) {
@@ -784,4 +886,254 @@
     pdu->present = E2AP_PDU_PR_unsuccessfulOutcome;
 }
 
+void buildResetReq(E2AP_PDU_t *pdu) {
+    ASN_STRUCT_RESET(asn_DEF_E2AP_PDU, pdu);
+
+    pdu->choice.initiatingMessage = (InitiatingMessage_t *)calloc(1, sizeof(InitiatingMessage_t));
+    pdu->present = E2AP_PDU_PR_initiatingMessage;
+
+    auto *initMsg = pdu->choice.initiatingMessage;
+    ASN_STRUCT_RESET(asn_DEF_InitiatingMessage, initMsg);
+    initMsg->procedureCode = ProcedureCode_id_Reset;
+    initMsg->criticality = Criticality_reject;
+    initMsg->value.present = InitiatingMessage__value_PR_ResetRequest;
+
+
+    auto *resetReq = &(initMsg->value.choice.ResetRequest);
+    ASN_STRUCT_RESET(asn_DEF_ResetRequest, resetReq);
+
+    { //
+        auto *e = (ResetRequestIEs_t *)calloc(1, sizeof(ResetRequestIEs_t));
+        ASN_STRUCT_RESET(asn_DEF_ResetRequestIEs, e);
+        e->id = ProtocolIE_ID_id_Cause;
+        e->criticality = Criticality_ignore;
+        e->value.present = ResetRequestIEs__value_PR_Cause;
+        e->value.choice.Cause.present = Cause_PR_ricRequest;
+        e->value.choice.Cause.choice.ricRequest = 1;
+        ASN_SEQUENCE_ADD(&resetReq->protocolIEs.list, e);
+    }
+
+}
+
+void buildResetResponse(E2AP_PDU_t *pdu) {
+    ASN_STRUCT_RESET(asn_DEF_E2AP_PDU, pdu);
+
+    pdu->choice.successfulOutcome = (SuccessfulOutcome_t *)calloc(1, sizeof(SuccessfulOutcome_t));
+    pdu->present = E2AP_PDU_PR_successfulOutcome;
+
+    auto *succ = pdu->choice.successfulOutcome;
+    ASN_STRUCT_RESET(asn_DEF_InitiatingMessage, succ);
+    succ->procedureCode = ProcedureCode_id_Reset;
+    succ->criticality = Criticality_reject;
+    succ->value.present = SuccessfulOutcome__value_PR_ResetResponse;
+
+
+    auto *resetRespo = &(succ->value.choice.ResetResponse);
+    ASN_STRUCT_RESET(asn_DEF_ResetResponse, resetRespo);
+
+    { //
+        auto *e = (ResetResponseIEs_t *)calloc(1, sizeof(ResetResponseIEs_t));
+        ASN_STRUCT_RESET(asn_DEF_ResetResponseIEs, e);
+        e->id = ProtocolIE_ID_id_CriticalityDiagnostics;
+        e->criticality = Criticality_ignore;
+        e->value.present = ResetResponseIEs__value_PR_CriticalityDiagnostics;
+
+        e->value.choice.CriticalityDiagnostics.procedureCode = (ProcedureCode_t *)calloc(1,sizeof(ProcedureCode_t));
+        *e->value.choice.CriticalityDiagnostics.procedureCode = ProcedureCode_id_Reset;
+        e->value.choice.CriticalityDiagnostics.triggeringMessage = (TriggeringMessage_t *)calloc(1,sizeof(TriggeringMessage_t));
+        *e->value.choice.CriticalityDiagnostics.triggeringMessage = TriggeringMessage_initiating_message;
+        e->value.choice.CriticalityDiagnostics.procedureCriticality = (Criticality_t *)calloc(1, sizeof(Criticality_t));
+        *e->value.choice.CriticalityDiagnostics.procedureCriticality = Criticality_reject;
+        ASN_SEQUENCE_ADD(&resetRespo->protocolIEs.list, e);
+    }
+
+}
+
+void buildServiceQuery(E2AP_PDU_t *pdu) {
+    ASN_STRUCT_RESET(asn_DEF_E2AP_PDU, pdu);
+
+    pdu->choice.initiatingMessage = (InitiatingMessage_t *)calloc(1, sizeof(InitiatingMessage_t));
+    pdu->present = E2AP_PDU_PR_initiatingMessage;
+
+    auto *initMsg = pdu->choice.initiatingMessage;
+    ASN_STRUCT_RESET(asn_DEF_InitiatingMessage, initMsg);
+    initMsg->procedureCode = ProcedureCode_id_RICserviceQuery;
+    initMsg->criticality = Criticality_ignore;
+    initMsg->value.present = InitiatingMessage__value_PR_RICserviceQuery;
+
+
+    auto *serviceQuery = &(initMsg->value.choice.RICserviceQuery);
+    ASN_STRUCT_RESET(asn_DEF_ResetRequest, serviceQuery);
+
+    { //
+        auto *e = (RICserviceQuery_IEs_t *)calloc(1, sizeof(RICserviceQuery_IEs_t));
+        ASN_STRUCT_RESET(asn_DEF_RICserviceQuery_IEs, e);
+        e->id = ProtocolIE_ID_id_RANfunctionsAccepted;
+        e->criticality = Criticality_reject;
+        e->value.present = RICserviceQuery_IEs__value_PR_RANfunctionsID_List;
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_ignore;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 10;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 1;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_ignore;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 11;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 2;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_ignore;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 28;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 13;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_ignore;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 1;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 4;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        ASN_SEQUENCE_ADD(&serviceQuery->protocolIEs.list, e);
+    }
+
+}
+void buildServiceUpdateResponce(E2AP_PDU_t *pdu) {
+    ASN_STRUCT_RESET(asn_DEF_E2AP_PDU, pdu);
+
+    pdu->choice.successfulOutcome = (SuccessfulOutcome_t *)calloc(1, sizeof(SuccessfulOutcome_t));
+    pdu->present = E2AP_PDU_PR_successfulOutcome;
+
+    auto *succ = pdu->choice.successfulOutcome;
+    ASN_STRUCT_RESET(asn_DEF_SuccessfulOutcome, succ);
+    succ->procedureCode = ProcedureCode_id_RICserviceQuery;
+    succ->criticality = Criticality_reject;
+    succ->value.present = SuccessfulOutcome__value_PR_RICserviceUpdateAcknowledge;
+
+
+    auto *serviceUpdAck = &(succ->value.choice.RICserviceUpdateAcknowledge);
+    ASN_STRUCT_RESET(asn_DEF_RICserviceUpdateAcknowledge, serviceUpdAck);
+
+    { //
+        auto *e = (RICserviceUpdateAcknowledge_IEs_t *)calloc(1, sizeof(RICserviceUpdateAcknowledge_IEs_t));
+        ASN_STRUCT_RESET(asn_DEF_RICserviceUpdateAcknowledge_IEs, e);
+        e->id = ProtocolIE_ID_id_RANfunctionsAccepted;
+        e->criticality = Criticality_reject;
+        e->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsID_List;
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_reject;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 10;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 1;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_reject;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 11;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 2;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_reject;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 28;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 13;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        {
+            auto *ranFuncIdItemIEs = (RANfunctionID_ItemIEs_t *)calloc(1, sizeof(RANfunctionID_ItemIEs_t));
+
+            ranFuncIdItemIEs->criticality = Criticality_reject;
+            ranFuncIdItemIEs->id = ProtocolIE_ID_id_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.present = RANfunctionID_ItemIEs__value_PR_RANfunctionID_Item;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionID = 1;
+            ranFuncIdItemIEs->value.choice.RANfunctionID_Item.ranFunctionRevision = 4;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsID_List.list, ranFuncIdItemIEs);
+        }
+        ASN_SEQUENCE_ADD(&serviceUpdAck->protocolIEs.list, e);
+    }
+
+
+    {
+        auto *e = (RICserviceUpdateAcknowledge_IEs_t *)calloc(1, sizeof(RICserviceUpdateAcknowledge_IEs_t));
+        ASN_STRUCT_RESET(asn_DEF_RICserviceUpdateAcknowledge_IEs, e);
+        e->id = ProtocolIE_ID_id_RANfunctionsRejected;
+        e->criticality = Criticality_reject;
+        e->value.present = RICserviceUpdateAcknowledge_IEs__value_PR_RANfunctionsIDcause_List;
+        {
+
+            auto *ranFuncIdcause = (RANfunctionIDcause_ItemIEs_t *) calloc(1, sizeof(RANfunctionIDcause_ItemIEs_t));
+            ASN_STRUCT_RESET(asn_DEF_RANfunctionIDcause_Item, ranFuncIdcause);
+
+            ranFuncIdcause->criticality = Criticality_ignore;
+            ranFuncIdcause->id = ProtocolIE_ID_id_RANfunctionIEcause_Item;
+            ranFuncIdcause->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.ranFunctionID = 1;
+
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.cause.present = Cause_PR_ricService;
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.cause.choice.ricService = 1;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsIDcause_List.list, ranFuncIdcause);
+
+        }
+        {
+
+            auto *ranFuncIdcause = (RANfunctionIDcause_ItemIEs_t *) calloc(1, sizeof(RANfunctionIDcause_ItemIEs_t));
+            ASN_STRUCT_RESET(asn_DEF_RANfunctionIDcause_Item, ranFuncIdcause);
+
+            ranFuncIdcause->criticality = Criticality_ignore;
+            ranFuncIdcause->id = ProtocolIE_ID_id_RANfunctionIEcause_Item;
+            ranFuncIdcause->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.ranFunctionID = 2;
+
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.cause.present = Cause_PR_ricService;
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.cause.choice.ricService = 2;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsIDcause_List.list, ranFuncIdcause);
+
+        }
+        {
+            auto *ranFuncIdcause = (RANfunctionIDcause_ItemIEs_t *) calloc(1, sizeof(RANfunctionIDcause_ItemIEs_t));
+            ASN_STRUCT_RESET(asn_DEF_RANfunctionIDcause_Item, ranFuncIdcause);
+
+            ranFuncIdcause->criticality = Criticality_ignore;
+            ranFuncIdcause->id = ProtocolIE_ID_id_RANfunctionIEcause_Item;
+            ranFuncIdcause->value.present = RANfunctionIDcause_ItemIEs__value_PR_RANfunctionIDcause_Item;
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.ranFunctionID = 3;
+
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.cause.present = Cause_PR_ricService;
+            ranFuncIdcause->value.choice.RANfunctionIDcause_Item.cause.choice.ricService = 2;
+            ASN_SEQUENCE_ADD(&e->value.choice.RANfunctionsIDcause_List.list, ranFuncIdcause);
+
+        }
+        ASN_SEQUENCE_ADD(&serviceUpdAck->protocolIEs.list, e);
+    }
+
+}
+
 #endif //E2_E2BUILDER_H
diff --git a/RIC-E2-TERMINATION/TEST/testAsn/T2/SubscriptionTest.cpp b/RIC-E2-TERMINATION/TEST/testAsn/T2/SubscriptionTest.cpp
deleted file mode 100644
index f0d4c50..0000000
--- a/RIC-E2-TERMINATION/TEST/testAsn/T2/SubscriptionTest.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright 2019 AT&T Intellectual Property
- * Copyright 2019 Nokia
- *
- * 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.
- */
-
-/*
- * This source code is part of the near-RT RIC (RAN Intelligent Controller)
- * platform project (RICP).
- */
-
-
-//
-// Created by adi ENZEL on 6/17/19.
-//
-
-#include <mdclog/mdclog.h>
-
-#include "asn/type_defs.h"
-#include "asn/per/codec.hpp"
-#include "asn/printer.hpp"
-
-#include "X2AP-CommonDataTypes.hpp"
-#include "X2AP-Containers.hpp"
-#include "X2AP-Constants.hpp"
-#include "X2AP-IEs.hpp"
-#include "X2AP-PDU-Contents.hpp"
-
-#include "E2AP-Constants.hpp"
-#include "E2AP-IEs.hpp"
-#include "E2AP-PDU-Contents.hpp"
-#include "E2AP-PDU-Descriptions.hpp"
-
-
-#include <iostream>
-#include <cstdio>
-#include <cctype>
-#include <cstring>
-
-#include <pthread.h>
-#include <rmr/rmr.h>
-#include <rmr/RIC_message_types.h>
-
-#include "logInit.h"
-
-// test X2SetUP request and response
-using namespace std;
-
-#define MAXEVENTS 64
-
-int main(const int argc, char **argv) {
-    mdclog_severity_t loglevel = MDCLOG_INFO;
-
-    auto buff = new string("Subscription TEST");
-    init_log((char *)buff->c_str());
-
-    mdclog_level_set(loglevel);
-
-    if (argc < 5){
-        mdclog_mdc_add("app", argv[0]);
-        mdclog_write(MDCLOG_ERR, "Usage ran <ran name> rmr <rmr address> [logLevel <debug/warning/info/error]");
-        return -1 ;
-    }
-
-    char ranName[256] {0};
-    char rmrAddress[256] {0};
-
-    char str1[128];
-    for (int i = 1; i < argc; i += 2) {
-        for (int j = 0; j < strlen(argv[i]); j++) {
-            str1[j] = (char)tolower(argv[i][j]);
-        }
-        str1[strlen(argv[i])] = 0;
-        if (strcmp("ran", str1) == 0) {
-            strcpy(ranName, argv[i + 1]);
-        } else if (strcmp("rmr", str1) == 0) {
-            strcpy(rmrAddress, argv[i + 1]);
-        } else if (strcmp("loglevel", str1) == 0) {
-            if (strcmp("debug", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_DEBUG;
-            } else if (strcmp("info", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_INFO;
-            } else if (strcmp("warning", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_WARN;
-            } else if (strcmp("error", argv[i + 1]) == 0) {
-                loglevel = MDCLOG_ERR;
-            }
-        }
-    }
-
-    void *rmrCtx = rmr_init(rmrAddress, RMR_MAX_RCV_BYTES, RMRFL_NONE);
-    if (rmrCtx == nullptr ) {
-        mdclog_write(MDCLOG_ERR, "RMR failed to initialise : %s", strerror(errno));
-        return(-1);
-    }
-
-    // get the RMR fd for the epoll
-    auto rmrListenFd = rmr_get_rcvfd(rmrCtx);
-
-    auto epoll_fd = epoll_create1(0);
-    if (epoll_fd == -1) {
-        mdclog_write(MDCLOG_ERR,"failed to open epoll descriptor");
-        rmr_close(rmrCtx);
-        return -2;
-    }
-
-    struct epoll_event event {};
-    event.events = EPOLLIN;
-    event.data.fd = rmrListenFd;
-    // add listening sctpPort to epoll
-    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, rmrListenFd, &event)) {
-        mdclog_write(MDCLOG_ERR, "Failed to add RMR descriptor to epoll");
-        close(rmrListenFd);
-        rmr_close(rmrCtx);
-        return -3;
-    }
-
-
-    // we need to find that routing table exist and we can run
-    if (mdclog_level_get() >= MDCLOG_INFO) {
-        mdclog_write(MDCLOG_INFO, "We are after RMR INIT wait for RMR_Ready");
-    }
-
-    int rmrReady = 0;
-    int count = 0;
-    while (!rmrReady) {
-        if ((rmrReady = rmr_ready(rmrCtx)) == 0) {
-            sleep(1);
-        }
-        count++;
-        if (count % 60 == 0) {
-            mdclog_write(MDCLOG_INFO, "waiting to RMR ready state for %d seconds", count);
-        }
-        if (count > 180) {
-            mdclog_write(MDCLOG_ERR, "RMR not ready tried for 3 minutes ");
-            return(-2);
-        }
-    }
-    if (mdclog_level_get() >= MDCLOG_INFO) {
-        mdclog_write(MDCLOG_INFO, "RMR running");
-    }
-
-    E2AP_PDU cuAckPdu {};
-    auto &succ = cuAckPdu.select_successfulOutcome();
-    succ.ref_procedureCode().select_id_endcConfigurationUpdate();
-    succ.ref_criticality().select_id_endcConfigurationUpdate();
-    auto &endcConfAck = succ.ref_value().select_id_endcConfigurationUpdate();
-    auto &confAckIes =  endcConfAck.ref_protocolIEs();
-
-    ENDCConfigurationUpdateAcknowledge::protocolIEs_t::value_type endcENB {};
-    endcENB.ref_id().select_id_RespondingNodeType_EndcConfigUpdate();
-    endcENB.ref_criticality().select_id_RespondingNodeType_EndcConfigUpdate();
-
-    auto &respondingNode = endcENB.ref_value().select_id_RespondingNodeType_EndcConfigUpdate();
-
-    auto &enb = respondingNode.select_respond_eNB();
-
-
-    confAckIes.push_back(endcENB);
-
-
-
-    E2AP_PDU pdu {};
-    auto &initiatingMsg = pdu.select_initiatingMessage();
-    initiatingMsg.ref_procedureCode().select_id_ricSubscription();
-    initiatingMsg.ref_criticality().select_id_ricSubscription();
-    auto &subscription = initiatingMsg.ref_value().select_id_ricSubscription();
-
-    auto &ies = subscription.ref_protocolIEs();
-
-
-
-    RICsubscriptionRequest::protocolIEs_t::value_type ranFuncId {};
-    ranFuncId.ref_id().select_id_RANfunctionID();
-    ranFuncId.ref_criticality().select_id_RANfunctionID();
-    ranFuncId.ref_value().select_id_RANfunctionID().set(28);
-    ies.push_back(ranFuncId);
-
-    RICsubscriptionRequest::protocolIEs_t::value_type ricRequestId {};
-    ricRequestId.ref_id().select_id_RICrequestID();
-    ricRequestId.ref_criticality().select_id_RICrequestID();
-    ricRequestId.ref_value().select_id_RICrequestID().ref_ricRequestorID().set(44);
-    ricRequestId.ref_value().select_id_RICrequestID().ref_ricRequestSequenceNumber().set(55);
-    ies.push_back(ricRequestId);
-
-    RICsubscriptionRequest::protocolIEs_t::value_type ricSubId {};
-    ricSubId.ref_id().select_id_RICsubscription();
-    ricSubId.ref_criticality().select_id_RICsubscription();
-
-    //E2SM_gNB_X2_eventTriggerDefinition_t evt;
-    uint8_t v1[] = {0x02, 0xf8, 0x29, 0x88};
-
-    RICeventTriggerDefinition eventTriggerDef {};  // octet string in E2AP but struct in E2SM
-    eventTriggerDef.set(4, v1);
-
-//    eventTriggerDef.
-//
-//
-//    RICaction_Admitted_List::value_type actbl {};
-//    actbl.ref_id().select_id_RICaction_Admitted_Item();
-//    actbl.ref_criticality().select_id_RICaction_Admitted_Item();
-
-
-//    RICaction_ToBeSetup_Item actb1{};
-//
-//    actbl.ref_value().select_id_RICaction_Admitted_Item().ref_ricActionID().set(actb1);
-//    ricSubId.ref_value().select_id_RICsubscription().ref_ricAction_ToBeSetup_List().set(actbl);
-
-
-    ies.push_back(ricSubId);
-
-/*
-
-    ies.push_back(ranFuncId);
-
-    X2SetupRequest::protocolIEs_t::value_type sc {};
-    ies.push_back(sc);
-
-    sc.ref_id().select_id_ServedCells();
-    sc.ref_criticality().select_id_ServedCells();
-
-    ServedCells::value_type sce;
-    sc.ref_value().select_id_ServedCells().push_back(sce);
-
-    sce.ref_servedCellInfo().ref_pCI().set(0x1F7);
-    uint8_t v3[] = {0x1, 0x2};
-    sce.ref_servedCellInfo().ref_tAC().set(2,v3);
-    sce.ref_servedCellInfo().ref_cellId().ref_pLMN_Identity().set(3, v1);
-    uint8_t v4[] = {0x00, 0x07, 0xab, ((unsigned)0x50) >> (unsigned)4};
-    sce.ref_servedCellInfo().ref_cellId().ref_eUTRANcellIdentifier().set_buffer(28, v4);
-
-    BroadcastPLMNs_Item::value_type bpe;
-    sce.ref_servedCellInfo().ref_broadcastPLMNs().push_back(bpe);
-    bpe.set(3, v1);
-
-    sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_uL_EARFCN().set(0x1);
-    sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_dL_EARFCN().set(0x1);
-    sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_uL_Transmission_Bandwidth().set(Transmission_Bandwidth::bw50);
-    sce.ref_servedCellInfo().ref_eUTRA_Mode_Info().select_fDD().ref_dL_Transmission_Bandwidth().set(Transmission_Bandwidth::bw50);
-
-*/
-
-    unsigned char s_buffer[64 * 1024];
-    asn::per::EncoderCtx ctx{s_buffer, sizeof(s_buffer)};
-    std::cout << asn::get_printed(pdu) << std::endl;
-    if (!asn::per::pack(pdu, ctx)) {
-        std::cout << ctx.refErrorCtx().toString() << std::endl;
-        return -3;
-    }
-    size_t packed_buf_size;
-    packed_buf_size = static_cast<size_t>(ctx.refBuffer().getBytesUsed());
-
-    // build message
-    char data[4096] {};
-    //auto delimiter = (const char) '|';
-    sprintf(data, "%s/0", ctx.refBuffer().getBytes(packed_buf_size));
-
-    rmr_mbuf_t *msg = rmr_alloc_msg(rmrCtx, int(strlen(data)));
-    rmr_bytes2meid(msg, (unsigned char const*)ranName, strlen(ranName));
-    rmr_bytes2payload(msg, (unsigned char const*)data, strlen(data));
-    rmr_bytes2xact(msg, (unsigned char const*)ranName, strlen(ranName));
-    msg->mtype = RIC_SUB_REQ;
-    msg->state = 0;
-
-    msg = rmr_send_msg(rmrCtx, msg);
-    if (msg->state != 0) {
-        mdclog_write(MDCLOG_ERR, "Message state %d while sending RIC_X2_SETUP to %s", msg->state, ranName);
-        rmr_free_msg(msg);
-        rmr_close(rmrCtx);
-        return -4;
-    }
-    rmr_free_msg(msg);
-
-
-    unsigned char allocBuffer[64*1024] {0};
-    auto *events = (struct epoll_event *)calloc(MAXEVENTS, sizeof(event));
-
-    while (true) {
-
-        auto numOfEvents = epoll_wait(epoll_fd, events, MAXEVENTS, -1);
-        if (numOfEvents < 0) {
-            mdclog_write(MDCLOG_ERR, "Epoll wait failed, errno = %s", strerror(errno));
-            rmr_close(rmrCtx);
-            return -4;
-        }
-        for (auto i = 0; i < numOfEvents; i++) {
-            if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) {
-                mdclog_write(MDCLOG_ERR, "epoll error");
-            } else if (rmrListenFd == events[i].data.fd) {
-                msg = rmr_alloc_msg(rmrCtx, 4096);
-                if (msg == nullptr) {
-                    mdclog_write(MDCLOG_ERR, "RMR Allocation message, %s", strerror(errno));
-                    rmr_close(rmrCtx);
-                    return -5;
-                }
-
-                msg = rmr_rcv_msg(rmrCtx, msg);
-                if (msg == nullptr) {
-                    mdclog_write(MDCLOG_ERR, "RMR Receving message, %s", strerror(errno));
-                    rmr_close(rmrCtx);
-                    return -6;
-                }
-                memset(allocBuffer, 0, 64*1024);
-                switch (msg->mtype) {
-                    default: {
-                        mdclog_write(MDCLOG_INFO, "RMR receiveing message type %d", msg->mtype);
-                        asn::per::DecoderCtx dCtx{msg->payload, (size_t) msg->len, allocBuffer, sizeof(allocBuffer)};
-                        E2AP_PDU opdu;
-                        if (!asn::per::unpack(opdu, dCtx)) {
-                            mdclog_write(MDCLOG_ERR, "Failed to unpack ASN message, %s", dCtx.refErrorCtx().toString());
-                            rmr_close(rmrCtx);
-                            return -7;
-                        }
-
-                        switch (opdu.get_index()) {
-                            case 1: { //initiating message
-                                mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
-                                             opdu.get_initiatingMessage()->ref_procedureCode().ref_value().get());
-                                break;
-                            }
-                            case 2: { //successful message
-                                mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
-                                             opdu.get_successfulOutcome()->ref_procedureCode().ref_value().get());
-                                break;
-                            }
-                            case 3: { //unsuccessesful message
-                                mdclog_write(MDCLOG_INFO, "ASN initiating message type %ld",
-                                             opdu.get_unsuccessfulOutcome()->ref_procedureCode().ref_value().get());
-                                break;
-                            }
-
-                        }
-                        mdclog_write(MDCLOG_INFO, "RMR receiveing message from E2 terminator, %d",
-                                     msg->mtype);
-                        break;
-                    }
-                }
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/RIC-E2-TERMINATION/TEST/testAsn/setUpMessages/SetUpMessages.cpp b/RIC-E2-TERMINATION/TEST/testAsn/setUpMessages/SetUpMessages.cpp
index 1c5a129..36d5f02 100644
--- a/RIC-E2-TERMINATION/TEST/testAsn/setUpMessages/SetUpMessages.cpp
+++ b/RIC-E2-TERMINATION/TEST/testAsn/setUpMessages/SetUpMessages.cpp
@@ -135,31 +135,30 @@
                        "</E2AP-PDU>\n";
 
 
-
 std::string newXml =
         "<E2AP-PDU><successfulOutcome><procedureCode>1</procedureCode><criticality><reject/></criticality><value><E2setupResponse><protocolIEs><E2setupResponseIEs><id>4</id><criticality><reject/></criticality><value><GlobalRIC-ID><pLMN-Identity>13 10 14</pLMN-Identity><ric-ID>10101010110011001110</ric-ID></GlobalRIC-ID></value></E2setupResponseIEs><E2setupResponseIEs><id>9</id><criticality><reject/></criticality><value><RANfunctionsID-List><ProtocolIE-SingleContainer><id>6</id><criticality><ignore/></criticality><value><RANfunctionID-Item><ranFunctionID>1</ranFunctionID><ranFunctionRevision>1</ranFunctionRevision></RANfunctionID-Item></value></ProtocolIE-SingleContainer><ProtocolIE-SingleContainer><id>6</id><criticality><ignore/></criticality><value><RANfunctionID-Item><ranFunctionID>2</ranFunctionID><ranFunctionRevision>1</ranFunctionRevision></RANfunctionID-Item></value></ProtocolIE-SingleContainer><ProtocolIE-SingleContainer><id>6</id><criticality><ignore/></criticality><value><RANfunctionID-Item><ranFunctionID>3</ranFunctionID><ranFunctionRevision>1</ranFunctionRevision></RANfunctionID-Item></value></ProtocolIE-SingleContainer></RANfunctionsID-List></value></E2setupResponseIEs></protocolIEs></E2setupResponse></value></successfulOutcome></E2AP-PDU>";
 std::string setupFailure = "<E2AP-PDU>"
-                             "<unsuccessfulOutcome>"
-                               "<procedureCode>1</procedureCode>"
-                               "<criticality><reject/></criticality>"
-                               "<value>"
-                                 "<E2setupFailure>"
-                                   "<protocolIEs>"
-                                     "<E2setupFailureIEs>"
-                                       "<id>1</id>"
-                                       "<criticality><reject/></criticality>"
-                                       "<value>"
-                                         "<Cause>"
-                                           "<transport>"
-                                             "<transport-resource-unavailable/>"
-                                           "</transport>"
-                                         "</Cause>"
-                                       "</value>"
-                                     "</E2setupFailureIEs>"
-                                   "</protocolIEs>"
-                                 "</E2setupFailure>"
-                               "</value>"
-                             "</unsuccessfulOutcome>"
+                           "<unsuccessfulOutcome>"
+                           "<procedureCode>1</procedureCode>"
+                           "<criticality><reject/></criticality>"
+                           "<value>"
+                           "<E2setupFailure>"
+                           "<protocolIEs>"
+                           "<E2setupFailureIEs>"
+                           "<id>1</id>"
+                           "<criticality><reject/></criticality>"
+                           "<value>"
+                           "<Cause>"
+                           "<transport>"
+                           "<transport-resource-unavailable/>"
+                           "</transport>"
+                           "</Cause>"
+                           "</value>"
+                           "</E2setupFailureIEs>"
+                           "</protocolIEs>"
+                           "</E2setupFailure>"
+                           "</value>"
+                           "</unsuccessfulOutcome>"
                            "</E2AP-PDU>";
 
 
@@ -203,7 +202,19 @@
     cout << "Encoding E2AP PDU of size  " << size << endl << printBuffer << endl;
     fseek(stream,0,SEEK_SET);
 
-//    cout << "=========================" << endl << otherXml << endl << "========================" << endl;
+    cout << "=========================" << endl << endl << endl << "========================" << endl;
+    buildSubsReq(&pdu);
+    char errbuf[256];
+    int errlen = 256;
+    int ret = asn_check_constraints(&asn_DEF_E2AP_PDU, &pdu, errbuf, (size_t *)&errlen);
+    if (ret) {
+        cout << "Constraint validation failed: " << errbuf << endl;
+    }
+    asn_fprint(stream, &asn_DEF_E2AP_PDU, &pdu);
+    cout << "Encoding E2AP PDU of size  " << size << endl << printBuffer << endl;
+    //fseek(stream,0,SEEK_SET);
+    extractPdu(&pdu, buffer, buffer_size);
+    memset(buffer, 0, buffer_size);
 
     buildSetupRequest(&pdu, 311, 410);
     asn_fprint(stream, &asn_DEF_E2AP_PDU, &pdu);
@@ -261,4 +272,39 @@
     fseek(stream,0,SEEK_SET);
 
     extractPdu(&pdu, buffer, buffer_size);
+    memset(buffer, 0, buffer_size);
+
+    buildResetReq(&pdu);
+    asn_fprint(stream, &asn_DEF_E2AP_PDU, &pdu);
+    cout << "Encoding E2AP PDU (Reset Request) of size  " << size << endl << printBuffer << endl;
+    fseek(stream,0,SEEK_SET);
+
+    extractPdu(&pdu, buffer, buffer_size);
+    memset(buffer, 0, buffer_size);
+
+
+    buildServiceQuery(&pdu);
+    asn_fprint(stream, &asn_DEF_E2AP_PDU, &pdu);
+    cout << "Encoding E2AP PDU (service query) of size  " << size << endl << printBuffer << endl;
+    fseek(stream,0,SEEK_SET);
+
+    extractPdu(&pdu, buffer, buffer_size);
+    memset(buffer, 0, buffer_size);
+
+    buildServiceUpdateResponce(&pdu);
+    asn_fprint(stream, &asn_DEF_E2AP_PDU, &pdu);
+    cout << "Encoding E2AP PDU (service update ack) of size  " << size << endl << printBuffer << endl;
+    fseek(stream,0,SEEK_SET);
+
+    extractPdu(&pdu, buffer, buffer_size);
+    memset(buffer, 0, buffer_size);
+
+    buildResetResponse(&pdu);
+    asn_fprint(stream, &asn_DEF_E2AP_PDU, &pdu);
+    cout << "Encoding E2AP PDU (reset response example) of size  " << size << endl << printBuffer << endl;
+    fseek(stream,0,SEEK_SET);
+
+    extractPdu(&pdu, buffer, buffer_size);
+    memset(buffer, 0, buffer_size);
+
 }
diff --git a/RIC-E2-TERMINATION/config/config.conf b/RIC-E2-TERMINATION/config/config.conf
index 43a124a..d6f5008 100644
--- a/RIC-E2-TERMINATION/config/config.conf
+++ b/RIC-E2-TERMINATION/config/config.conf
@@ -4,6 +4,12 @@
 #the key name of the environment holds the local ip address
 #ip address of the E2T in the RMR
 local-ip=127.0.0.1
+#prometheus mode can be pull or push
+prometheusMode=pull
+#timeout can be from 5 seconds to 300 seconds default is 10
+prometheusPushTimeOut=10
+prometheusPushAddr=127.0.0.1:7676
+prometheusPort=8088
 #trace is start, stop
 trace=start
 external-fqdn=e2t.com
diff --git a/RIC-E2-TERMINATION/container-tag.yaml b/RIC-E2-TERMINATION/container-tag.yaml
index 8c395d4..6a6c6f6 100644
--- a/RIC-E2-TERMINATION/container-tag.yaml
+++ b/RIC-E2-TERMINATION/container-tag.yaml
@@ -1,3 +1,3 @@
 # The Jenkins job requires a tag to build the Docker image.
 # Global-JJB script assumes this file is in the repo root.
-tag: 4.0.10
+tag: 5.0.1
diff --git a/RIC-E2-TERMINATION/sctpThread.cpp b/RIC-E2-TERMINATION/sctpThread.cpp
index 7fa142e..94827f9 100644
--- a/RIC-E2-TERMINATION/sctpThread.cpp
+++ b/RIC-E2-TERMINATION/sctpThread.cpp
@@ -31,6 +31,8 @@
 using namespace std;
 //using namespace std::placeholders;
 using namespace boost::filesystem;
+using namespace prometheus;
+
 
 //#ifdef __cplusplus
 //extern "C"
@@ -237,6 +239,31 @@
     }
     jsonTrace = sctpParams.trace;
 
+    sctpParams.epollTimeOut = -1;
+    tmpStr = conf.getStringValue("prometheusMode");
+    transform(tmpStr.begin(), tmpStr.end(), tmpStr.begin(), ::tolower);
+    if (tmpStr.length() != 0) {
+        if (tmpStr.compare("push") == 0) {
+            sctpParams.prometheusPushAddress = tmpStr;
+            auto timeout = conf.getIntValue("prometheusPushTimeOut");
+            if (timeout >= 5 && timeout <= 300) {
+                sctpParams.epollTimeOut = timeout * 1000;
+            } else {
+                sctpParams.epollTimeOut = 10 * 1000;
+            }
+        }
+    }
+
+    tmpStr = conf.getStringValue("prometheusPushAddr");
+    if (tmpStr.length() != 0) {
+        sctpParams.prometheusMode = tmpStr;
+    }
+
+    tmpStr = conf.getStringValue("prometheusPort");
+    if (tmpStr.length() != 0) {
+        sctpParams.prometheusPort = tmpStr;
+    }
+
     sctpParams.ka_message_length = snprintf(sctpParams.ka_message, KA_MESSAGE_SIZE, "{\"address\": \"%s:%d\","
                                                                                     "\"fqdn\": \"%s\","
                                                                                     "\"pod_name\": \"%s\"}",
@@ -282,6 +309,15 @@
     return 0;
 }
 
+static std::string GetHostName() {
+    char hostname[1024];
+
+    if (::gethostname(hostname, sizeof(hostname))) {
+        return {};
+    }
+    return hostname;
+}
+
 
 
 int main(const int argc, char **argv) {
@@ -325,6 +361,18 @@
         exit(-1);
     }
 
+    //auto registry = std::make_shared<Registry>();
+    sctpParams.prometheusRegistry = std::make_shared<Registry>();
+
+    //sctpParams.promtheusFamily = new Family<Counter>("E2T", "E2T message counter", {{"E", sctpParams.podName}});
+
+    sctpParams.prometheusFamily = &BuildCounter()
+            .Name("E2T")
+            .Help("E2T message counter")
+            .Labels({{"E", sctpParams.podName}})
+            .Register(*sctpParams.prometheusRegistry);
+
+
     // start epoll
     sctpParams.epoll_fd = epoll_create1(0);
     if (sctpParams.epoll_fd == -1) {
@@ -357,6 +405,27 @@
     std::vector<std::thread> threads(num_cpus);
 //    std::vector<std::thread> threads;
 
+    if (sctpParams.prometheusMode.compare("pull") == 0) {
+        sctpParams.prometheusExposer = new Exposer(sctpParams.myIP + ":" + sctpParams.prometheusPort, 1);
+        sctpParams.prometheusExposer->RegisterCollectable(sctpParams.prometheusRegistry);
+    } else if (sctpParams.prometheusMode.compare("push") == 0) {
+        const auto labels = Gateway::GetInstanceLabel(GetHostName());
+        string address {};
+        string port {};
+        char ch = ':';
+        auto found = sctpParams.prometheusPushAddress.find_last_of(ch);
+        // If string doesn't have
+        // character ch present in it
+        if (found != string::npos) {
+            address = sctpParams.prometheusPushAddress.substr(0,found);
+            port = sctpParams.prometheusPushAddress.substr(found + 1);
+            sctpParams.prometheusGateway = new Gateway(address, port, "E2T", labels);
+            sctpParams.prometheusGateway->RegisterCollectable(sctpParams.prometheusRegistry);
+        } else {
+            mdclog_write(MDCLOG_ERR, "failed to build Prometheus gateway no stats will be sent");
+        }
+    }
+
     num_cpus = 1;
     for (unsigned int i = 0; i < num_cpus; i++) {
         threads[i] = std::thread(listener, &sctpParams);
@@ -370,8 +439,6 @@
         }
     }
 
-    auto statFlag = false;
-    auto statThread = std::thread(statColectorThread, (void *)&statFlag);
 
     //loop over term_init until first message from xApp
     handleTermInit(sctpParams);
@@ -380,9 +447,6 @@
         t.join();
     }
 
-    statFlag = true;
-    statThread.join();
-
     return 0;
 }
 
@@ -530,7 +594,6 @@
         mdclog_write(MDCLOG_DEBUG, "started thread number %s", tid);
     }
 
-
     RmrMessagesBuffer_t rmrMessageBuffer{};
     //create and init RMR
     rmrMessageBuffer.rmrCtx = params->rmrCtx;
@@ -557,23 +620,39 @@
 //        rmrMessageBuffer.sendBufferedMessages[i] = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, RECEIVE_XAPP_BUFFER_SIZE);
 //    }
 
-    message.statCollector = StatCollector::GetInstance();
-
+    bool gatewayflag = false;
     while (true) {
+        future<int> gateWay;
+
         if (mdclog_level_get() >= MDCLOG_DEBUG) {
-            mdclog_write(MDCLOG_DEBUG, "Start EPOLL Wait");
+            mdclog_write(MDCLOG_DEBUG, "Start EPOLL Wait. Timeout = %d", params->epollTimeOut);
         }
-        auto numOfEvents = epoll_wait(params->epoll_fd, events, MAXEVENTS, -1);
-        if (numOfEvents < 0 && errno == EINTR) {
-            if (mdclog_level_get() >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "got EINTR : %s", strerror(errno));
+        auto numOfEvents = epoll_wait(params->epoll_fd, events, MAXEVENTS, params->epollTimeOut);
+        if (numOfEvents == 0) {
+            if (params->prometheusGateway != nullptr) {
+                gateWay = params->prometheusGateway->AsyncPush();
+                gatewayflag = true;
             }
             continue;
-        }
-        if (numOfEvents < 0) {
+        } else if (numOfEvents < 0) {
+            if (errno == EINTR) {
+                if (mdclog_level_get() >= MDCLOG_DEBUG) {
+                    mdclog_write(MDCLOG_DEBUG, "got EINTR : %s", strerror(errno));
+                }
+                continue;
+            }
             mdclog_write(MDCLOG_ERR, "Epoll wait failed, errno = %s", strerror(errno));
             return;
         }
+        if (gatewayflag) {
+            gatewayflag = false;
+            auto rc = gateWay.get();
+            if (rc != 200) {
+                mdclog_write(MDCLOG_ERR, "Async Send to Promethues faild with Return Code %d", rc);
+            } else if (mdclog_level_get() >= MDCLOG_DEBUG) {
+                mdclog_write(MDCLOG_DEBUG, "Stats sent to Prometheus");
+            }
+        }
         for (auto i = 0; i < numOfEvents; i++) {
             if (mdclog_level_get() >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "handling epoll event %d out of %d", i + 1, numOfEvents);
@@ -791,6 +870,17 @@
                     sctpParams->trace = false;
                 }
                 jsonTrace = sctpParams->trace;
+
+                if (sctpParams->prometheusMode.compare("push") == 0) {
+                    auto timeout = conf.getIntValue("prometheusPushTimeOut");
+                    if (timeout >= 5 && timeout <= 300) {
+                        sctpParams->epollTimeOut = timeout * 1000;
+                    } else {
+                        mdclog_write(MDCLOG_ERR, "prometheusPushTimeOut set wrong value %d, values are [5..300]",
+                                     timeout);
+                    }
+                }
+
                 endlessLoop = false;
             }
         }
@@ -983,8 +1073,6 @@
             m->erase(key);
             return -1;
         }
-        // TODO remove stat update
-        //message.statCollector->incSentMessage(string(message.message.enodbName));
         message.message.direction = 'D';
         // send report.buffer of size
         buildJsonMessage(message);
@@ -1005,8 +1093,6 @@
  * @param rmrMessageBuffer
  */
 void getRequestMetaData(ReportingMessages_t &message, RmrMessagesBuffer_t &rmrMessageBuffer) {
-    rmr_get_meid(rmrMessageBuffer.rcvMessage, (unsigned char *) (message.message.enodbName));
-
     message.message.asndata = rmrMessageBuffer.rcvMessage->payload;
     message.message.asnLength = rmrMessageBuffer.rcvMessage->len;
 
@@ -1042,14 +1128,12 @@
     // get the identity of the interface
     message.peerInfo = (ConnectedCU_t *)events->data.ptr;
 
-    message.statCollector = StatCollector::GetInstance();
     struct timespec start{0, 0};
     struct timespec decodestart{0, 0};
     struct timespec end{0, 0};
 
     E2AP_PDU_t *pdu = nullptr;
 
-
     while (true) {
         if (loglevel >= MDCLOG_DEBUG) {
             mdclog_write(MDCLOG_DEBUG, "Start Read from SCTP %d fd", message.peerInfo->fileDescriptor);
@@ -1066,7 +1150,6 @@
         }
 
         memcpy(message.message.enodbName, message.peerInfo->enodbName, sizeof(message.peerInfo->enodbName));
-        message.statCollector->incRecvMessage(string(message.message.enodbName));
         message.message.direction = 'U';
         message.message.time.tv_nsec = ts.tv_nsec;
         message.message.time.tv_sec = ts.tv_sec;
@@ -1115,7 +1198,6 @@
         if (rval.code != RC_OK) {
             mdclog_write(MDCLOG_ERR, "Error %d Decoding (unpack) E2AP PDU from RAN : %s", rval.code,
                          message.peerInfo->enodbName);
-            //todo may need reset to pdu
             break;
         }
 
@@ -1195,89 +1277,100 @@
 static void buildAndsendSetupRequest(ReportingMessages_t &message,
                                      RmrMessagesBuffer_t &rmrMessageBuffer,
                                      E2AP_PDU_t *pdu,
-                                     vector<string> &repValues) {
+                                     string const &messageName,
+                                     string const &ieName,
+                                     vector<string> &functionsToAdd_v,
+                                     vector<string> &functionsToModified_v) {
     auto logLevel = mdclog_level_get();
     // now we can send the data to e2Mgr
-    auto buffer_size = RECEIVE_SCTP_BUFFER_SIZE * 2;
-    unsigned char buffer[RECEIVE_SCTP_BUFFER_SIZE * 2];
-    auto *rmrMsg = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, buffer_size);
-    // encode to xml
-    auto er = asn_encode_to_buffer(nullptr, ATS_BASIC_XER, &asn_DEF_E2AP_PDU, pdu, buffer, buffer_size);
-    if (er.encoded == -1) {
-        mdclog_write(MDCLOG_ERR, "encoding of %s failed, %s", asn_DEF_E2AP_PDU.name, strerror(errno));
-    } else if (er.encoded > (ssize_t) buffer_size) {
-        mdclog_write(MDCLOG_ERR, "Buffer of size %d is to small for %s, at %s line %d",
-                     (int) buffer_size,
-                     asn_DEF_E2AP_PDU.name, __func__, __LINE__);
-    } else {
-        string messageType("E2setupRequest");
-        string ieName("E2setupRequestIEs");
-        buffer[er.encoded] = '\0';
-        buildXmlData(messageType, ieName, repValues, buffer, (size_t)er.encoded);
 
-//        string xmlStr = (char *)buffer;
-//        auto removeSpaces = [] (string str) -> string {
-//            str.erase(remove(str.begin(), str.end(), ' '), str.end());
-//            str.erase(remove(str.begin(), str.end(), '\t'), str.end());
-//            return str;
-//        };
-//
-//        xmlStr = removeSpaces(xmlStr);
-//        // we have the XML
-//        rmrMsg->len = snprintf((char *)rmrMsg->payload, RECEIVE_SCTP_BUFFER_SIZE * 2, "%s:%d|%s",
-//                               message.peerInfo->sctpParams->myIP.c_str(),
-//                               message.peerInfo->sctpParams->rmrPort,
-//                               xmlStr.c_str());
-        rmrMsg->len = snprintf((char *)rmrMsg->payload, RECEIVE_SCTP_BUFFER_SIZE * 2, "%s:%d|%s",
+    asn_enc_rval_t er;
+    auto buffer_size = RECEIVE_SCTP_BUFFER_SIZE * 2;
+    unsigned char *buffer;
+    while (true) {
+        buffer = (unsigned char *)malloc(buffer_size);
+        er = asn_encode_to_buffer(nullptr, ATS_BASIC_XER, &asn_DEF_E2AP_PDU, pdu, buffer, buffer_size);
+        if (er.encoded == -1) {
+            mdclog_write(MDCLOG_ERR, "encoding of %s failed, %s", asn_DEF_E2AP_PDU.name, strerror(errno));
+            return;
+        } else if (er.encoded > (ssize_t) buffer_size) {
+            buffer_size = er.encoded + 128;
+            mdclog_write(MDCLOG_WARN, "Buffer of size %d is to small for %s. Reallocate buffer of size %d",
+                         (int) buffer_size,
+                         asn_DEF_E2AP_PDU.name, buffer_size);
+            buffer_size = er.encoded + 128;
+            free(buffer);
+            continue;
+        }
+        buffer[er.encoded] = '\0';
+        break;
+    }
+    // encode to xml
+
+    string res {};
+    if (!functionsToAdd_v.empty() || !functionsToModified_v.empty()) {
+        res = buildXmlData(messageName, ieName, functionsToAdd_v, functionsToModified_v, buffer, (size_t) er.encoded);
+    }
+    rmr_mbuf_t *rmrMsg;
+    if (res.length() == 0) {
+        rmrMsg = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, buffer_size + 256);
+        rmrMsg->len = snprintf((char *) rmrMsg->payload, RECEIVE_SCTP_BUFFER_SIZE * 2, "%s:%d|%s",
                                message.peerInfo->sctpParams->myIP.c_str(),
                                message.peerInfo->sctpParams->rmrPort,
                                buffer);
-        if (logLevel >= MDCLOG_DEBUG) {
-            mdclog_write(MDCLOG_DEBUG, "Setup request of size %d :\n %s\n", rmrMsg->len, rmrMsg->payload);
-        }
-        // send to RMR
-        message.message.messageType = rmrMsg->mtype = RIC_E2_SETUP_REQ;
-        rmrMsg->state = 0;
-        rmr_bytes2meid(rmrMsg, (unsigned char *) message.message.enodbName, strlen(message.message.enodbName));
+    } else {
+        rmrMsg = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, (int)res.length() + 256);
+        rmrMsg->len = snprintf((char *) rmrMsg->payload, res.length() + 256, "%s:%d|%s",
+                               message.peerInfo->sctpParams->myIP.c_str(),
+                               message.peerInfo->sctpParams->rmrPort,
+                               res.c_str());
+    }
 
-        static unsigned char tx[32];
-        snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
-        rmr_bytes2xact(rmrMsg, tx, strlen((const char *) tx));
+    if (logLevel >= MDCLOG_DEBUG) {
+        mdclog_write(MDCLOG_DEBUG, "Setup request of size %d :\n %s\n", rmrMsg->len, rmrMsg->payload);
+    }
+    // send to RMR
+    rmrMsg->mtype = message.message.messageType;
+    rmrMsg->state = 0;
+    rmr_bytes2meid(rmrMsg, (unsigned char *) message.message.enodbName, strlen(message.message.enodbName));
 
-        rmrMsg = rmr_send_msg(rmrMessageBuffer.rmrCtx, rmrMsg);
-        if (rmrMsg == nullptr) {
-            mdclog_write(MDCLOG_ERR, "RMR failed to send returned nullptr");
-        } else if (rmrMsg->state != 0) {
-            char meid[RMR_MAX_MEID]{};
-            if (rmrMsg->state == RMR_ERR_RETRY) {
-                usleep(5);
-                rmrMsg->state = 0;
-                mdclog_write(MDCLOG_INFO, "RETRY sending Message %d to Xapp from %s",
-                             rmrMsg->mtype, rmr_get_meid(rmrMsg, (unsigned char *) meid));
-                rmrMsg = rmr_send_msg(rmrMessageBuffer.rmrCtx, rmrMsg);
-                if (rmrMsg == nullptr) {
-                    mdclog_write(MDCLOG_ERR, "RMR failed send returned nullptr");
-                } else if (rmrMsg->state != 0) {
-                    mdclog_write(MDCLOG_ERR,
-                                 "RMR Retry failed %s sending request %d to Xapp from %s",
-                                 translateRmrErrorMessages(rmrMsg->state).c_str(),
-                                 rmrMsg->mtype,
-                                 rmr_get_meid(rmrMsg, (unsigned char *) meid));
-                }
-            } else {
-                mdclog_write(MDCLOG_ERR, "RMR failed: %s. sending request %d to Xapp from %s",
+    static unsigned char tx[32];
+    snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
+    rmr_bytes2xact(rmrMsg, tx, strlen((const char *) tx));
+
+    rmrMsg = rmr_send_msg(rmrMessageBuffer.rmrCtx, rmrMsg);
+    if (rmrMsg == nullptr) {
+        mdclog_write(MDCLOG_ERR, "RMR failed to send returned nullptr");
+    } else if (rmrMsg->state != 0) {
+        char meid[RMR_MAX_MEID]{};
+        if (rmrMsg->state == RMR_ERR_RETRY) {
+            usleep(5);
+            rmrMsg->state = 0;
+            mdclog_write(MDCLOG_INFO, "RETRY sending Message %d to Xapp from %s",
+                         rmrMsg->mtype, rmr_get_meid(rmrMsg, (unsigned char *) meid));
+            rmrMsg = rmr_send_msg(rmrMessageBuffer.rmrCtx, rmrMsg);
+            if (rmrMsg == nullptr) {
+                mdclog_write(MDCLOG_ERR, "RMR failed send returned nullptr");
+            } else if (rmrMsg->state != 0) {
+                mdclog_write(MDCLOG_ERR,
+                             "RMR Retry failed %s sending request %d to Xapp from %s",
                              translateRmrErrorMessages(rmrMsg->state).c_str(),
                              rmrMsg->mtype,
                              rmr_get_meid(rmrMsg, (unsigned char *) meid));
             }
-        }
-        message.peerInfo->gotSetup = true;
-        buildJsonMessage(message);
-        if (rmrMsg != nullptr) {
-            rmr_free_msg(rmrMsg);
+        } else {
+            mdclog_write(MDCLOG_ERR, "RMR failed: %s. sending request %d to Xapp from %s",
+                         translateRmrErrorMessages(rmrMsg->state).c_str(),
+                         rmrMsg->mtype,
+                         rmr_get_meid(rmrMsg, (unsigned char *) meid));
         }
     }
-
+    message.peerInfo->gotSetup = true;
+    buildJsonMessage(message);
+    if (rmrMsg != nullptr) {
+        rmr_free_msg(rmrMsg);
+    }
+    free(buffer);
 }
 
 int RAN_Function_list_To_Vector(RANfunctions_List_t& list, vector <string> &runFunXML_v) {
@@ -1301,17 +1394,9 @@
                 return -1;
             }
 
-//                        if (mdclog_level_get() >= MDCLOG_DEBUG) {
-//                            char *printBuffer;
-//                            size_t size;
-//                            FILE *stream = open_memstream(&printBuffer, &size);
-//                            asn_fprint(stream, &asn_DEF_E2SM_gNB_NRT_RANfunction_Definition, ranFunDef);
-//                            mdclog_write(MDCLOG_DEBUG, "Encoding E2SM %s PDU past : %s",
-//                                         asn_DEF_E2SM_gNB_NRT_RANfunction_Definition.name,
-//                                         printBuffer);
-//                        }
             auto xml_buffer_size = RECEIVE_SCTP_BUFFER_SIZE * 2;
             unsigned char xml_buffer[RECEIVE_SCTP_BUFFER_SIZE * 2];
+            memset(xml_buffer, 0, RECEIVE_SCTP_BUFFER_SIZE * 2);
             // encode to xml
             auto er = asn_encode_to_buffer(nullptr,
                                            ATS_BASIC_XER,
@@ -1334,6 +1419,7 @@
                                  index++,
                                  xml_buffer);
                 }
+
                 string runFuncs = (char *)(xml_buffer);
                 runFunXML_v.emplace_back(runFuncs);
             }
@@ -1342,29 +1428,16 @@
     return 0;
 }
 
-
-
-int collectSetupAndServiceUpdate_RequestData(E2AP_PDU_t *pdu,
-                                             Sctp_Map_t *sctpMap,
-                                             ReportingMessages_t &message,
-                                             vector <string> &RANfunctionsAdded_v,
-                                             vector <string> &RANfunctionsModified_v) {
+int collectServiceUpdate_RequestData(E2AP_PDU_t *pdu,
+                                     Sctp_Map_t *sctpMap,
+                                     ReportingMessages_t &message,
+                                     vector <string> &RANfunctionsAdded_v,
+                                     vector <string> &RANfunctionsModified_v) {
     memset(message.peerInfo->enodbName, 0 , MAX_ENODB_NAME_SIZE);
-    for (auto i = 0; i < pdu->choice.initiatingMessage->value.choice.E2setupRequest.protocolIEs.list.count; i++) {
-        auto *ie = pdu->choice.initiatingMessage->value.choice.E2setupRequest.protocolIEs.list.array[i];
-        if (ie->id == ProtocolIE_ID_id_GlobalE2node_ID) {
-            // get the ran name for meid
-            if (ie->value.present == E2setupRequestIEs__value_PR_GlobalE2node_ID) {
-                if (buildRanName(message.peerInfo->enodbName, ie) < 0) {
-                    mdclog_write(MDCLOG_ERR, "Bad param in E2setupRequestIEs GlobalE2node_ID.\n");
-                    // no mesage will be sent
-                    return -1;
-                }
-                memcpy(message.message.enodbName, message.peerInfo->enodbName, strlen(message.peerInfo->enodbName));
-                sctpMap->setkey(message.message.enodbName, message.peerInfo);
-            }
-        } else if (ie->id == ProtocolIE_ID_id_RANfunctionsAdded) {
-            if (ie->value.present == E2setupRequestIEs__value_PR_RANfunctions_List) {
+    for (auto i = 0; i < pdu->choice.initiatingMessage->value.choice.RICserviceUpdate.protocolIEs.list.count; i++) {
+        auto *ie = pdu->choice.initiatingMessage->value.choice.RICserviceUpdate.protocolIEs.list.array[i];
+        if (ie->id == ProtocolIE_ID_id_RANfunctionsAdded) {
+            if (ie->value.present == RICserviceUpdate_IEs__value_PR_RANfunctionsID_List) {
                 if (mdclog_level_get() >= MDCLOG_DEBUG) {
                     mdclog_write(MDCLOG_DEBUG, "Run function list have %d entries",
                                  ie->value.choice.RANfunctions_List.list.count);
@@ -1374,7 +1447,7 @@
                 }
             }
         } else if (ie->id == ProtocolIE_ID_id_RANfunctionsModified) {
-            if (ie->value.present == E2setupRequestIEs__value_PR_RANfunctions_List) {
+            if (ie->value.present == RICserviceUpdate_IEs__value_PR_RANfunctions_List) {
                 if (mdclog_level_get() >= MDCLOG_DEBUG) {
                     mdclog_write(MDCLOG_DEBUG, "Run function list have %d entries",
                                  ie->value.choice.RANfunctions_List.list.count);
@@ -1391,6 +1464,162 @@
     }
     return 0;
 }
+
+
+
+void buildPrometheuslist(ConnectedCU_t *peerInfo, Family<Counter> *prometheusFamily) {
+    peerInfo->counters[IN_INITI][MSG_COUNTER][(ProcedureCode_id_E2setup - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"SetupRequest", "Messages"}});
+    peerInfo->counters[IN_INITI][BYTES_COUNTER][(ProcedureCode_id_E2setup - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"SetupRequest", "Bytes"}});
+
+    peerInfo->counters[IN_INITI][MSG_COUNTER][(ProcedureCode_id_ErrorIndication - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"ErrorIndication", "Messages"}});
+    peerInfo->counters[IN_INITI][BYTES_COUNTER][(ProcedureCode_id_ErrorIndication - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"ErrorIndication", "Bytes"}});
+
+    peerInfo->counters[IN_INITI][MSG_COUNTER][(ProcedureCode_id_RICindication - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICindication", "Messages"}});
+    peerInfo->counters[IN_INITI][BYTES_COUNTER][(ProcedureCode_id_RICindication - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICindication", "Bytes"}});
+
+    peerInfo->counters[IN_INITI][MSG_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"ResetRequest", "Messages"}});
+    peerInfo->counters[IN_INITI][BYTES_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"ResetRequest", "Bytes"}});
+
+    peerInfo->counters[IN_INITI][MSG_COUNTER][(ProcedureCode_id_RICserviceUpdate - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICserviceUpdate", "Messages"}});
+    peerInfo->counters[IN_INITI][BYTES_COUNTER][(ProcedureCode_id_RICserviceUpdate - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICserviceUpdate", "Bytes"}});
+    // ---------------------------------------------
+    peerInfo->counters[IN_SUCC][MSG_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"ResetACK", "Messages"}});
+    peerInfo->counters[IN_SUCC][BYTES_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"ResetACK", "Bytes"}});
+
+    peerInfo->counters[IN_SUCC][MSG_COUNTER][(ProcedureCode_id_RICcontrol - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICcontrolACK", "Messages"}});
+    peerInfo->counters[IN_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICcontrol - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICcontrolACK", "Bytes"}});
+
+    peerInfo->counters[IN_SUCC][MSG_COUNTER][(ProcedureCode_id_RICsubscription - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionACK", "Messages"}});
+    peerInfo->counters[IN_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICsubscription - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionACK", "Bytes"}});
+
+    peerInfo->counters[IN_SUCC][MSG_COUNTER][(ProcedureCode_id_RICsubscriptionDelete - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionDeleteACK", "Messages"}});
+    peerInfo->counters[IN_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICsubscriptionDelete - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionDeleteACK", "Bytes"}});
+    //-------------------------------------------------------------
+
+    peerInfo->counters[IN_UN_SUCC][MSG_COUNTER][(ProcedureCode_id_RICcontrol - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICcontrolFailure", "Messages"}});
+    peerInfo->counters[IN_UN_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICcontrol - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICcontrolFailure", "Bytes"}});
+
+    peerInfo->counters[IN_UN_SUCC][MSG_COUNTER][(ProcedureCode_id_RICsubscription - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionFailure", "Messages"}});
+    peerInfo->counters[IN_UN_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICsubscription - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionFailure", "Bytes"}});
+
+    peerInfo->counters[IN_UN_SUCC][MSG_COUNTER][(ProcedureCode_id_RICsubscriptionDelete - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionDeleteFailure", "Messages"}});
+    peerInfo->counters[IN_UN_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICsubscriptionDelete - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "IN"}, {"RICsubscriptionDeleteFailure", "Bytes"}});
+
+    //====================================================================================
+    peerInfo->counters[OUT_INITI][MSG_COUNTER][(ProcedureCode_id_ErrorIndication - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"ErrorIndication", "Messages"}});
+    peerInfo->counters[OUT_INITI][BYTES_COUNTER][(ProcedureCode_id_ErrorIndication - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"ErrorIndication", "Bytes"}});
+
+    peerInfo->counters[OUT_INITI][MSG_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"ResetRequest", "Messages"}});
+    peerInfo->counters[OUT_INITI][BYTES_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"ResetRequest", "Bytes"}});
+
+    peerInfo->counters[OUT_INITI][MSG_COUNTER][(ProcedureCode_id_RICcontrol - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICcontrol", "Messages"}});
+    peerInfo->counters[OUT_INITI][BYTES_COUNTER][(ProcedureCode_id_RICcontrol - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICcontrol", "Bytes"}});
+
+    peerInfo->counters[OUT_INITI][MSG_COUNTER][(ProcedureCode_id_RICserviceQuery - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICserviceQuery", "Messages"}});
+    peerInfo->counters[OUT_INITI][BYTES_COUNTER][(ProcedureCode_id_RICserviceQuery - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICserviceQuery", "Bytes"}});
+
+    peerInfo->counters[OUT_INITI][MSG_COUNTER][(ProcedureCode_id_RICsubscription - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICsubscription", "Messages"}});
+    peerInfo->counters[OUT_INITI][BYTES_COUNTER][(ProcedureCode_id_RICsubscription - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICsubscription", "Bytes"}});
+
+    peerInfo->counters[OUT_INITI][MSG_COUNTER][(ProcedureCode_id_RICsubscriptionDelete - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICsubscriptionDelete", "Messages"}});
+    peerInfo->counters[OUT_INITI][BYTES_COUNTER][(ProcedureCode_id_RICsubscriptionDelete - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICsubscriptionDelete", "Bytes"}});
+    //---------------------------------------------------------------------------------------------------------
+    peerInfo->counters[OUT_SUCC][MSG_COUNTER][(ProcedureCode_id_E2setup - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"SetupResponse", "Messages"}});
+    peerInfo->counters[OUT_SUCC][BYTES_COUNTER][(ProcedureCode_id_E2setup - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"SetupResponse", "Bytes"}});
+
+    peerInfo->counters[OUT_SUCC][MSG_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"ResetACK", "Messages"}});
+    peerInfo->counters[OUT_SUCC][BYTES_COUNTER][(ProcedureCode_id_Reset - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"ResetACK", "Bytes"}});
+
+    peerInfo->counters[OUT_SUCC][MSG_COUNTER][(ProcedureCode_id_RICserviceUpdate - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICserviceUpdateResponse", "Messages"}});
+    peerInfo->counters[OUT_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICserviceUpdate - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICserviceUpdateResponse", "Bytes"}});
+    //----------------------------------------------------------------------------------------------------------------
+    peerInfo->counters[OUT_UN_SUCC][MSG_COUNTER][(ProcedureCode_id_E2setup - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"SetupRequestFailure", "Messages"}});
+    peerInfo->counters[OUT_UN_SUCC][BYTES_COUNTER][(ProcedureCode_id_E2setup - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"SetupRequestFailure", "Bytes"}});
+
+    peerInfo->counters[OUT_UN_SUCC][MSG_COUNTER][(ProcedureCode_id_RICserviceUpdate - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICserviceUpdateFailure", "Messages"}});
+    peerInfo->counters[OUT_UN_SUCC][BYTES_COUNTER][(ProcedureCode_id_RICserviceUpdate - 1)] = &prometheusFamily->Add({{peerInfo->enodbName, "OUT"}, {"RICserviceUpdateFailure", "Bytes"}});
+}
+/**
+ *
+ * @param pdu
+ * @param sctpMap
+ * @param message
+ * @param RANfunctionsAdded_v
+ * @return
+ */
+int collectSetupRequestData(E2AP_PDU_t *pdu,
+                                     Sctp_Map_t *sctpMap,
+                                     ReportingMessages_t &message,
+                                     vector <string> &RANfunctionsAdded_v) {
+    memset(message.peerInfo->enodbName, 0 , MAX_ENODB_NAME_SIZE);
+    for (auto i = 0; i < pdu->choice.initiatingMessage->value.choice.E2setupRequest.protocolIEs.list.count; i++) {
+        auto *ie = pdu->choice.initiatingMessage->value.choice.E2setupRequest.protocolIEs.list.array[i];
+        if (ie->id == ProtocolIE_ID_id_GlobalE2node_ID) {
+            // get the ran name for meid
+            if (ie->value.present == E2setupRequestIEs__value_PR_GlobalE2node_ID) {
+                if (buildRanName(message.peerInfo->enodbName, ie) < 0) {
+                    mdclog_write(MDCLOG_ERR, "Bad param in E2setupRequestIEs GlobalE2node_ID.\n");
+                    // no mesage will be sent
+                    return -1;
+                }
+
+                memcpy(message.message.enodbName, message.peerInfo->enodbName, strlen(message.peerInfo->enodbName));
+                sctpMap->setkey(message.message.enodbName, message.peerInfo);
+            }
+        } else if (ie->id == ProtocolIE_ID_id_RANfunctionsAdded) {
+            if (ie->value.present == E2setupRequestIEs__value_PR_RANfunctions_List) {
+                if (mdclog_level_get() >= MDCLOG_DEBUG) {
+                    mdclog_write(MDCLOG_DEBUG, "Run function list have %d entries",
+                                 ie->value.choice.RANfunctions_List.list.count);
+                }
+                if (RAN_Function_list_To_Vector(ie->value.choice.RANfunctions_List, RANfunctionsAdded_v) != 0 ) {
+                    return -1;
+                }
+            }
+        }
+    }
+    if (mdclog_level_get() >= MDCLOG_DEBUG) {
+        mdclog_write(MDCLOG_DEBUG, "Run function vector have %ld entries",
+                     RANfunctionsAdded_v.size());
+    }
+    return 0;
+}
+
+int XML_From_PER(ReportingMessages_t &message, RmrMessagesBuffer_t &rmrMessageBuffer) {
+    E2AP_PDU_t *pdu = nullptr;
+
+    if (mdclog_level_get() >= MDCLOG_DEBUG) {
+        mdclog_write(MDCLOG_DEBUG, "got PER message of size %d is:%s",
+                     rmrMessageBuffer.sendMessage->len, rmrMessageBuffer.sendMessage->payload);
+    }
+    auto rval = asn_decode(nullptr, ATS_ALIGNED_BASIC_PER, &asn_DEF_E2AP_PDU, (void **) &pdu,
+                           rmrMessageBuffer.sendMessage->payload, rmrMessageBuffer.sendMessage->len);
+    if (rval.code != RC_OK) {
+        mdclog_write(MDCLOG_ERR, "Error %d Decoding (unpack) setup response  from E2MGR : %s",
+                     rval.code,
+                     message.message.enodbName);
+        return -1;
+    }
+
+    int buff_size = RECEIVE_XAPP_BUFFER_SIZE;
+    auto er = asn_encode_to_buffer(nullptr, ATS_BASIC_XER, &asn_DEF_E2AP_PDU, pdu,
+                                   rmrMessageBuffer.sendMessage->payload, buff_size);
+    if (er.encoded == -1) {
+        mdclog_write(MDCLOG_ERR, "encoding of %s failed, %s", asn_DEF_E2AP_PDU.name, strerror(errno));
+        return -1;
+    } else if (er.encoded > (ssize_t)buff_size) {
+        mdclog_write(MDCLOG_ERR, "Buffer of size %d is to small for %s, at %s line %d",
+                     (int)rmrMessageBuffer.sendMessage->len,
+                     asn_DEF_E2AP_PDU.name,
+                     __func__,
+                     __LINE__);
+        return -1;
+    }
+    rmrMessageBuffer.sendMessage->len = er.encoded;
+    return 0;
+
+}
+
 /**
  *
  * @param pdu
@@ -1412,47 +1641,52 @@
                 mdclog_write(MDCLOG_DEBUG, "Got E2setup");
             }
 
-            // first get the message as XML buffer
-            auto setup_xml_buffer_size = RECEIVE_SCTP_BUFFER_SIZE * 2;
-            unsigned char setup_xml_buffer[RECEIVE_SCTP_BUFFER_SIZE * 2];
-
-            auto er = asn_encode_to_buffer(nullptr, ATS_BASIC_XER, &asn_DEF_E2AP_PDU, pdu, setup_xml_buffer, setup_xml_buffer_size);
-            if (er.encoded == -1) {
-                mdclog_write(MDCLOG_ERR, "encoding of %s failed, %s", asn_DEF_E2AP_PDU.name, strerror(errno));
-                break;
-            } else if (er.encoded > (ssize_t) setup_xml_buffer_size) {
-                mdclog_write(MDCLOG_ERR, "Buffer of size %d is to small for %s, at %s line %d",
-                             (int)setup_xml_buffer_size,
-                             asn_DEF_E2AP_PDU.name, __func__, __LINE__);
-                break;
-            }
-            std::string xmlString(setup_xml_buffer_size,  setup_xml_buffer_size + er.encoded);
-
             vector <string> RANfunctionsAdded_v;
             vector <string> RANfunctionsModified_v;
             RANfunctionsAdded_v.clear();
             RANfunctionsModified_v.clear();
-            if (collectSetupAndServiceUpdate_RequestData(pdu, sctpMap, message,
-                    RANfunctionsAdded_v, RANfunctionsModified_v) != 0) {
+            if (collectSetupRequestData(pdu, sctpMap, message, RANfunctionsAdded_v) != 0) {
                 break;
             }
 
-            buildAndsendSetupRequest(message, rmrMessageBuffer, pdu, RANfunctionsAdded_v);
+            buildPrometheuslist(message.peerInfo, message.peerInfo->sctpParams->prometheusFamily);
+
+            string messageName("E2setupRequest");
+            string ieName("E2setupRequestIEs");
+            message.message.messageType = RIC_E2_SETUP_REQ;
+            message.peerInfo->counters[IN_INITI][MSG_COUNTER][ProcedureCode_id_E2setup - 1]->Increment();
+            message.peerInfo->counters[IN_INITI][BYTES_COUNTER][ProcedureCode_id_E2setup - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
+            buildAndsendSetupRequest(message, rmrMessageBuffer, pdu, messageName, ieName, RANfunctionsAdded_v, RANfunctionsModified_v);
             break;
         }
         case ProcedureCode_id_RICserviceUpdate: {
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got RICserviceUpdate %s", message.message.enodbName);
             }
-            if (sendRequestToXapp(message, RIC_SERVICE_UPDATE, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_SERVICE_UPDATE message failed to send to xAPP");
+            vector <string> RANfunctionsAdded_v;
+            vector <string> RANfunctionsModified_v;
+            RANfunctionsAdded_v.clear();
+            RANfunctionsModified_v.clear();
+            if (collectServiceUpdate_RequestData(pdu, sctpMap, message,
+                                                 RANfunctionsAdded_v, RANfunctionsModified_v) != 0) {
+                break;
             }
+
+            string messageName("RICserviceUpdate");
+            string ieName("RICserviceUpdateIEs");
+            message.message.messageType = RIC_SERVICE_UPDATE;
+            message.peerInfo->counters[IN_INITI][MSG_COUNTER][ProcedureCode_id_RICserviceUpdate - 1]->Increment();
+            message.peerInfo->counters[IN_INITI][BYTES_COUNTER][ProcedureCode_id_RICserviceUpdate - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
+
+            buildAndsendSetupRequest(message, rmrMessageBuffer, pdu, messageName, ieName, RANfunctionsAdded_v, RANfunctionsModified_v);
             break;
         }
         case ProcedureCode_id_ErrorIndication: {
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got ErrorIndication %s", message.message.enodbName);
             }
+            message.peerInfo->counters[IN_INITI][MSG_COUNTER][ProcedureCode_id_ErrorIndication - 1]->Increment();
+            message.peerInfo->counters[IN_INITI][BYTES_COUNTER][ProcedureCode_id_ErrorIndication - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
             if (sendRequestToXapp(message, RIC_ERROR_INDICATION, rmrMessageBuffer) != 0) {
                 mdclog_write(MDCLOG_ERR, "RIC_ERROR_INDICATION failed to send to xAPP");
             }
@@ -1462,14 +1696,15 @@
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got Reset %s", message.message.enodbName);
             }
-            if (sendRequestToXapp(message, RIC_X2_RESET, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_X2_RESET message failed to send to xAPP");
+
+            message.peerInfo->counters[IN_INITI][MSG_COUNTER][ProcedureCode_id_Reset - 1]->Increment();
+            message.peerInfo->counters[IN_INITI][BYTES_COUNTER][ProcedureCode_id_Reset - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
+            if (XML_From_PER(message, rmrMessageBuffer) < 0) {
+                break;
             }
-            break;
-        }
-        case ProcedureCode_id_RICcontrol: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICcontrol %s", message.message.enodbName);
+
+            if (sendRequestToXapp(message, RIC_E2_RESET_REQ, rmrMessageBuffer) != 0) {
+                mdclog_write(MDCLOG_ERR, "RIC_E2_RESET_REQ message failed to send to xAPP");
             }
             break;
         }
@@ -1506,6 +1741,8 @@
                                          ie->value.choice.RICrequestID.ricInstanceID,
                                          ie->value.choice.RICrequestID.ricRequestorID);
                         }
+                        message.peerInfo->counters[IN_INITI][MSG_COUNTER][ProcedureCode_id_RICindication - 1]->Increment();
+                        message.peerInfo->counters[IN_INITI][BYTES_COUNTER][ProcedureCode_id_RICindication - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
                         sendRmrMessage(rmrMessageBuffer, message);
                         messageSent = true;
                     } else {
@@ -1518,24 +1755,6 @@
             }
             break;
         }
-        case ProcedureCode_id_RICserviceQuery: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICserviceQuery %s", message.message.enodbName);
-            }
-            break;
-        }
-        case ProcedureCode_id_RICsubscription: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICsubscription %s", message.message.enodbName);
-            }
-            break;
-        }
-        case ProcedureCode_id_RICsubscriptionDelete: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICsubscriptionDelete %s", message.message.enodbName);
-            }
-            break;
-        }
         default: {
             mdclog_write(MDCLOG_ERR, "Undefined or not supported message = %ld", procedureCode);
             message.message.messageType = 0; // no RMR message type yet
@@ -1563,27 +1782,17 @@
         mdclog_write(MDCLOG_INFO, "Successful Outcome %ld", procedureCode);
     }
     switch (procedureCode) {
-        case ProcedureCode_id_E2setup: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got E2setup\n");
-            }
-            break;
-        }
-        case ProcedureCode_id_ErrorIndication: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got ErrorIndication %s", message.message.enodbName);
-            }
-            if (sendRequestToXapp(message, RIC_ERROR_INDICATION, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_ERROR_INDICATION failed to send to xAPP");
-            }
-            break;
-        }
         case ProcedureCode_id_Reset: {
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got Reset %s", message.message.enodbName);
             }
-            if (sendRequestToXapp(message, RIC_X2_RESET, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_X2_RESET message failed to send to xAPP");
+            message.peerInfo->counters[IN_SUCC][MSG_COUNTER][ProcedureCode_id_Reset - 1]->Increment();
+            message.peerInfo->counters[IN_SUCC][BYTES_COUNTER][ProcedureCode_id_Reset - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
+            if (XML_From_PER(message, rmrMessageBuffer) < 0) {
+                break;
+            }
+            if (sendRequestToXapp(message, RIC_E2_RESET_RESP, rmrMessageBuffer) != 0) {
+                mdclog_write(MDCLOG_ERR, "RIC_E2_RESET_RESP message failed to send to xAPP");
             }
             break;
         }
@@ -1615,6 +1824,8 @@
                                        (unsigned char *)message.message.enodbName,
                                        strlen(message.message.enodbName));
 
+                        message.peerInfo->counters[IN_SUCC][MSG_COUNTER][ProcedureCode_id_RICcontrol - 1]->Increment();
+                        message.peerInfo->counters[IN_SUCC][BYTES_COUNTER][ProcedureCode_id_RICcontrol - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
                         sendRmrMessage(rmrMessageBuffer, message);
                         messageSent = true;
                     } else {
@@ -1628,66 +1839,12 @@
 
             break;
         }
-        case ProcedureCode_id_RICindication: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICindication %s", message.message.enodbName);
-            }
-            for (auto i = 0; i < pdu->choice.initiatingMessage->value.choice.RICindication.protocolIEs.list.count; i++) {
-                auto messageSent = false;
-                RICindication_IEs_t *ie = pdu->choice.initiatingMessage->value.choice.RICindication.protocolIEs.list.array[i];
-                if (logLevel >= MDCLOG_DEBUG) {
-                    mdclog_write(MDCLOG_DEBUG, "ie type (ProtocolIE_ID) = %ld", ie->id);
-                }
-                if (ie->id == ProtocolIE_ID_id_RICrequestID) {
-                    if (logLevel >= MDCLOG_DEBUG) {
-                        mdclog_write(MDCLOG_DEBUG, "Got RIC requestId entry, ie type (ProtocolIE_ID) = %ld", ie->id);
-                    }
-                    if (ie->value.present == RICindication_IEs__value_PR_RICrequestID) {
-                        static unsigned char tx[32];
-                        message.message.messageType = rmrMessageBuffer.sendMessage->mtype = RIC_INDICATION;
-                        snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
-                        rmr_bytes2xact(rmrMessageBuffer.sendMessage, tx, strlen((const char *) tx));
-                        rmr_bytes2meid(rmrMessageBuffer.sendMessage,
-                                       (unsigned char *)message.message.enodbName,
-                                       strlen(message.message.enodbName));
-                        rmrMessageBuffer.sendMessage->state = 0;
-                        rmrMessageBuffer.sendMessage->sub_id = (int)ie->value.choice.RICrequestID.ricInstanceID;
-                        if (mdclog_level_get() >= MDCLOG_DEBUG) {
-                            mdclog_write(MDCLOG_DEBUG, "RIC sub id = %d, message type = %d",
-                                         rmrMessageBuffer.sendMessage->sub_id,
-                                         rmrMessageBuffer.sendMessage->mtype);
-                        }
-                        sendRmrMessage(rmrMessageBuffer, message);
-                        messageSent = true;
-                    } else {
-                        mdclog_write(MDCLOG_ERR, "RIC request id missing illigal request");
-                    }
-                }
-                if (messageSent) {
-                    break;
-                }
-            }
-            break;
-        }
-        case ProcedureCode_id_RICserviceQuery: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICserviceQuery %s", message.message.enodbName);
-            }
-            break;
-        }
-        case ProcedureCode_id_RICserviceUpdate: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICserviceUpdate %s", message.message.enodbName);
-            }
-            if (sendRequestToXapp(message, RIC_SERVICE_UPDATE, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_SERVICE_UPDATE message failed to send to xAPP");
-            }
-            break;
-        }
         case ProcedureCode_id_RICsubscription: {
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got RICsubscription %s", message.message.enodbName);
             }
+            message.peerInfo->counters[IN_SUCC][MSG_COUNTER][ProcedureCode_id_RICsubscription - 1]->Increment();
+            message.peerInfo->counters[IN_SUCC][BYTES_COUNTER][ProcedureCode_id_RICsubscription - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
             if (sendRequestToXapp(message, RIC_SUB_RESP, rmrMessageBuffer) != 0) {
                 mdclog_write(MDCLOG_ERR, "Subscription successful message failed to send to xAPP");
             }
@@ -1697,6 +1854,8 @@
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got RICsubscriptionDelete %s", message.message.enodbName);
             }
+            message.peerInfo->counters[IN_SUCC][MSG_COUNTER][ProcedureCode_id_RICsubscriptionDelete - 1]->Increment();
+            message.peerInfo->counters[IN_SUCC][BYTES_COUNTER][ProcedureCode_id_RICsubscriptionDelete - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
             if (sendRequestToXapp(message, RIC_SUB_DEL_RESP, rmrMessageBuffer) != 0) {
                 mdclog_write(MDCLOG_ERR, "Subscription delete successful message failed to send to xAPP");
             }
@@ -1728,30 +1887,6 @@
         mdclog_write(MDCLOG_INFO, "Unsuccessful Outcome %ld", procedureCode);
     }
     switch (procedureCode) {
-        case ProcedureCode_id_E2setup: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got E2setup\n");
-            }
-            break;
-        }
-        case ProcedureCode_id_ErrorIndication: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got ErrorIndication %s", message.message.enodbName);
-            }
-            if (sendRequestToXapp(message, RIC_ERROR_INDICATION, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_ERROR_INDICATION failed to send to xAPP");
-            }
-            break;
-        }
-        case ProcedureCode_id_Reset: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got Reset %s", message.message.enodbName);
-            }
-            if (sendRequestToXapp(message, RIC_X2_RESET, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_X2_RESET message failed to send to xAPP");
-            }
-            break;
-        }
         case ProcedureCode_id_RICcontrol: {
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got RICcontrol %s", message.message.enodbName);
@@ -1777,6 +1912,8 @@
                         rmr_bytes2xact(rmrMessageBuffer.sendMessage, tx, strlen((const char *) tx));
                         rmr_bytes2meid(rmrMessageBuffer.sendMessage, (unsigned char *) message.message.enodbName,
                                        strlen(message.message.enodbName));
+                        message.peerInfo->counters[IN_UN_SUCC][MSG_COUNTER][ProcedureCode_id_RICcontrol - 1]->Increment();
+                        message.peerInfo->counters[IN_UN_SUCC][BYTES_COUNTER][ProcedureCode_id_RICcontrol - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
                         sendRmrMessage(rmrMessageBuffer, message);
                         messageSent = true;
                     } else {
@@ -1789,67 +1926,12 @@
             }
             break;
         }
-        case ProcedureCode_id_RICindication: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICindication %s", message.message.enodbName);
-            }
-            for (auto i = 0; i < pdu->choice.initiatingMessage->value.choice.RICindication.protocolIEs.list.count; i++) {
-                auto messageSent = false;
-                RICindication_IEs_t *ie = pdu->choice.initiatingMessage->value.choice.RICindication.protocolIEs.list.array[i];
-                if (logLevel >= MDCLOG_DEBUG) {
-                    mdclog_write(MDCLOG_DEBUG, "ie type (ProtocolIE_ID) = %ld", ie->id);
-                }
-                if (ie->id == ProtocolIE_ID_id_RICrequestID) {
-                    if (logLevel >= MDCLOG_DEBUG) {
-                        mdclog_write(MDCLOG_DEBUG, "Got RIC requestId entry, ie type (ProtocolIE_ID) = %ld", ie->id);
-                    }
-                    if (ie->value.present == RICindication_IEs__value_PR_RICrequestID) {
-                        static unsigned char tx[32];
-                        message.message.messageType = rmrMessageBuffer.sendMessage->mtype = RIC_INDICATION;
-                        snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
-                        rmr_bytes2xact(rmrMessageBuffer.sendMessage, tx, strlen((const char *) tx));
-                        rmr_bytes2meid(rmrMessageBuffer.sendMessage,
-                                       (unsigned char *)message.message.enodbName,
-                                       strlen(message.message.enodbName));
-                        rmrMessageBuffer.sendMessage->state = 0;
-//                        rmrMessageBuffer.sendMessage->sub_id = (int)ie->value.choice.RICrequestID.ricRequestorID;
-                        rmrMessageBuffer.sendMessage->sub_id = (int)ie->value.choice.RICrequestID.ricInstanceID;
-                        if (mdclog_level_get() >= MDCLOG_DEBUG) {
-                            mdclog_write(MDCLOG_DEBUG, "RIC sub id = %d, message type = %d",
-                                         rmrMessageBuffer.sendMessage->sub_id,
-                                         rmrMessageBuffer.sendMessage->mtype);
-                        }
-                        sendRmrMessage(rmrMessageBuffer, message);
-                        messageSent = true;
-                    } else {
-                        mdclog_write(MDCLOG_ERR, "RIC request id missing illigal request");
-                    }
-                }
-                if (messageSent) {
-                    break;
-                }
-            }
-            break;
-        }
-        case ProcedureCode_id_RICserviceQuery: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICserviceQuery %s", message.message.enodbName);
-            }
-            break;
-        }
-        case ProcedureCode_id_RICserviceUpdate: {
-            if (logLevel >= MDCLOG_DEBUG) {
-                mdclog_write(MDCLOG_DEBUG, "Got RICserviceUpdate %s", message.message.enodbName);
-            }
-            if (sendRequestToXapp(message, RIC_SERVICE_UPDATE, rmrMessageBuffer) != 0) {
-                mdclog_write(MDCLOG_ERR, "RIC_SERVICE_UPDATE message failed to send to xAPP");
-            }
-            break;
-        }
         case ProcedureCode_id_RICsubscription: {
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got RICsubscription %s", message.message.enodbName);
             }
+            message.peerInfo->counters[IN_UN_SUCC][MSG_COUNTER][ProcedureCode_id_RICsubscription - 1]->Increment();
+            message.peerInfo->counters[IN_UN_SUCC][BYTES_COUNTER][ProcedureCode_id_RICsubscription - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
             if (sendRequestToXapp(message, RIC_SUB_FAILURE, rmrMessageBuffer) != 0) {
                 mdclog_write(MDCLOG_ERR, "Subscription unsuccessful message failed to send to xAPP");
             }
@@ -1859,7 +1941,9 @@
             if (logLevel >= MDCLOG_DEBUG) {
                 mdclog_write(MDCLOG_DEBUG, "Got RICsubscriptionDelete %s", message.message.enodbName);
             }
-            if (sendRequestToXapp(message, RIC_SUB_DEL_FAILURE, rmrMessageBuffer) != 0) {
+            message.peerInfo->counters[IN_UN_SUCC][MSG_COUNTER][ProcedureCode_id_RICsubscriptionDelete - 1]->Increment();
+            message.peerInfo->counters[IN_UN_SUCC][BYTES_COUNTER][ProcedureCode_id_RICsubscriptionDelete - 1]->Increment((double)rmrMessageBuffer.rcvMessage->len);
+            if (sendRequestToXapp(message, RIC_SUB_FAILURE, rmrMessageBuffer) != 0) {
                 mdclog_write(MDCLOG_ERR, "Subscription Delete unsuccessful message failed to send to xAPP");
             }
             break;
@@ -1898,7 +1982,10 @@
     return rc;
 }
 
-
+/**
+ *
+ * @param pSctpParams
+ */
 void getRmrContext(sctp_params_t &pSctpParams) {
     pSctpParams.rmrCtx = nullptr;
     pSctpParams.rmrCtx = rmr_init(pSctpParams.rmrAddress, RECEIVE_XAPP_BUFFER_SIZE, RMRFL_NONE);
@@ -1942,11 +2029,17 @@
     }
 }
 
+/**
+ *
+ * @param message
+ * @param rmrMessageBuffer
+ * @return
+ */
 int PER_FromXML(ReportingMessages_t &message, RmrMessagesBuffer_t &rmrMessageBuffer) {
     E2AP_PDU_t *pdu = nullptr;
 
     if (mdclog_level_get() >= MDCLOG_DEBUG) {
-        mdclog_write(MDCLOG_DEBUG, "got xml setup response of size %d is:%s",
+        mdclog_write(MDCLOG_DEBUG, "got xml Format  data from xApp of size %d is:%s",
                 rmrMessageBuffer.rcvMessage->len, rmrMessageBuffer.rcvMessage->payload);
     }
     auto rval = asn_decode(nullptr, ATS_BASIC_XER, &asn_DEF_E2AP_PDU, (void **) &pdu,
@@ -2013,12 +2106,27 @@
         return -1;
     }
     rmr_get_meid(rmrMessageBuffer.rcvMessage, (unsigned char *)message.message.enodbName);
+    message.peerInfo = (ConnectedCU_t *) sctpMap->find(message.message.enodbName);
+    if (message.peerInfo == nullptr) {
+        auto type = rmrMessageBuffer.rcvMessage->mtype;
+        switch (type) {
+            case RIC_SCTP_CLEAR_ALL:
+            case E2_TERM_KEEP_ALIVE_REQ:
+            case RIC_HEALTH_CHECK_REQ:
+                break;
+            default:
+                mdclog_write(MDCLOG_ERR, "Failed to send message no CU entry %s", message.message.enodbName);
+                return -1;
+        }
+    }
+
     switch (rmrMessageBuffer.rcvMessage->mtype) {
         case RIC_E2_SETUP_RESP : {
             if (PER_FromXML(message, rmrMessageBuffer) != 0) {
                 break;
             }
-
+            message.peerInfo->counters[OUT_SUCC][MSG_COUNTER][ProcedureCode_id_E2setup - 1]->Increment();
+            message.peerInfo->counters[OUT_SUCC][BYTES_COUNTER][ProcedureCode_id_E2setup - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_E2_SETUP_RESP");
                 return -6;
@@ -2029,6 +2137,8 @@
             if (PER_FromXML(message, rmrMessageBuffer) != 0) {
                 break;
             }
+            message.peerInfo->counters[OUT_UN_SUCC][MSG_COUNTER][ProcedureCode_id_E2setup - 1]->Increment();
+            message.peerInfo->counters[OUT_UN_SUCC][BYTES_COUNTER][ProcedureCode_id_E2setup - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_E2_SETUP_FAILURE");
                 return -6;
@@ -2036,6 +2146,8 @@
             break;
         }
         case RIC_ERROR_INDICATION: {
+            message.peerInfo->counters[OUT_INITI][MSG_COUNTER][ProcedureCode_id_ErrorIndication - 1]->Increment();
+            message.peerInfo->counters[OUT_INITI][BYTES_COUNTER][ProcedureCode_id_ErrorIndication - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_ERROR_INDICATION");
                 return -6;
@@ -2043,6 +2155,8 @@
             break;
         }
         case RIC_SUB_REQ: {
+            message.peerInfo->counters[OUT_INITI][MSG_COUNTER][ProcedureCode_id_RICsubscription - 1]->Increment();
+            message.peerInfo->counters[OUT_INITI][BYTES_COUNTER][ProcedureCode_id_RICsubscription - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_SUB_REQ");
                 return -6;
@@ -2050,6 +2164,8 @@
             break;
         }
         case RIC_SUB_DEL_REQ: {
+            message.peerInfo->counters[OUT_INITI][MSG_COUNTER][ProcedureCode_id_RICsubscriptionDelete - 1]->Increment();
+            message.peerInfo->counters[OUT_INITI][BYTES_COUNTER][ProcedureCode_id_RICsubscriptionDelete - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_SUB_DEL_REQ");
                 return -6;
@@ -2057,6 +2173,8 @@
             break;
         }
         case RIC_CONTROL_REQ: {
+            message.peerInfo->counters[OUT_INITI][MSG_COUNTER][ProcedureCode_id_RICcontrol - 1]->Increment();
+            message.peerInfo->counters[OUT_INITI][BYTES_COUNTER][ProcedureCode_id_RICcontrol - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_CONTROL_REQ");
                 return -6;
@@ -2067,6 +2185,8 @@
             if (PER_FromXML(message, rmrMessageBuffer) != 0) {
                 break;
             }
+            message.peerInfo->counters[OUT_INITI][MSG_COUNTER][ProcedureCode_id_RICserviceQuery - 1]->Increment();
+            message.peerInfo->counters[OUT_INITI][BYTES_COUNTER][ProcedureCode_id_RICserviceQuery - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_SERVICE_QUERY");
                 return -6;
@@ -2077,6 +2197,8 @@
             if (PER_FromXML(message, rmrMessageBuffer) != 0) {
                 break;
             }
+            message.peerInfo->counters[OUT_SUCC][MSG_COUNTER][ProcedureCode_id_RICserviceUpdate - 1]->Increment();
+            message.peerInfo->counters[OUT_SUCC][BYTES_COUNTER][ProcedureCode_id_RICserviceQuery - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_SERVICE_UPDATE_ACK");
                 return -6;
@@ -2087,22 +2209,34 @@
             if (PER_FromXML(message, rmrMessageBuffer) != 0) {
                 break;
             }
+            message.peerInfo->counters[OUT_UN_SUCC][MSG_COUNTER][ProcedureCode_id_RICserviceUpdate - 1]->Increment();
+            message.peerInfo->counters[OUT_UN_SUCC][BYTES_COUNTER][ProcedureCode_id_RICserviceQuery - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
                 mdclog_write(MDCLOG_ERR, "Failed to send RIC_SERVICE_UPDATE_FAILURE");
                 return -6;
             }
             break;
         }
-        case RIC_X2_RESET: {
+        case RIC_E2_RESET_REQ: {
+            if (PER_FromXML(message, rmrMessageBuffer) != 0) {
+                break;
+            }
+            message.peerInfo->counters[OUT_INITI][MSG_COUNTER][ProcedureCode_id_Reset - 1]->Increment();
+            message.peerInfo->counters[OUT_INITI][BYTES_COUNTER][ProcedureCode_id_Reset - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
-                mdclog_write(MDCLOG_ERR, "Failed to send RIC_X2_RESET");
+                mdclog_write(MDCLOG_ERR, "Failed to send RIC_E2_RESET");
                 return -6;
             }
             break;
         }
-        case RIC_X2_RESET_RESP: {
+        case RIC_E2_RESET_RESP: {
+            if (PER_FromXML(message, rmrMessageBuffer) != 0) {
+                break;
+            }
+            message.peerInfo->counters[OUT_SUCC][MSG_COUNTER][ProcedureCode_id_Reset - 1]->Increment();
+            message.peerInfo->counters[OUT_SUCC][BYTES_COUNTER][ProcedureCode_id_Reset - 1]->Increment(rmrMessageBuffer.rcvMessage->len);
             if (sendDirectionalSctpMsg(rmrMessageBuffer, message, 0, sctpMap) != 0) {
-                mdclog_write(MDCLOG_ERR, "Failed to send RIC_X2_RESET_RESP");
+                mdclog_write(MDCLOG_ERR, "Failed to send RIC_E2_RESET_RESP");
                 return -6;
             }
             break;
@@ -2165,6 +2299,30 @@
 
             break;
         }
+        case RIC_HEALTH_CHECK_REQ: {
+            // send message back
+            rmr_bytes2payload(rmrMessageBuffer.sendMessage,
+                              (unsigned char *)"OK",
+                              2);
+            rmrMessageBuffer.sendMessage->mtype = RIC_HEALTH_CHECK_RESP;
+            rmrMessageBuffer.sendMessage->state = 0;
+            static unsigned char tx[32];
+            auto txLen = snprintf((char *) tx, sizeof tx, "%15ld", transactionCounter++);
+            rmr_bytes2xact(rmrMessageBuffer.sendMessage, tx, txLen);
+            rmrMessageBuffer.sendMessage = rmr_send_msg(rmrMessageBuffer.rmrCtx, rmrMessageBuffer.sendMessage);
+            if (rmrMessageBuffer.sendMessage == nullptr) {
+                rmrMessageBuffer.sendMessage = rmr_alloc_msg(rmrMessageBuffer.rmrCtx, RECEIVE_XAPP_BUFFER_SIZE);
+                mdclog_write(MDCLOG_ERR, "Failed to send RIC_HEALTH_CHECK_RESP RMR message returned NULL");
+            } else if (rmrMessageBuffer.sendMessage->state != 0)  {
+                mdclog_write(MDCLOG_ERR, "Failed to send RIC_HEALTH_CHECK_RESP, on RMR state = %d ( %s)",
+                             rmrMessageBuffer.sendMessage->state, translateRmrErrorMessages(rmrMessageBuffer.sendMessage->state).c_str());
+            } else if (mdclog_level_get() >= MDCLOG_DEBUG) {
+                mdclog_write(MDCLOG_DEBUG, "Got RIC_HEALTH_CHECK_REQ Request send : OK");
+            }
+
+            break;
+        }
+
         default:
             mdclog_write(MDCLOG_WARN, "Message Type : %d is not seported", rmrMessageBuffer.rcvMessage->mtype);
             message.message.asndata = rmrMessageBuffer.rcvMessage->payload;
@@ -2218,19 +2376,9 @@
                     RmrMessagesBuffer_t &messageBuffer,
                     ReportingMessages_t &message,
                     int failedMesgId) {
-    auto *peerInfo = (ConnectedCU_t *) sctpMap->find(message.message.enodbName);
-    if (peerInfo == nullptr) {
-        if (failedMesgId != 0) {
-            sendFailedSendingMessagetoXapp(messageBuffer, message, failedMesgId);
-        } else {
-            mdclog_write(MDCLOG_ERR, "Failed to send message no CU entry %s", message.message.enodbName);
-        }
-        return -1;
-    }
-
     // get the FD
     message.message.messageType = messageBuffer.rcvMessage->mtype;
-    auto rc = sendSctpMsg(peerInfo, message, sctpMap);
+    auto rc = sendSctpMsg(message.peerInfo, message, sctpMap);
     return rc;
 }
 
diff --git a/RIC-E2-TERMINATION/sctpThread.h b/RIC-E2-TERMINATION/sctpThread.h
index 10c6d90..2e286f8 100644
--- a/RIC-E2-TERMINATION/sctpThread.h
+++ b/RIC-E2-TERMINATION/sctpThread.h
@@ -50,6 +50,7 @@
 #include <map>
 #include <sys/inotify.h>
 #include <csignal>
+#include <future>
 
 #include <rmr/rmr.h>
 #include <rmr/RIC_message_types.h>
@@ -83,10 +84,15 @@
 
 #include "cxxopts.hpp"
 //#include "config-cpp/include/config-cpp/config-cpp.h"
+#include <zlib.h>
+#include <prometheus/counter.h>
+#include <prometheus/exposer.h>
+#include <prometheus/gateway.h>
+#include <prometheus/registry.h>
 
+using namespace prometheus;
 
 #include "mapWrapper.h"
-#include "statCollector.h"
 
 #include "base64.h"
 
@@ -106,8 +112,8 @@
 
 #define MAXEVENTS 128
 
-#define RECEIVE_SCTP_BUFFER_SIZE (128 * 1024)
-#define RECEIVE_XAPP_BUFFER_SIZE RECEIVE_SCTP_BUFFER_SIZE 
+#define RECEIVE_SCTP_BUFFER_SIZE (256 * 1024)
+#define RECEIVE_XAPP_BUFFER_SIZE RECEIVE_SCTP_BUFFER_SIZE
 
 typedef mapWrapper Sctp_Map_t;
 
@@ -117,6 +123,7 @@
 #define KA_MESSAGE_SIZE 2048
 
 typedef struct sctp_params {
+    int      epollTimeOut = -1;
     uint16_t rmrPort = 0;
     uint16_t sctpPort = SRC_PORT;
     int      epoll_fd = 0;
@@ -137,9 +144,28 @@
     string configFilePath {};
     string configFileName {};
     bool trace = true;
-    //shared_timed_mutex fence; // moved to mapWrapper
+    string prometheusMode {"pull"};
+    string prometheusPushAddress {"127.0.0.1:7676"};
+    shared_ptr<prometheus::Registry> prometheusRegistry;
+    string prometheusPort {"8088"};
+    Family<Counter> *prometheusFamily;
+    Gateway *prometheusGateway = nullptr;
+    Exposer *prometheusExposer = nullptr;
 } sctp_params_t;
 
+// RAN to RIC
+#define IN_INITI 0 //INITIATING
+#define IN_SUCC 1 //SUCCESSFULL
+#define IN_UN_SUCC 2 //UN-Successfull
+
+// RIC To RAN
+#define OUT_INITI 3 //INITIATING
+#define OUT_SUCC 4 //SUCCESSFULL
+#define OUT_UN_SUCC 5 //UN-Successfull
+
+#define MSG_COUNTER 0
+#define BYTES_COUNTER 1
+
 typedef struct ConnectedCU {
     int fileDescriptor = 0;
     char hostName[NI_MAXHOST] {};
@@ -151,8 +177,10 @@
     bool isConnected = false;
     bool gotSetup = false;
     sctp_params_t *sctpParams = nullptr;
+    Counter *counters[6][2][ProcedureCode_id_RICsubscriptionDelete] {};
 } ConnectedCU_t ;
 
+
 #define MAX_RMR_BUFF_ARRY 32
 typedef struct RmrMessagesBuffer {
     char ka_message[KA_MESSAGE_SIZE] {};
@@ -179,7 +207,6 @@
     long outLen = 0;
     unsigned char base64Data[RECEIVE_SCTP_BUFFER_SIZE * 2] {};
     char buffer[RECEIVE_SCTP_BUFFER_SIZE * 8] {};
-    StatCollector *statCollector = nullptr;
 } ReportingMessages_t;
 
 cxxopts::ParseResult parse(int argc, char *argv[], sctp_params_t &pSctpParams);
diff --git a/RIC-E2-TERMINATION/statCollector.h b/RIC-E2-TERMINATION/statCollector.h
deleted file mode 100644
index 3279585..0000000
--- a/RIC-E2-TERMINATION/statCollector.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright 2020 AT&T Intellectual Property
- * Copyright 2020 Nokia
- *
- * 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 adi ENZEL on 3/24/20.
-//
-
-#ifndef E2_STATCOLLECTOR_H
-#define E2_STATCOLLECTOR_H
-
-#include <unordered_map>
-#include <mutex>
-#include <shared_mutex>
-#include <thread>
-#include <string>
-#include <iostream>
-#include <utility>
-#include <chrono>
-#include <ctime>
-#include <iomanip>
-#include <mdclog/mdclog.h>
-//#include <tbb/concurrent_unordered_map.h>
-
-//using namespace tbb;
-
-typedef struct statResult {
-    std::string ranName;
-    uint32_t receivedMessages;
-    uint32_t sentMessages;
-} statResult_t ;
-
-class StatCollector {
-
-    static std::mutex singltonMutex;
-    static std::atomic<StatCollector *> obj;
-
-public:
-    static StatCollector* GetInstance() {
-        StatCollector* pStatCollector = obj.load(std::memory_order_acquire);
-        if (pStatCollector == nullptr) {
-            std::lock_guard<std::mutex> lock(singltonMutex);
-            pStatCollector = obj.load(std::memory_order_relaxed);
-            if (pStatCollector == nullptr) {
-                pStatCollector = new StatCollector();
-                obj.store(pStatCollector, std::memory_order_release);
-            }
-        }
-        return pStatCollector;
-    }
-
-    void incSentMessage(const std::string &key) {
-        increment(sentMessages, key);
-    }
-    void incRecvMessage(const std::string &key) {
-        increment(recvMessages, key);
-    }
-
-    std::vector<statResult_t> &getCurrentStats() {
-        results.clear();
-
-        for (auto const &e : recvMessages) {
-            statResult_t result {};
-            result.ranName = e.first;
-            result.receivedMessages = e.second.load(std::memory_order_acquire);
-            auto found = sentMessages.find(result.ranName);
-            if (found != sentMessages.end()) {
-                result.sentMessages = found->second.load(std::memory_order_acquire);
-            } else {
-              result.sentMessages = 0;
-            }
-
-            results.emplace_back(result);
-        }
-        return results;
-    }
-
-    StatCollector(const StatCollector&)= delete;
-    StatCollector& operator=(const StatCollector&)= delete;
-
-private:
-    //tbb::concurrent_unordered_map<std::string, int> sentMessages;
-    std::unordered_map<std::string, std::atomic<int>> sentMessages;
-    std::unordered_map<std::string, std::atomic<int>> recvMessages;
-//    tbb::concurrent_unordered_map<std::string, int> recvMessages;
-    std::vector<statResult_t> results;
-
-
-//    StatCollector() = default;
-    StatCollector() {
-        sentMessages.clear();
-        recvMessages.clear();
-    }
-    ~StatCollector() = default;
-
-
-    void increment(std::unordered_map<std::string, std::atomic<int>> &map, const std::string &key);
-
-};
-
-void StatCollector::increment(std::unordered_map<std::string, std::atomic<int>> &map, const std::string &key) {
-    if (map.empty()) {
-        map.emplace(std::piecewise_construct,
-                    std::forward_as_tuple(key),
-                    std::forward_as_tuple(1));
-        return;
-    }
-    auto found = map.find(key);
-    if (found != map.end()) { //inc
-        map[key].fetch_add(1, std::memory_order_release);
-        //map[key]++;
-    } else { //add
-        //sentMessages.emplace(std::make_pair(std::string(key), std::atomic<int>(0)));
-        map.emplace(std::piecewise_construct,
-                    std::forward_as_tuple(key),
-                    std::forward_as_tuple(1));
-    }
-
-}
-
-
-// must define this to allow StatCollector private variables to be known to compiler linker
-std::mutex StatCollector::singltonMutex;
-std::atomic<StatCollector *> StatCollector::obj;
-
-
-void statColectorThread(void *runtime) {
-    bool *stop_loop = (bool *)runtime;
-    auto *statCollector = StatCollector::GetInstance();
-    std::time_t tt = std::chrono::system_clock::to_time_t (std::chrono::system_clock::now());
-
-    struct std::tm * ptm = std::localtime(&tt);
-    std::cout << "Waiting for the next minute to begin...\n";
-    ptm->tm_min = ptm->tm_min + (5 - ptm->tm_min % 5);
-    ptm->tm_sec=0;
-
-    std::this_thread::sleep_until(std::chrono::system_clock::from_time_t(mktime(ptm)));
-
-// alligned to 5 minutes
-    while (true) {
-        if (*stop_loop) {
-            break;
-        }
-        for (auto const &e : statCollector->getCurrentStats()) {
-            if (mdclog_level_get() >= MDCLOG_INFO) {
-                mdclog_write(MDCLOG_INFO, "RAN : %s sent messages : %d recived messages : %d\n",
-                             e.ranName.c_str(), e.sentMessages, e.receivedMessages);
-            }
-        }
-        std::this_thread::sleep_for(std::chrono::seconds(300));
-    }
-}
-#endif //E2_STATCOLLECTOR_H