[RICPLT-1852] Supports E2T Initialize + ExecuteSetup + prepare setup request on init

Change-Id: I5baf070b78f1ed38a92b188b6b8a789d5cb151dd
Signed-off-by: rh362j <ronen.hasid@intl.att.com>
diff --git a/E2Manager/asn1codec/src/x2setup_request_wrapper.c b/E2Manager/asn1codec/src/x2setup_request_wrapper.c
index a159f98..2eebbb1 100644
--- a/E2Manager/asn1codec/src/x2setup_request_wrapper.c
+++ b/E2Manager/asn1codec/src/x2setup_request_wrapper.c
@@ -211,7 +211,7 @@
 	assert(broadcastPLMN_Identity != 0);
 	ASN_SEQUENCE_ADD(&servedCell_Information->broadcastPLMNs, broadcastPLMN_Identity);
 
-	assignPLMN_Identity(broadcastPLMN_Identity,ric_flag);
+	assignPLMN_Identity(broadcastPLMN_Identity, pLMN_Identity); //ric_flag: disabled because a real eNB rejects the message
 
 	servedCell_Information->eUTRA_Mode_Info.present= EUTRA_Mode_Info_PR_fDD;
 	servedCell_Information->eUTRA_Mode_Info.choice.fDD = calloc(1, sizeof(FDD_Info_t));
diff --git a/E2Manager/container-tag.yaml b/E2Manager/container-tag.yaml
index daa3e14..4add8c7 100644
--- a/E2Manager/container-tag.yaml
+++ b/E2Manager/container-tag.yaml
@@ -1,4 +1,4 @@
 # The Jenkins job requires a tag to build the Docker image.
 # Global-JJB script assumes this file is in the repo root.
 ---
-tag: 1.0.4
+tag: 2.0.4
diff --git a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer_test.go b/E2Manager/e2pdus/endc_x2_setup_request_test.go
similarity index 63%
rename from E2Manager/handlers/endc_x2apSetupRequest_asn1_packer_test.go
rename to E2Manager/e2pdus/endc_x2_setup_request_test.go
index 5c88773..e288c18 100644
--- a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer_test.go
+++ b/E2Manager/e2pdus/endc_x2_setup_request_test.go
@@ -15,10 +15,9 @@
  *   limitations under the License.
  *
  *******************************************************************************/
-package handlers
+package e2pdus
 
 import (
-	"e2mgr/logger"
 	"fmt"
 	"strings"
 	"testing"
@@ -29,8 +28,8 @@
  * Verify the packed representation matches the want value.
  */
 func TestPackEndcX2apSetupRequest(t *testing.T) {
-	logger, _ := logger.InitLogger(logger.InfoLevel)
 	pLMNId := []byte{0xbb, 0xbc, 0xcc}
+	ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/
 
 	var testCases = []struct {
 		eNBId []byte
@@ -38,26 +37,26 @@
 		packedPdu        string
 	}{
 		{
-			eNBId :[]byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/
-			eNBIdBitqty: shortMacro_eNB_ID,
-			packedPdu: "0024003200000100f4002b0000020015000900bbbccc8003abcd8000fa0017000001f700bbbcccabcd80000000bbbccc000000000001",
+			eNBId :      []byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/
+			eNBIdBitqty: ShortMacro_eNB_ID,
+			packedPdu:   "0024003200000100f4002b0000020015000900bbbccc8003abcd8000fa0017000001f700bbbcccabcd80000000bbbccc000000000001",
 		},
 
 		{
-			eNBId :[]byte{0xab, 0xcd, 0xe},
-			eNBIdBitqty: macro_eNB_ID,
-			packedPdu: "0024003100000100f4002a0000020015000800bbbccc00abcde000fa0017000001f700bbbcccabcde0000000bbbccc000000000001",
+			eNBId :      []byte{0xab, 0xcd, 0xe},
+			eNBIdBitqty: Macro_eNB_ID,
+			packedPdu:   "0024003100000100f4002a0000020015000800bbbccc00abcde000fa0017000001f700bbbcccabcde0000000bbbccc000000000001",
 		},
 		{
-			eNBId :[]byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/
-			eNBIdBitqty: longMacro_eNB_ID,
+			eNBId :      []byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/
+			eNBIdBitqty: LongMacro_eNB_ID,
 			//packedPdu: "0024003200000100f4002b0000020015000900bbbccc8103abcd3800fa0017000001f700bbbcccabcd38000000bbbccc000000000001",
 			packedPdu: "0024003200000100f4002b0000020015000900bbbcccc003abcd3800fa0017000001f700bbbcccabcd38000000bbbccc000000000001",
 		},
 		{
-			eNBId :[]byte{0xab, 0xcd, 0xef, 0x8},
-			eNBIdBitqty: home_eNB_ID,
-			packedPdu: "0024003200000100f4002b0000020015000900bbbccc40abcdef8000fa0017000001f700bbbcccabcdef800000bbbccc000000000001",
+			eNBId :      []byte{0xab, 0xcd, 0xef, 0x8},
+			eNBIdBitqty: Home_eNB_ID,
+			packedPdu:   "0024003200000100f4002b0000020015000900bbbccc40abcdef8000fa0017000001f700bbbcccabcdef800000bbbccc000000000001",
 		},
 
 
@@ -66,7 +65,7 @@
 	for _, tc := range testCases {
 		t.Run(tc.packedPdu, func(t *testing.T) {
 
-			payload, err := packEndcX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], tc.eNBId[:], tc.eNBIdBitqty)
+			payload, _, err := PreparePackedEndcX2SetupRequest(MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, tc.eNBId, tc.eNBIdBitqty, ricFlag)
 			if err != nil {
 				t.Errorf("want: success, got: pack failed. Error: %v\n", err)
 			} else {
@@ -87,11 +86,13 @@
 /*Packing error*/
 
 func TestPackEndcX2apSetupRequestPackError(t *testing.T) {
-	logger, _ := logger.InitLogger(logger.InfoLevel)
-
+	pLMNId := []byte{0xbb, 0xbc, 0xcc}
+	ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/
+	eNBId := []byte{0xab, 0xcd, 0x2}
+	eNBIdBitqty := uint(Macro_eNB_ID)
 	wantError := "packing error: #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big:53"
 
-	 _, err := packEndcX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, 40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], eNBId[:],eNBIdBitqty)
+	 _, _, err :=PreparePackedEndcX2SetupRequest(40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, eNBId, eNBIdBitqty, ricFlag)
 	if err != nil {
 		if 0 != strings.Compare(fmt.Sprintf("%s", err), wantError) {
 			t.Errorf("want failure: %s, got: %s", wantError, err)
diff --git a/E2Manager/handlers/x2apSetupRequest_asn1_packer_test.go b/E2Manager/e2pdus/x2_setup_request_test.go
similarity index 77%
rename from E2Manager/handlers/x2apSetupRequest_asn1_packer_test.go
rename to E2Manager/e2pdus/x2_setup_request_test.go
index 30967ad..42fcff8 100644
--- a/E2Manager/handlers/x2apSetupRequest_asn1_packer_test.go
+++ b/E2Manager/e2pdus/x2_setup_request_test.go
@@ -15,10 +15,9 @@
  *   limitations under the License.
  *
  *******************************************************************************/
-package handlers
+package e2pdus
 
 import (
-	"e2mgr/logger"
 	"fmt"
 	"strings"
 	"testing"
@@ -29,8 +28,9 @@
  * Verify the packed representation matches the want value.
  */
 func TestPackX2apSetupRequest(t *testing.T) {
-	logger, _ := logger.InitLogger(logger.InfoLevel)
 	pLMNId := []byte{0xbb, 0xbc, 0xcc}
+	ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/
+
 	var testCases = []struct {
 		eNBId       []byte
 		eNBIdBitqty uint
@@ -38,24 +38,24 @@
 	}{
 		{
 			eNBId:       []byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/
-			eNBIdBitqty: shortMacro_eNB_ID,
+			eNBIdBitqty: ShortMacro_eNB_ID,
 			packedPdu:   "0006002b0000020015000900bbbccc8003abcd8000140017000001f700bbbcccabcd80000000bbbccc000000000001",
 		},
 
 		{
 			eNBId:       []byte{0xab, 0xcd, 0xe},
-			eNBIdBitqty: macro_eNB_ID,
-			packedPdu: "0006002a0000020015000800bbbccc00abcde000140017000001f700bbbcccabcde0000000bbbccc000000000001",
+			eNBIdBitqty: Macro_eNB_ID,
+			packedPdu:   "0006002a0000020015000800bbbccc00abcde000140017000001f700bbbcccabcde0000000bbbccc000000000001",
 		},
 		{
 			eNBId:       []byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/
-			eNBIdBitqty: longMacro_eNB_ID,
+			eNBIdBitqty: LongMacro_eNB_ID,
 			//packedPdu:   "0006002b0000020015000900bbbccc8103abcd3800140017000001f700bbbcccabcd38000000bbbccc000000000001",
 			packedPdu:   "0006002b0000020015000900bbbcccc003abcd3800140017000001f700bbbcccabcd38000000bbbccc000000000001",
 		},
 		{
 			eNBId:       []byte{0xab, 0xcd, 0xef, 0x8},
-			eNBIdBitqty: home_eNB_ID,
+			eNBIdBitqty: Home_eNB_ID,
 			packedPdu:   "0006002b0000020015000900bbbccc40abcdef8000140017000001f700bbbcccabcdef800000bbbccc000000000001",
 		},
 	}
@@ -65,7 +65,7 @@
 	for _, tc := range testCases {
 		t.Run(tc.packedPdu, func(t *testing.T) {
 
-			payload, err := packX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, tc.eNBId, tc.eNBIdBitqty)
+			payload, _, err :=PreparePackedX2SetupRequest(MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, tc.eNBId, tc.eNBIdBitqty,ricFlag)
 			if err != nil {
 				t.Errorf("want: success, got: pack failed. Error: %v\n", err)
 			} else {
@@ -86,13 +86,13 @@
 /*Packing error*/
 
 func TestPackX2apSetupRequestPackError(t *testing.T) {
-	logger, _ := logger.InitLogger(logger.InfoLevel)
 
 	wantError := "packing error: #src/asn1codec_utils.c.pack_pdu_aux - Encoded output of E2AP-PDU, is too big:46"
 	pLMNId := []byte{0xbb, 0xbc, 0xcc}
+	ricFlag := []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/
 	eNBId := []byte{0xab, 0xcd, 0xe}
-	eNBIdBitqty := uint(macro_eNB_ID)
-	_, err := packX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, 40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], eNBId[:], eNBIdBitqty)
+	eNBIdBitqty := uint(Macro_eNB_ID)
+	_, _, err := PreparePackedX2SetupRequest(40 /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, eNBId, eNBIdBitqty, ricFlag)
 	if err != nil {
 		if 0 != strings.Compare(fmt.Sprintf("%s", err), wantError) {
 			t.Errorf("want failure: %s, got: %s", wantError, err)
diff --git a/E2Manager/e2pdus/x2_setup_requests.go b/E2Manager/e2pdus/x2_setup_requests.go
new file mode 100644
index 0000000..9f3d3f8
--- /dev/null
+++ b/E2Manager/e2pdus/x2_setup_requests.go
@@ -0,0 +1,80 @@
+package e2pdus
+
+// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/
+// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec
+// #include <asn1codec_utils.h>
+// #include <x2setup_request_wrapper.h>
+import "C"
+import (
+	"fmt"
+	"github.com/pkg/errors"
+	"unsafe"
+)
+
+const (
+	ShortMacro_eNB_ID = 18
+	Macro_eNB_ID      = 20
+	LongMacro_eNB_ID  = 21
+	Home_eNB_ID       = 28
+)
+
+var PackedEndcX2setupRequest []byte
+var PackedX2setupRequest []byte
+var PackedEndcX2setupRequestAsString string
+var PackedX2setupRequestAsString string
+
+func PreparePackedEndcX2SetupRequest(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int,pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint, ricFlag []byte) ([]byte, string, error) {
+	packedBuf := make([]byte, maxAsn1PackedBufferSize)
+	errBuf := make([]C.char, maxAsn1CodecMessageBufferSize)
+	packedBufSize := C.ulong(len(packedBuf))
+	pduAsString := ""
+
+	if !C.build_pack_endc_x2setup_request(
+			(*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/,
+			(*C.uchar)(unsafe.Pointer(&eNB_Id[0])),
+			C.uint(bitqty),
+			(*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/,
+			&packedBufSize,
+			(*C.uchar)(unsafe.Pointer(&packedBuf[0])),
+			C.ulong(len(errBuf)),
+			&errBuf[0]) {
+		return nil, "", errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0])))
+	}
+
+	pdu:= C.new_pdu(C.size_t(1)) //TODO: change signature
+	defer C.delete_pdu(pdu)
+	if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){
+		C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0])
+		pduAsString = C.GoString(&errBuf[0])
+	}
+
+	return packedBuf[:packedBufSize], pduAsString, nil
+}
+
+func PreparePackedX2SetupRequest(maxAsn1PackedBufferSize int, maxAsn1CodecMessageBufferSize int,pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint, ricFlag []byte) ([]byte, string, error)  {
+	packedBuf := make([]byte, maxAsn1PackedBufferSize)
+	errBuf := make([]C.char, maxAsn1CodecMessageBufferSize)
+	packedBufSize := C.ulong(len(packedBuf))
+	pduAsString := ""
+
+	if !C.build_pack_x2setup_request(
+		(*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/,
+		(*C.uchar)(unsafe.Pointer(&eNB_Id[0])),
+		C.uint(bitqty),
+		(*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/,
+		&packedBufSize,
+		(*C.uchar)(unsafe.Pointer(&packedBuf[0])),
+		C.ulong(len(errBuf)),
+		&errBuf[0]) {
+		return nil, "", errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0])))
+	}
+
+	pdu:= C.new_pdu(C.size_t(1)) //TODO: change signature
+	defer C.delete_pdu(pdu)
+	if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){
+		C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0])
+		pduAsString = C.GoString(&errBuf[0])
+	}
+	return packedBuf[:packedBufSize], pduAsString, nil
+}
+
diff --git a/E2Manager/handlers/e2_term_init_notification_handler.go b/E2Manager/handlers/e2_term_init_notification_handler.go
new file mode 100644
index 0000000..6e28d14
--- /dev/null
+++ b/E2Manager/handlers/e2_term_init_notification_handler.go
@@ -0,0 +1,66 @@
+//
+// 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.
+//
+
+package handlers
+
+import (
+	"e2mgr/logger"
+	"e2mgr/managers"
+	"e2mgr/models"
+	"e2mgr/sessions"
+	"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
+)
+
+type E2TermInitNotificationHandler struct {
+	rnibReaderProvider func() reader.RNibReader
+	ranReconnectionManager *managers.RanReconnectionManager
+}
+
+func NewE2TermInitNotificationHandler(ranReconnectionManager  *managers.RanReconnectionManager, rnibReaderProvider func() reader.RNibReader) E2TermInitNotificationHandler {
+	return E2TermInitNotificationHandler{
+		rnibReaderProvider: rnibReaderProvider,
+		ranReconnectionManager: ranReconnectionManager,
+	}
+}
+
+
+func (handler E2TermInitNotificationHandler) Handle(logger *logger.Logger, e2Sessions sessions.E2Sessions,
+	request *models.NotificationRequest, messageChannel chan<- *models.NotificationResponse) {
+	logger.Infof("#e2_term_init_notification_handler.Handle - Received E2_TERM_INIT")
+	return	//TODO: enable
+
+	nbIdentityList, err := handler.rnibReaderProvider().GetListNodebIds()
+
+	if err != nil {
+		logger.Errorf("#e2_term_init_notification_handler.Handle - Failed to get nodes list from RNIB. Error: %s", err.Error())
+		return
+	}
+
+	if len(nbIdentityList) == 0 {
+		logger.Warnf("#e2_term_init_notification_handler.Handle - The Nodes list in RNIB is empty")
+		return
+	}
+
+	for _,nbIdentity := range nbIdentityList{
+
+		if err := handler.ranReconnectionManager.ReconnectRan(nbIdentity.InventoryName); err != nil {
+			logger.Errorf("#e2_term_init_notification_handler.Handle - connection attempt failure, ran name: %s. Error: %s",
+				(*nbIdentity).GetInventoryName(), err.Error())
+			break
+		}
+	}
+}
diff --git a/E2Manager/handlers/endc_setup_request_handler.go b/E2Manager/handlers/endc_setup_request_handler.go
index ad3ae8f..6954149 100644
--- a/E2Manager/handlers/endc_setup_request_handler.go
+++ b/E2Manager/handlers/endc_setup_request_handler.go
@@ -18,9 +18,11 @@
 package handlers
 
 import (
+	"e2mgr/e2pdus"
 	"e2mgr/logger"
 	"e2mgr/rNibWriter"
 	"e2mgr/rnibBuilders"
+	"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
 	"sync"
 	"time"
 
@@ -40,7 +42,7 @@
 }
 
 func (handler EndcSetupRequestHandler) PreHandle(logger *logger.Logger, details *models.RequestDetails) error {
-	nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details)
+	nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details,entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST)
 
 	rNibErr := handler.rnibWriterProvider().SaveNodeb(nodebIdentity, nodebInfo)
 	if rNibErr != nil {
@@ -56,17 +58,13 @@
 
 	wg.Add(1)
 
-	 payload, err := packEndcX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId[:], eNBId[:], eNBIdBitqty)
-	if err != nil {
-		logger.Errorf("#endc_setup_request_handler.CreateMessage - pack was failed. Error: %v", err)
-	} else {
-		transactionId := requestDetails.RanName
-		e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails}
-		setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, payload)
+	transactionId := requestDetails.RanName
+	e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails}
+	setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, e2pdus.PackedEndcX2setupRequest)
 
-		logger.Debugf("#endc_setup_request_handler.CreateMessage - setupRequestMessage was created successfuly. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage)
-		messageChannel <- setupRequestMessage
-	}
+	logger.Debugf("#endc_setup_request_handler.CreateMessage - PDU: %s", e2pdus.PackedEndcX2setupRequestAsString)
+	logger.Debugf("#endc_setup_request_handler.CreateMessage - setupRequestMessage was created successfuly. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage)
+	messageChannel <- setupRequestMessage
 
 	wg.Done()
 }
diff --git a/E2Manager/handlers/endc_setup_response_notification_handler.go b/E2Manager/handlers/endc_setup_response_notification_handler.go
index e706039..2e64f3e 100644
--- a/E2Manager/handlers/endc_setup_response_notification_handler.go
+++ b/E2Manager/handlers/endc_setup_response_notification_handler.go
@@ -53,6 +53,7 @@
 			nb.GlobalNbId = nbIdentity.GlobalNbId
 			nb.RanName = e2session.Request.RanName
 			nb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
+			nb.E2ApplicationProtocol = entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST
 			nb.Ip = e2session.Request.RanIp
 			nb.Port = uint32(e2session.Request.RanPort)
 			nb.NodeType = entities.Node_GNB
diff --git a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer.go b/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer.go
deleted file mode 100644
index 879e01d..0000000
--- a/E2Manager/handlers/endc_x2apSetupRequest_asn1_packer.go
+++ /dev/null
@@ -1,54 +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.
-//
-
-package handlers
-
-// #cgo CFLAGS: -I../asn1codec/inc/ -I../asn1codec/e2ap_engine/
-// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec
-// #include <asn1codec_utils.h>
-// #include <x2setup_request_wrapper.h>
-import "C"
-import (
-	"e2mgr/logger"
-	"fmt"
-	"github.com/pkg/errors"
-	"unsafe"
-)
-
-func packEndcX2apSetupRequest(logger *logger.Logger, allocationBufferSize int, maxPackedBufferSize int, maxMessageBufferSize int, pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint) ([]byte, error) {
-	packedBuf := make([]byte, maxPackedBufferSize)
-	errBuf := make([]C.char, maxMessageBufferSize)
-	packedBufSize := C.ulong(len(packedBuf))
-
-	if !C.build_pack_endc_x2setup_request((*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/,
-		(*C.uchar)(unsafe.Pointer(&eNB_Id[0])), C.uint(bitqty),(*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/,
-		&packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])), C.ulong(len(errBuf)), &errBuf[0]) {
-		return  nil, errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0])))
-	}
-
-	if logger.DebugEnabled() {
-		pdu:= C.new_pdu(C.size_t(allocationBufferSize))
-		defer C.delete_pdu(pdu)
-		if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){
-			C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0])
-			logger.Debugf("endc_x2apSetupRequest_asn1_packer.packEndcX2apSetupRequest - PDU:%s\n\npacked (%d):%x", C.GoString(&errBuf[0]), packedBufSize, packedBuf[:packedBufSize])
-		}
-	}
-
-	return packedBuf[:packedBufSize], nil
-
-}
diff --git a/E2Manager/handlers/setup_request_handler.go b/E2Manager/handlers/setup_request_handler.go
index f9c031b..4c49b1d 100644
--- a/E2Manager/handlers/setup_request_handler.go
+++ b/E2Manager/handlers/setup_request_handler.go
@@ -18,10 +18,12 @@
 package handlers
 
 import (
+	"e2mgr/e2pdus"
 	"e2mgr/logger"
 	"e2mgr/rNibWriter"
 	"e2mgr/rnibBuilders"
 	"fmt"
+	"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
 	"os"
 	"sync"
 	"time"
@@ -38,18 +40,12 @@
 	MaxAsn1CodecMessageBufferSize    = 4096
 )
 
-const (
-	shortMacro_eNB_ID = 18
-	macro_eNB_ID      = 20
-	longMacro_eNB_ID  = 21
-	home_eNB_ID       = 28
-)
 
 /*The Ric Id is the combination of pLMNId and ENBId*/
 var pLMNId []byte
 var eNBId []byte
 var eNBIdBitqty uint
-var ricFlag = [3]byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/
+var ricFlag = []byte{0xbb, 0xbc, 0xcc} /*pLMNId [3]bytes*/
 
 type SetupRequestHandler struct {
 	rnibWriterProvider func() rNibWriter.RNibWriter
@@ -62,7 +58,7 @@
 }
 
 func (handler SetupRequestHandler) PreHandle(logger *logger.Logger, details *models.RequestDetails) error {
-	nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details)
+	nodebInfo, nodebIdentity := rnibBuilders.CreateInitialNodeInfo(details, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 
 	rNibErr := handler.rnibWriterProvider().SaveNodeb(nodebIdentity, nodebInfo)
 	if rNibErr != nil {
@@ -78,17 +74,13 @@
 
 	wg.Add(1)
 
-	payload, err := packX2apSetupRequest(logger, MaxAsn1CodecAllocationBufferSize /*allocation buffer*/, MaxAsn1PackedBufferSize /*max packed buffer*/, MaxAsn1CodecMessageBufferSize /*max message buffer*/, pLMNId, eNBId, eNBIdBitqty)
-	if err != nil {
-		logger.Errorf("#setup_request_handler.CreateMessage - pack was failed. Error: %v", err)
-	} else {
-		transactionId := requestDetails.RanName
-		e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails}
-		setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, payload)
+	transactionId := requestDetails.RanName
+	e2sessions[transactionId] = sessions.E2SessionDetails{SessionStart: startTime, Request: requestDetails}
+	setupRequestMessage := models.NewE2RequestMessage(transactionId, requestDetails.RanIp, requestDetails.RanPort, requestDetails.RanName, e2pdus.PackedX2setupRequest)
 
-		logger.Debugf("#setup_request_handler.CreateMessage - setupRequestMessage was created successfully. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage)
-		messageChannel <- setupRequestMessage
-	}
+	logger.Debugf("#setup_request_handler.CreateMessage - PDU: %s", e2pdus.PackedX2setupRequestAsString)
+	logger.Debugf("#setup_request_handler.CreateMessage - setupRequestMessage was created successfully. setup request details(transactionId = [%s]): %+v", transactionId, setupRequestMessage)
+	messageChannel <- setupRequestMessage
 
 	wg.Done()
 }
@@ -110,7 +102,7 @@
 		return fmt.Errorf("invalid value for %s, len(eNBId:%v) != 3 or 4", ENV_RIC_ID, eNBId)
 	}
 
-	if eNBIdBitqty != shortMacro_eNB_ID && eNBIdBitqty != macro_eNB_ID && eNBIdBitqty != longMacro_eNB_ID && eNBIdBitqty != home_eNB_ID {
+	if eNBIdBitqty != e2pdus.ShortMacro_eNB_ID && eNBIdBitqty != e2pdus.Macro_eNB_ID && eNBIdBitqty != e2pdus.LongMacro_eNB_ID && eNBIdBitqty != e2pdus.Home_eNB_ID {
 		return fmt.Errorf("invalid value for %s, eNBIdBitqty: %d", ENV_RIC_ID, eNBIdBitqty)
 	}
 
@@ -123,11 +115,20 @@
 }
 
 func init() {
+	var err error
 	ricId := os.Getenv(ENV_RIC_ID)
 	//ricId="bbbccc-ffff0e/20"
 	//ricId="bbbccc-abcd0e/20"
-	if err := parseRicID(ricId); err != nil {
+	if err = parseRicID(ricId); err != nil {
 		panic(err)
 	}
 
+	e2pdus.PackedEndcX2setupRequest,e2pdus.PackedEndcX2setupRequestAsString, err = e2pdus.PreparePackedEndcX2SetupRequest(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize,pLMNId, eNBId, eNBIdBitqty, ricFlag )
+	if err != nil{
+		panic(err)
+	}
+	e2pdus.PackedX2setupRequest,e2pdus.PackedX2setupRequestAsString, err = e2pdus.PreparePackedX2SetupRequest(MaxAsn1PackedBufferSize, MaxAsn1CodecMessageBufferSize,pLMNId, eNBId, eNBIdBitqty, ricFlag )
+	if err != nil{
+		panic(err)
+	}
 }
diff --git a/E2Manager/handlers/setup_request_handler_test.go b/E2Manager/handlers/setup_request_handler_test.go
index f0de7c4..afd093d 100644
--- a/E2Manager/handlers/setup_request_handler_test.go
+++ b/E2Manager/handlers/setup_request_handler_test.go
@@ -19,6 +19,7 @@
 
 import (
 	"bytes"
+	"e2mgr/e2pdus"
 	"e2mgr/logger"
 	"e2mgr/mocks"
 	"e2mgr/models"
@@ -64,25 +65,25 @@
 			ricId:       "bbbccc-abcd02/18",
 			pLMNId:      []byte{0xbb, 0xbc, 0xcc},
 			eNBId:       []byte{0xab, 0xcd, 0x2}, /*00000010 -> 10000000*/
-			eNBIdBitqty: shortMacro_eNB_ID,
+			eNBIdBitqty: e2pdus.ShortMacro_eNB_ID,
 		},
 		{
 			ricId:       "bbbccc-abcd0e/20",
 			pLMNId:      []byte{0xbb, 0xbc, 0xcc},
 			eNBId:       []byte{0xab, 0xcd, 0xe},
-			eNBIdBitqty: macro_eNB_ID,
+			eNBIdBitqty: e2pdus.Macro_eNB_ID,
 		},
 		{
 			ricId:       "bbbccc-abcd07/21",
 			pLMNId:      []byte{0xbb, 0xbc, 0xcc},
 			eNBId:       []byte{0xab, 0xcd, 0x7}, /*00000111 -> 00111000*/
-			eNBIdBitqty: longMacro_eNB_ID,
+			eNBIdBitqty: e2pdus.LongMacro_eNB_ID,
 		},
 		{
 			ricId:       "bbbccc-abcdef08/28",
 			pLMNId:      []byte{0xbb, 0xbc, 0xcc},
 			eNBId:       []byte{0xab, 0xcd, 0xef, 0x8},
-			eNBIdBitqty: home_eNB_ID,
+			eNBIdBitqty: e2pdus.Home_eNB_ID,
 		},
 		{
 			ricId:   "",
diff --git a/E2Manager/handlers/x2_reset_request_handler.go b/E2Manager/handlers/x2_reset_request_handler.go
index eafd0cc..5964c67 100644
--- a/E2Manager/handlers/x2_reset_request_handler.go
+++ b/E2Manager/handlers/x2_reset_request_handler.go
@@ -32,7 +32,7 @@
 )
 
 const (
-	X2_RESET_ACTIVITIY_NAME = "X2_RESET"
+	X2_RESET_ACTIVITY_NAME = "X2_RESET"
 )
 type X2ResetRequestHandler struct {
 	readerProvider func() reader.RNibReader
@@ -75,7 +75,7 @@
 
 	if nodeb.ConnectionStatus != entities.ConnectionStatus_CONNECTED {
 		logger.Errorf("#reset_request_handler.Handle - RAN: %s in wrong state (%s)", resetRequest.RanName, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
-		return e2managererrors.NewWrongStateError(X2_RESET_ACTIVITIY_NAME,entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
+		return e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME,entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)])
 	}
 
 	response := models.NotificationResponse{MgsType: rmrCgo.RIC_X2_RESET, RanName: resetRequest.RanName, Payload: payload}
diff --git a/E2Manager/handlers/x2_reset_request_handler_test.go b/E2Manager/handlers/x2_reset_request_handler_test.go
index 7027ec4..79dc93e 100644
--- a/E2Manager/handlers/x2_reset_request_handler_test.go
+++ b/E2Manager/handlers/x2_reset_request_handler_test.go
@@ -140,7 +140,7 @@
 
 	actual := handler.Handle(log, models.ResetRequest{RanName: ranName })
 
-	assert.IsType(t, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITIY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]), actual)
+	assert.IsType(t, e2managererrors.NewWrongStateError(X2_RESET_ACTIVITY_NAME, entities.ConnectionStatus_name[int32(nodeb.ConnectionStatus)]), actual)
 
 }
 
diff --git a/E2Manager/handlers/x2apSetupRequest_asn1_packer.go b/E2Manager/handlers/x2apSetupRequest_asn1_packer.go
deleted file mode 100644
index 9c548b0..0000000
--- a/E2Manager/handlers/x2apSetupRequest_asn1_packer.go
+++ /dev/null
@@ -1,54 +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.
-//
-
-package handlers
-
-// #cgo CFLAGS: -I../asn1codec/inc/  -I../asn1codec/e2ap_engine/
-// #cgo LDFLAGS: -L ../asn1codec/lib/ -L../asn1codec/e2ap_engine/ -le2ap_codec -lasncodec
-// #include <asn1codec_utils.h>
-// #include <x2setup_request_wrapper.h>
-import "C"
-import (
-	"e2mgr/logger"
-	"fmt"
-	"github.com/pkg/errors"
-	"unsafe"
-)
-
-func packX2apSetupRequest(logger *logger.Logger, allocationBufferSize int, maxPackedBufferSize int, maxMessageBufferSize int, pLMNId []byte, eNB_Id []byte /*18, 20, 21, 28 bits length*/, bitqty uint) ([]byte, error) {
-	packedBuf := make([]byte, maxPackedBufferSize)
-	errBuf := make([]C.char, maxMessageBufferSize)
-	packedBufSize := C.ulong(len(packedBuf))
-
-	if !C.build_pack_x2setup_request((*C.uchar)(unsafe.Pointer(&pLMNId[0])) /*pLMN_Identity*/,
-		(*C.uchar)(unsafe.Pointer(&eNB_Id[0])), C.uint(bitqty),(*C.uchar)(unsafe.Pointer(&ricFlag[0])) /*pLMN_Identity*/,
-		&packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])), C.ulong(len(errBuf)), &errBuf[0]) {
-		return nil, errors.New(fmt.Sprintf("packing error: %s", C.GoString(&errBuf[0])))
-	}
-
-	if logger.DebugEnabled() {
-		pdu:= C.new_pdu(C.size_t(allocationBufferSize))
-		defer C.delete_pdu(pdu)
-		if C.per_unpack_pdu(pdu, packedBufSize, (*C.uchar)(unsafe.Pointer(&packedBuf[0])),C.size_t(len(errBuf)), &errBuf[0]){
-			C.asn1_pdu_printer(pdu, C.size_t(len(errBuf)), &errBuf[0])
-			logger.Debugf("#x2apSetupRequest_asn1_packer.packX2apSetupRequest - PDU:%s\n\npacked (%d):%x", C.GoString(&errBuf[0]), packedBufSize, packedBuf[:packedBufSize])
-		}
-	}
-	return packedBuf[:packedBufSize], nil
-
-}
-
diff --git a/E2Manager/handlers/x2apSetup_response_notification_handler.go b/E2Manager/handlers/x2apSetup_response_notification_handler.go
index 5e9f674..b69cf58 100644
--- a/E2Manager/handlers/x2apSetup_response_notification_handler.go
+++ b/E2Manager/handlers/x2apSetup_response_notification_handler.go
@@ -51,6 +51,7 @@
 			nb.GlobalNbId = nbIdentity.GlobalNbId
 			nb.RanName = e2session.Request.RanName
 			nb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
+			nb.E2ApplicationProtocol = entities.E2ApplicationProtocol_X2_SETUP_REQUEST
 			nb.Ip = e2session.Request.RanIp
 			nb.Port = uint32(e2session.Request.RanPort)
 			nb.NodeType = entities.Node_ENB
diff --git a/E2Manager/managers/ran_reconnection_manager.go b/E2Manager/managers/ran_reconnection_manager.go
index 328018b..df3467a 100644
--- a/E2Manager/managers/ran_reconnection_manager.go
+++ b/E2Manager/managers/ran_reconnection_manager.go
@@ -45,7 +45,7 @@
 		config:             config,
 		rnibReaderProvider: rnibReaderProvider,
 		rnibWriterProvider: rnibWriterProvider,
-		ranSetupManager:    NewRanSetupManager(logger,rmrService,rnibReaderProvider,rnibWriterProvider),
+		ranSetupManager:    NewRanSetupManager(logger,rmrService,rnibWriterProvider),
 	}
 }
 
diff --git a/E2Manager/managers/ran_setup_manager.go b/E2Manager/managers/ran_setup_manager.go
index ce84468..cb24472 100644
--- a/E2Manager/managers/ran_setup_manager.go
+++ b/E2Manager/managers/ran_setup_manager.go
@@ -18,28 +18,101 @@
 package managers
 
 import (
+	"e2mgr/e2managererrors"
+	"e2mgr/e2pdus"
 	"e2mgr/logger"
+	"e2mgr/models"
 	"e2mgr/rNibWriter"
+	"e2mgr/rmrCgo"
 	"e2mgr/services"
 	"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
-	"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
 )
 
 type RanSetupManager struct {
 	logger             *logger.Logger
-	rnibReaderProvider func() reader.RNibReader
 	rnibWriterProvider func() rNibWriter.RNibWriter
 	rmrService         *services.RmrService
 }
 
-func NewRanSetupManager(logger *logger.Logger, rmrService *services.RmrService, rnibReaderProvider func() reader.RNibReader, rnibWriterProvider func() rNibWriter.RNibWriter) *RanSetupManager {
+func NewRanSetupManager(logger *logger.Logger, rmrService *services.RmrService, rnibWriterProvider func() rNibWriter.RNibWriter) *RanSetupManager {
 	return &RanSetupManager{
 		logger:             logger,
-		rnibReaderProvider: rnibReaderProvider,
 		rnibWriterProvider: rnibWriterProvider,
+		rmrService        : rmrService,
 	}
 }
 
+
+// Update retries and connection status (connecting)
+func (m *RanSetupManager) updateConnectionStatusConnecting(nodebInfo *entities.NodebInfo) error {
+	// Update retries and connection status (connecting)
+	nodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTING
+	nodebInfo.ConnectionAttempts++
+	err:= m.rnibWriterProvider().UpdateNodebInfo(nodebInfo)
+	if err != nil {
+		m.logger.Errorf("#ran_setup_manager.updateConnectionStatusConnecting - failed to update RAN's connection status to CONNECTING: %s", err)
+	} else {
+		m.logger.Infof("#ran_setup_manager.updateConnectionStatusConnecting - successfully updated RAN's connection status to CONNECTING: %s", err)
+	}
+	return err
+}
+
+// Decrement retries and connection status (disconnected)
+func (m *RanSetupManager) updateConnectionStatusDisconnected(nodebInfo *entities.NodebInfo) error {
+	// Update retries and connection status (connecting)
+	nodebInfo.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
+	nodebInfo.ConnectionAttempts--
+	err := m.rnibWriterProvider().UpdateNodebInfo(nodebInfo)
+	if err != nil {
+		m.logger.Errorf("#ran_setup_manager.updateConnectionStatusDisconnected - failed to update RAN's connection status to DISCONNECTED : %s", err)
+	} else {
+		m.logger.Errorf("#ran_setup_manager.updateConnectionStatusDisconnected - successfully updated RAN's connection status to DISCONNECTED : %s", err)
+	}
+	return err
+}
+
+func (m *RanSetupManager) prepareSetupRequest(nodebInfo *entities.NodebInfo) (int, *models.E2RequestMessage, error) {
+	// Build the endc/x2 setup request
+	switch nodebInfo.E2ApplicationProtocol {
+	case entities.E2ApplicationProtocol_X2_SETUP_REQUEST:
+		rmrMsgType := rmrCgo.RIC_X2_SETUP_REQ
+		request := models.NewE2RequestMessage(nodebInfo.RanName /*tid*/, nodebInfo.Ip, uint16(nodebInfo.Port), nodebInfo.RanName, e2pdus.PackedX2setupRequest)
+		return rmrMsgType, request, nil
+	case entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST:
+		rmrMsgType := rmrCgo.RIC_ENDC_X2_SETUP_REQ
+		request:= models.NewE2RequestMessage(nodebInfo.RanName /*tid*/, nodebInfo.Ip, uint16(nodebInfo.Port), nodebInfo.RanName, e2pdus.PackedEndcX2setupRequest)
+		return rmrMsgType, request, nil
+	}
+
+	m.logger.Errorf("#ran_setup_manager.ExecuteSetup - unsupported nodebInfo.E2ApplicationProtocol %d ", nodebInfo.E2ApplicationProtocol)
+	return 0, nil, e2managererrors.NewInternalError()
+}
+
+// ExecuteSetup updates the connection status and number of attempts in the nodebInfo and send an endc/x2 setup request to establish a connection with the RAN
 func (m *RanSetupManager) ExecuteSetup(nodebInfo *entities.NodebInfo) error {
+
+	// Update retries and connection status (connecting)
+	if err := m.updateConnectionStatusConnecting(nodebInfo); err != nil {
+		return e2managererrors.NewRnibDbError()
+	}
+
+	// Build the endc/x2 setup request
+	rmrMsgType,request, err := m.prepareSetupRequest(nodebInfo)
+	if err != nil {
+		return err
+	}
+	
+	// Send the endc/x2 setup request
+	response := &models.NotificationResponse{MgsType: rmrMsgType, RanName: nodebInfo.RanName, Payload: request.GetMessageAsBytes(m.logger)}
+	if err := m.rmrService.SendRmrMessage(response); err != nil {
+		m.logger.Errorf("#ran_setup_manager.ExecuteSetup - failed to send setup request to RMR: %s", err)
+
+		// Decrement retries and connection status (disconnected)
+		if err := m.updateConnectionStatusDisconnected(nodebInfo); err != nil {
+			return e2managererrors.NewRnibDbError()
+		}
+
+		return e2managererrors.NewRmrError()
+	}
 	return nil
 }
diff --git a/E2Manager/managers/ran_setup_manager_test.go b/E2Manager/managers/ran_setup_manager_test.go
new file mode 100644
index 0000000..2b1906b
--- /dev/null
+++ b/E2Manager/managers/ran_setup_manager_test.go
@@ -0,0 +1,213 @@
+//
+// 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.
+//
+
+package managers
+
+import (
+	"e2mgr/e2managererrors"
+	"e2mgr/e2pdus"
+	"e2mgr/logger"
+	"e2mgr/mocks"
+	"e2mgr/rNibWriter"
+	"e2mgr/rmrCgo"
+	"fmt"
+	"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
+	"gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/mock"
+	"testing"
+)
+
+func TestExecuteSetupConnectingX2Setup(t *testing.T) {
+	log := initLog(t)
+
+	ranName := "test1"
+
+
+	writerMock := &mocks.RnibWriterMock{}
+	writerProvider := func() rNibWriter.RNibWriter {
+		return writerMock
+	}
+
+	var initialNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+	var argNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 }
+	var rnibErr common.IRNibError
+	writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr)
+
+	payload:= e2pdus.PackedX2setupRequest
+	xaction := []byte(ranName)
+	msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+	rmrMessengerMock := &mocks.RmrMessengerMock{}
+	rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,nil)
+	rmrService:= getRmrService(rmrMessengerMock, log)
+
+	mgr := NewRanSetupManager(log, rmrService, writerProvider)
+	if err:= mgr.ExecuteSetup(initialNodeb); err != nil {
+		t.Errorf("want: success, got: error: %s", err)
+	}
+
+	writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+	rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+}
+
+
+func TestExecuteSetupConnectingEndcX2Setup(t *testing.T) {
+	log := initLog(t)
+
+	ranName := "test1"
+
+
+	writerMock := &mocks.RnibWriterMock{}
+	writerProvider := func() rNibWriter.RNibWriter {
+		return writerMock
+	}
+
+	var initialNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST}
+	var argNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, ConnectionAttempts: 1 }
+	var rnibErr common.IRNibError
+	writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr)
+
+	payload:= e2pdus.PackedEndcX2setupRequest
+	xaction := []byte(ranName)
+	msg:= rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+	rmrMessengerMock := &mocks.RmrMessengerMock{}
+	rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,nil)
+	rmrService:= getRmrService(rmrMessengerMock, log)
+
+	mgr := NewRanSetupManager(log, rmrService, writerProvider)
+	if err:= mgr.ExecuteSetup(initialNodeb); err != nil {
+		t.Errorf("want: success, got: error: %s", err)
+	}
+
+	writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+	rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+}
+
+func TestExecuteSetupDisconnected(t *testing.T) {
+	log := initLog(t)
+
+	ranName := "test1"
+
+	writerMock := &mocks.RnibWriterMock{}
+	writerProvider := func() rNibWriter.RNibWriter {
+		return writerMock
+	}
+
+	var initialNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+	var argNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 }
+	var argNodebDisconnected = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 0 }
+	var rnibErr common.IRNibError
+	writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr)
+	writerMock.On("UpdateNodebInfo",argNodebDisconnected).Return(rnibErr)
+
+	payload:= []byte {0}
+	xaction := []byte(ranName)
+	msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+	rmrMessengerMock := &mocks.RmrMessengerMock{}
+	rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,fmt.Errorf("send failure"))
+	rmrService:= getRmrService(rmrMessengerMock, log)
+
+	mgr := NewRanSetupManager(log, rmrService,  writerProvider)
+	if err:= mgr.ExecuteSetup(initialNodeb); err == nil {
+		t.Errorf("want: failure, got: success")
+	}
+
+	writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
+	rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+}
+
+func TestExecuteSetupConnectingRnibError(t *testing.T) {
+	log := initLog(t)
+
+	ranName := "test1"
+
+	writerMock := &mocks.RnibWriterMock{}
+	writerProvider := func() rNibWriter.RNibWriter {
+		return writerMock
+	}
+
+	var initialNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+	var argNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 }
+	var argNodebDisconnected = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 0 }
+	var rnibErr = common.NewInternalError(fmt.Errorf("DB error"))
+	writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr)
+	writerMock.On("UpdateNodebInfo",argNodebDisconnected).Return(rnibErr)
+
+	payload:= []byte {0}
+	xaction := []byte(ranName)
+	msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+	rmrMessengerMock := &mocks.RmrMessengerMock{}
+	rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,fmt.Errorf("send failure"))
+	rmrService:= getRmrService(rmrMessengerMock, log)
+
+	mgr := NewRanSetupManager(log, rmrService, writerProvider)
+	if err:= mgr.ExecuteSetup(initialNodeb); err == nil {
+		t.Errorf("want: failure, got: success")
+	} else {
+		assert.IsType(t, e2managererrors.NewRnibDbError(), err)
+	}
+
+
+	writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 1)
+	rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
+}
+
+func TestExecuteSetupDisconnectedRnibError(t *testing.T) {
+	log := initLog(t)
+
+	ranName := "test1"
+
+	writerMock := &mocks.RnibWriterMock{}
+	writerProvider := func() rNibWriter.RNibWriter {
+		return writerMock
+	}
+
+	var initialNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
+	var argNodeb = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 1 }
+	var argNodebDisconnected = &entities.NodebInfo{ConnectionStatus:  entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, ConnectionAttempts: 0 }
+	var rnibErr common.IRNibError
+	writerMock.On("UpdateNodebInfo",argNodeb).Return(rnibErr)
+	writerMock.On("UpdateNodebInfo",argNodebDisconnected).Return(common.NewInternalError(fmt.Errorf("DB error")))
+
+	payload:= []byte {0}
+	xaction := []byte(ranName)
+	msg:= rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xaction)
+	rmrMessengerMock := &mocks.RmrMessengerMock{}
+	rmrMessengerMock.On("SendMsg",mock.Anything,mock.Anything).Return(msg,fmt.Errorf("send failure"))
+	rmrService:= getRmrService(rmrMessengerMock, log)
+
+	mgr := NewRanSetupManager(log, rmrService,  writerProvider)
+	if err:= mgr.ExecuteSetup(initialNodeb); err == nil {
+		t.Errorf("want: failure, got: success")
+	} else {
+		assert.IsType(t, e2managererrors.NewRnibDbError(), err)
+	}
+
+	writerMock.AssertNumberOfCalls(t, "UpdateNodebInfo", 2)
+	rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
+}
+
+
+func initLog(t *testing.T) *logger.Logger {
+	log, err := logger.InitLogger(logger.InfoLevel)
+	if err != nil {
+		t.Errorf("#initLog test - failed to initialize logger, error: %s", err)
+	}
+	return log
+}
+
+
diff --git a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go
index f65dee3..159c44d 100644
--- a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go
+++ b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider.go
@@ -49,6 +49,7 @@
 		rmrCgo.RIC_ENDC_CONF_UPDATE:        handlers.EndcConfigurationUpdateHandler{},
 		rmrCgo.RIC_X2_RESET_RESP:           handlers.NewX2ResetResponseHandler(rnibReaderProvider),
 		rmrCgo.RIC_X2_RESET:                handlers.NewX2ResetRequestNotificationHandler(rnibReaderProvider),
+		rmrCgo.RIC_E2_TERM_INIT:            handlers.NewE2TermInitNotificationHandler(ranReconnectionManager, rnibReaderProvider ),
 	}
 }
 
diff --git a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go
index a2a814d..66f2e36 100644
--- a/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go
+++ b/E2Manager/providers/rmrmsghandlerprovider/notification_handler_provider_test.go
@@ -68,6 +68,7 @@
 		{rmrCgo.RIC_ENB_LOAD_INFORMATION, handlers.NewEnbLoadInformationNotificationHandler(rnibWriterProvider)},
 		{rmrCgo.RIC_ENB_CONF_UPDATE, handlers.X2EnbConfigurationUpdateHandler{}},
 		{rmrCgo.RIC_ENDC_CONF_UPDATE, handlers.EndcConfigurationUpdateHandler{}},
+		{rmrCgo.RIC_E2_TERM_INIT,    handlers.NewE2TermInitNotificationHandler(ranReconnectionManager, rnibReaderProvider)},
 	}
 
 	for _, tc := range testCases {
diff --git a/E2Manager/rmrCgo/rmrCgoTypes.go b/E2Manager/rmrCgo/rmrCgoTypes.go
index e37b97b..441ed9f 100644
--- a/E2Manager/rmrCgo/rmrCgoTypes.go
+++ b/E2Manager/rmrCgo/rmrCgoTypes.go
@@ -67,6 +67,7 @@
 	RIC_SCTP_CLEAR_ALL                   = C.RIC_SCTP_CLEAR_ALL
 	RIC_X2_RESET_RESP                    = C.RIC_X2_RESET_RESP
 	RIC_X2_RESET                         = C.RIC_X2_RESET
+	RIC_E2_TERM_INIT 					 = C.E2_TERM_INIT
 )
 
 const (
diff --git a/E2Manager/rnibBuilders/node_info_builder.go b/E2Manager/rnibBuilders/node_info_builder.go
index 53c3411..3595d79 100644
--- a/E2Manager/rnibBuilders/node_info_builder.go
+++ b/E2Manager/rnibBuilders/node_info_builder.go
@@ -22,11 +22,12 @@
 	"e2mgr/models"
 )
 
-func CreateInitialNodeInfo(requestDetails *models.RequestDetails) (*entities.NodebInfo, *entities.NbIdentity) {
+func CreateInitialNodeInfo(requestDetails *models.RequestDetails, protocol entities.E2ApplicationProtocol) (*entities.NodebInfo, *entities.NbIdentity) {
 	nodebInfo := &entities.NodebInfo{}
 	nodebInfo.Ip = requestDetails.RanIp
 	nodebInfo.Port = uint32(requestDetails.RanPort)
 	nodebInfo.ConnectionStatus = entities.ConnectionStatus_CONNECTING
+	nodebInfo.E2ApplicationProtocol = protocol
 	nodebInfo.RanName = requestDetails.RanName
 
 	nodebIdentity := &entities.NbIdentity{}
diff --git a/E2Manager/rnibBuilders/node_info_builder_test.go b/E2Manager/rnibBuilders/node_info_builder_test.go
index 40c0d1b..e95f12d 100644
--- a/E2Manager/rnibBuilders/node_info_builder_test.go
+++ b/E2Manager/rnibBuilders/node_info_builder_test.go
@@ -34,9 +34,10 @@
 		RanPort:ranPort,
 		RanIp:ranIP,
 	}
-	nodebInfo, identity := CreateInitialNodeInfo(requestDetails)
+	nodebInfo, identity := CreateInitialNodeInfo(requestDetails, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 	assert.Equal(t, identity.InventoryName, ranName)
 	assert.Equal(t, nodebInfo.Ip, ranIP)
 	assert.Equal(t, nodebInfo.ConnectionStatus, entities.ConnectionStatus_CONNECTING)
+	assert.Equal(t, nodebInfo.E2ApplicationProtocol, entities.E2ApplicationProtocol_X2_SETUP_REQUEST)
 	assert.Equal(t, nodebInfo.Port, uint32(ranPort))
 }
\ No newline at end of file
diff --git a/router.txt b/router.txt
index 0a643f9..b80e438 100644
--- a/router.txt
+++ b/router.txt
@@ -13,5 +13,5 @@
 rte|10080|10.0.2.15:3801
 rte|10081|10.0.2.15:38000
 rte|10082|10.0.2.15:38000
-
+rte|1100|10.0.2.15:3801
 newrt|end