E2AP and E2SM-RC version upgrade to E2aP v.2.0 and E2SM-RC to v1.0.1

Signed-off-by: rajalakshmisv <rajalakshmisv@gmail.com>
Change-Id: I241726da02e3aea69f3cc3e127a47455b778c1e6
diff --git a/control/rcControl.go b/control/rcControl.go
index 41cfc92..5bf5994 100644
--- a/control/rcControl.go
+++ b/control/rcControl.go
@@ -3,13 +3,14 @@
 import (

 	"errors"

 	"fmt"

-	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"

-	"gerrit.o-ran-sc.org/r/ric-app/rc/protocol/grpc/ricmsgcommrpc/rc"

 	"log"

 	"os"

 	"strconv"

 	"sync"

 	"time"

+

+	"gerrit.o-ran-sc.org/r/ric-app/rc/protocol/grpc/ricmsgcommrpc/rc"

+	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"

 )

 

 var (

@@ -33,6 +34,12 @@
 	xapp.Logger.Debug("GRPC Server Port = %v ", xapp.Config.GetString("controls.ricHOControlgRpcServerPort"))

 	xapp.Logger.Debug("Log Level = %d ", xapp.Config.GetInt("controls.logLevel"))

 

+	go StartgRPCRCControlCommServerRoutine()

+	xapp.Logger.Debug("StartgRPCRCControlCommServerRoutine done")

+

+	//To Handle RIC Control Message

+	go StartHandleControlReqRoutine()

+

 	return Control{5,

 		make(chan *xapp.RMRParams, 1000), //Make it configurable

 		make(map[int]bool),

@@ -42,17 +49,7 @@
 

 func ReadyCB(i interface{}) {

 	gControlData = i.(*Control)

-

 	go controlLoop()

-

-	//Start gRPC Server for Receiving messages

-

-	go StartgRPCRCControlCommServerRoutine()

-	xapp.Logger.Info("StartgRPCRCControlCommServerRoutine done")

-

-	//To Handle RIC Control Message

-	go StartHandleControlReqRoutine()

-

 }

 

 func (aControlData *Control) Run() {

@@ -68,7 +65,7 @@
 func (aControlData *Control) rmrSend(params *xapp.RMRParams) (err error) {

 	if !xapp.Rmr.Send(params, false) {

 		err = errors.New("rmr.Send() failed")

-		xapp.Logger.Error("Failed to rmrSend to %v", err)

+		xapp.Logger.Info("Failed to rmrSend to %v", err)

 		log.Printf("Failed to rmrSend to %v", err)

 	}

 	return

@@ -113,21 +110,28 @@
 

 func HandlegRPCRICControlMsgReq(aPtrRicControlGrpcReq *rc.RicControlGrpcReq) {

 

+	xapp.Logger.Debug("HandlegRPCRICControlMsgReq :%v", *aPtrRicControlGrpcReq)

 	lRicHoControlMsg := RicHoControlMsg{}

 	lRicHoControlMsg.RicControlGrpcReqPtr = aPtrRicControlGrpcReq

 

 	lUEID := lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID

-	xapp.Logger.Debug("HandlegRPCRICControlMsgReq UEID = %s ", lUEID)

-        //Mandatory parameters validation

-        if lRicHoControlMsg.RicControlGrpcReqPtr.E2NodeID == "" ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID == "" ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID == "" ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.PlmnID == "" ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlActionId < 0 ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlStyle < 0 ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.RICControlCellTypeVal < 0 ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RICRequestorID < 0 ||

-                lRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RanFuncId < 0 {

+	xapp.Logger.Debug("HandlegRPCRICControlMsgReq UEID = %v ", lUEID)

+	//Mandatory parameters validation

+	if lRicHoControlMsg.RicControlGrpcReqPtr.E2NodeID == "" ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID == "" ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.AmfUENGAPID < 0 ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.PLMNIdentity == "" ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.AMFRegionID == "" ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.AMFSetID == "" ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.Guami.AMFPointer == "" ||

+		len(lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.GNBCUUEF1APID) == 0 ||

+		len(lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID.GnbUEID.GNBCUCPUEE1APID) == 0 ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.PlmnID == "" ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlActionId < 0 ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlStyle < 0 ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.RICControlCellTypeVal < 0 ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RICRequestorID < 0 ||

+		lRicHoControlMsg.RicControlGrpcReqPtr.RICE2APHeaderData.RanFuncId < 0 {

 		xapp.Logger.Error("Mandaroty parameters missing, dont send control request ")

 		return

 	}

@@ -154,8 +158,10 @@
 	gControlData.eventRicControlReqExpiredMu.Lock()

 	gControlData.eventRicControlReqExpiredMap[aSeqNum] = false

 	gControlData.eventRicControlReqExpiredMu.Unlock()

+	controlAckTimer := xapp.Config.GetInt("controls.controlAckTimer")

+	xapp.Logger.Debug("configured controlAckTimer = %d and controlAckTimer = %d ", xapp.Config.GetInt("controls.controlAckTimer"),controlAckTimer)

 

-	timer := time.NewTimer(time.Duration(gControlData.eventRicControlReqTimePeriod) * time.Second)

+	timer := time.NewTimer(time.Duration(controlAckTimer) * time.Second)

 	go func(t *time.Timer) {

 		defer t.Stop()

 		xapp.Logger.Debug("RIC_CONTROL_REQ[%s]: Waiting for RIC_CONTROL_RESP...", aSeqNum)

@@ -204,15 +210,23 @@
 	var lRicControlActionID int64 = aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.ControlActionId

 	lUEID := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID

 

-	lUeIdBuf := []byte(aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

+	var ueId_data UEid

 

-	xapp.Logger.Debug("UEID:%s, lUeIdBuf: %v", aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID, lUeIdBuf)

+	xapp.Logger.Debug("UEID:%v, ueId_data strct :%v", aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID,

+		ueId_data)

+	ueId_data.amf_UE_NGAP_Id = lUEID.GnbUEID.AmfUENGAPID

+	ueId_data.pLMNIdentitybuf = lUEID.GnbUEID.Guami.PLMNIdentity

+        ueId_data.aMFRegionIDbuf = lUEID.GnbUEID.Guami.AMFRegionID

+        ueId_data.aMFSetIDbuf = lUEID.GnbUEID.Guami.AMFSetID

+        ueId_data.aMFPointerbuf = lUEID.GnbUEID.Guami.AMFPointer

+        ueId_data.F1AP_id = lUEID.GnbUEID.GNBCUUEF1APID

+        ueId_data.E1AP_id = lUEID.GnbUEID.GNBCUCPUEE1APID

 

-	var lRicControlHeader []byte = make([]byte, 256) //Check the Size

-	lRicControlHeaderEncoded, err := e2sm.SetRicControlHeader(lRicControlHeader, lUeIdBuf, lRicControlStyleType, lRicControlActionID)

+	var lRicControlHeader []byte = make([]byte, 1024) //Check the Size

+	lRicControlHeaderEncoded, err := e2sm.SetRicControlHeader(lRicControlHeader, &ueId_data, lRicControlStyleType, lRicControlActionID)

 	if err != nil {

-		xapp.Logger.Error("SetRicControlHeader Failed: %v, UEID:%s", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

-		log.Printf("SetRicControlHeader Failed: %v, UEID:%s", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

+		xapp.Logger.Error("SetRicControlHeader Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

+		log.Printf("SetRicControlHeader Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

 		return err

 	} else {

 		xapp.Logger.Info("SetRicControlHeader is success: %x", lRicControlHeaderEncoded)

@@ -222,7 +236,6 @@
 		}

 		fmt.Fprintf(os.Stderr, "\n")

 	}

-

 	var lTargetPrimaryCell int64 = RIC_CONTROL_TARGET_PRIMARY_CELL

 	var lTargetCell int64 = RIC_CONTROL_TARGET_CELL

 	var lNrCGIOrECGI int64 = RIC_CONTROL_CGI_TYPE

@@ -230,12 +243,15 @@
 	lNrOrEUtraCellType := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.RICControlCellTypeVal

 	lTargetCellVal := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID

 	lTargetCellValBuf := []byte(lTargetCellVal)

+	//lNRPlmnId := []byte(aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID.PlmnID)

+        //lNRCellId := aRicHoControlMsg.RicControlGrpcReqPtr.RICControlMessageData.TargetCellID.NRCellID

 

-	var lRicControlMessage []byte = make([]byte, 1024) 

+

+	var lRicControlMessage []byte = make([]byte, 1024)

 	lRicControlMessageEncoded, err := e2sm.SetRicControlMessage(lRicControlMessage, lTargetPrimaryCell, lTargetCell, lNrCGIOrECGI, int64(lNrOrEUtraCellType), lTargetCellValBuf)

 	if err != nil {

-		xapp.Logger.Error("SetRicControlMessage Failed: %v, UEID:%s", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

-		log.Printf("SetRicControlMessage Failed: %v, UEID:%s", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

+		xapp.Logger.Error("SetRicControlMessage Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

+		log.Printf("SetRicControlMessage Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

 		return err

 	} else {

 		xapp.Logger.Debug("SetRicControlMessage is success: %x", lRicControlMessageEncoded)

@@ -257,45 +273,85 @@
 	lParams.Payload, err = e2ap.SetRicControlRequestPayload(lParams.Payload, lRequestorId, uint16(aRequestSN), lFuncId,

 		lRicControlHeaderEncoded, lRicControlMessageEncoded)

 	if err != nil {

-		xapp.Logger.Error("SetRicControlRequestPayload Failed: %v, UEID:%s", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

-		log.Printf("SetRicControlRequestPayload Failed: %v, UEID:%s", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

+		xapp.Logger.Error("SetRicControlRequestPayload Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

+		log.Printf("SetRicControlRequestPayload Failed: %v, UEID:%v", err, aRicHoControlMsg.RicControlGrpcReqPtr.RICControlHeaderData.UEID)

 		return err

 	} else {

-		xapp.Logger.Debug("Encoding RicControlRequestPayload is success. UEID: %s, Payload: %x", lUEID, lParams.Payload)

+

+		xapp.Logger.Debug("Encoding RicControlRequestPayload is success. UEID: %v, Payload: %x", lUEID, lParams.Payload)

 		fmt.Fprintf(os.Stderr, "Encoded RIC Control Req PDU:\n")

 		for i := 0; i < len(lParams.Payload); i++ {

 			fmt.Fprintf(os.Stderr, " %02x", lParams.Payload[i])

 		}

 		fmt.Fprintf(os.Stderr, "\n")

 	}

-

+	lParams.PayloadLen = len(lParams.Payload)

 	valEnbId := aRicHoControlMsg.RicControlGrpcReqPtr.E2NodeID

 	valRanName := aRicHoControlMsg.RicControlGrpcReqPtr.RanName

 	valPlmnId := aRicHoControlMsg.RicControlGrpcReqPtr.PlmnID

 	lParams.Meid = &xapp.RMRMeid{PlmnID: valPlmnId, EnbID: valEnbId, RanName: valRanName}

 

-	xapp.Logger.Debug("The RIC Control RMR message to be sent is with MsgType:%d  SubId=%d, lParams.Meid: %v, UEID: %s", lParams.Mtype, lParams.SubId, lParams.Meid, lUEID)

+	xapp.Logger.Debug("The RIC Control RMR message to be sent is with MsgType:%d  SubId=%d, lParams.Meid: %v, UEID: %v", lParams.Mtype, lParams.SubId, lParams.Meid, lUEID)

 

-	xapp.Logger.Debug("Sending RIC Control message to RanName: %s, UEID: %s  ", aRicHoControlMsg.RicControlGrpcReqPtr.RanName, lUEID)

-

+	xapp.Logger.Debug("Sending RIC Control message to RanName: %s, UEID: %v  ", aRicHoControlMsg.RicControlGrpcReqPtr.RanName, lUEID)

+	

+	xapp.Logger.Info("lParams %v ",lParams)

 	err = gControlData.rmrSend(lParams)

 	if err != nil {

 		xapp.Logger.Error("Failed to send RIC_CONTROL_REQ: %v", err)

 		log.Printf("Failed to send RIC_CONTROL_REQ: %v", err)

+		xapp.Logger.Info("Failed to send RIC_CONTROL_REQ: %v", err)

 		return err

 	}

 

-	xapp.Logger.Info("Sending RIC Control message to RanName: %s, UEID: %s  Success", aRicHoControlMsg.RicControlGrpcReqPtr.RanName, lUEID)

-

+	xapp.Logger.Info("Sending RIC Control message to RanName: %s, UEID: %v  Success", aRicHoControlMsg.RicControlGrpcReqPtr.RanName, lUEID)

+	//Start Timer Operation.

 	aRicHoControlMsg.setEventRicControlCreateExpiredTimer(aRequestSN) //TODO check if this is required as we are not expecting Control ACK

 

 	return nil

 }

 

 func HandleControlResponse(params *xapp.RMRParams) (err error) {

+

+	var e2ap *E2ap

+        var e2sm *E2sm

 	xapp.Logger.Debug("The SubId in RIC_CONTROL_RESP is %d", params.SubId)

 	log.Printf("The SubId in RIC_CONTROL_RESP is %d", params.SubId)

 

+

+

+	//Decode the RIC Control Ack message

+	controlAck, err := e2ap.GetControlAckMsg(params.Payload)

+	if err != nil {

+		xapp.Logger.Error("Failed to decode RIC Control Ack: %v", err)

+                log.Println("Failed to decode RIC Control Ack: %v", err)

+                return

+	}

+	log.Println("E2ap RIC RIC Control Ack message decoded \n")

+	xapp.Logger.Info("E2ap RIC RIC Control Ack message decoded \n")

+	gControlData.eventRicControlReqExpiredMu.Lock()

+        _,ok := gControlData.eventRicControlReqExpiredMap[int(controlAck.InstanceId)]

+        if !ok {

+                gControlData.eventRicControlReqExpiredMu.Unlock()

+                xapp.Logger.Debug("RIC_CONTROL_REQ has been deleted!")

+                log.Printf("RIC_CONTROL_REQ has been deleted!")

+                return nil

+        } else {

+                gControlData.eventRicControlReqExpiredMap[int(controlAck.InstanceId)] = true

+		gControlData.eventRicControlReqExpiredMu.Unlock()

+        }

+

+	controlOutcome, err := e2sm.GetControlOutcome(controlAck.ControlOutcome)

+        if err != nil {

+		xapp.Logger.Error("Failed to decode RIC Control Outcome: %v", err)

+                log.Println("Failed to decode RIC Control Outcome: %v", err)

+                return

+        }

+        log.Println("E2SM-RC RIC Control Outcome  decoded \n",controlOutcome)

+        xapp.Logger.Info("E2SM-RC RIC Control Outcome  decoded \n",controlOutcome)

+

+

+

 	return nil

 }

 

diff --git a/control/rcControlUtils.go b/control/rcControlUtils.go
new file mode 100644
index 0000000..c0efda1
--- /dev/null
+++ b/control/rcControlUtils.go
@@ -0,0 +1,58 @@
+package control
+
+import (
+	_ "strconv"
+	_ "time"
+)
+
+func get_bytepack_plmnId(lInPlmnId []byte) []byte {
+
+var tmpPlmnId []byte
+var bytePackedPlmnId []byte
+
+tmpPlmnId = make([]byte, 6)
+bytePackedPlmnId = make([]byte, 3)
+
+num_mnc_digits := len(lInPlmnId)
+
+tmpPlmnId[0] = lInPlmnId[0]
+tmpPlmnId[1] = lInPlmnId[1]
+tmpPlmnId[2] = lInPlmnId[2]
+
+if num_mnc_digits == 5 {
+tmpPlmnId[3] = 0x0f
+tmpPlmnId[4] = lInPlmnId[3]
+tmpPlmnId[5] = lInPlmnId[4]
+} else {
+tmpPlmnId[3] = lInPlmnId[3]
+tmpPlmnId[4] = lInPlmnId[4]
+tmpPlmnId[5] = lInPlmnId[5]
+}
+bytePackedPlmnId[0] = ((tmpPlmnId[1] & 0x0F) << 4) | (tmpPlmnId[0] & 0x0F)
+bytePackedPlmnId[1] = ((tmpPlmnId[3] & 0x0F) << 4) | (tmpPlmnId[2] & 0x0F)
+bytePackedPlmnId[2] = ((tmpPlmnId[5] & 0x0F) << 4) | (tmpPlmnId[4] & 0x0F)
+
+return bytePackedPlmnId
+}
+
+func ConverIntegerToByte(lIntVar int) []byte {
+var rightMost, tempIntVar int
+var byteArray []byte
+tempIntVar = lIntVar
+for {
+rightMost = tempIntVar % 10
+byteArray = append(byteArray, byte(rightMost)) // convert single digit to byte
+tempIntVar /= 10
+if tempIntVar == 0 {
+break
+}
+}
+// need to reverse the order
+fixByteArray := []byte{}
+for i := range byteArray {
+n := byteArray[len(byteArray)-1-i]
+fixByteArray = append(fixByteArray, n)
+}
+
+return fixByteArray
+}
diff --git a/control/rcE2AP.go b/control/rcE2AP.go
index ee3db21..e305125 100644
--- a/control/rcE2AP.go
+++ b/control/rcE2AP.go
@@ -40,3 +40,24 @@
 	return
 }
 
+
+func (c *E2ap) GetControlAckMsg(payload []byte) (decodedMsg *ControlAckMsg, err error) {
+        cptr := unsafe.Pointer(&payload[0])
+        decodedMsg = &ControlAckMsg{}
+        decodedCMsg := C.e2ap_decode_ric_control_acknowledge_message(cptr, C.size_t(len(payload)))
+        if decodedCMsg == nil {
+                return decodedMsg, errors.New("e2ap wrapper is unable to decode indication message due to wrong or invalid payload")
+        }
+        defer C.e2ap_free_decoded_ric_control_ack(decodedCMsg)
+
+        decodedMsg.RequestID = int32(decodedCMsg.requestorID)
+        decodedMsg.InstanceId = int32(decodedCMsg.instanceID)
+        decodedMsg.FuncID = int32(decodedCMsg.ranfunctionID)
+        callproc := unsafe.Pointer(decodedCMsg.callProcessID)
+        decodedMsg.CallProcessID = C.GoBytes(callproc, C.int(decodedCMsg.callProcessIDSize))
+        decodedMsg.CallProcessIDLength = int32(decodedCMsg.callProcessIDSize)
+        controlOutcome := unsafe.Pointer(decodedCMsg.ricControlOutCome)
+        decodedMsg.ControlOutcome = C.GoBytes(controlOutcome, C.int(decodedCMsg.ricControlOutComeSize))
+        decodedMsg.ControlOutcomeLength = int32(decodedCMsg.ricControlOutComeSize)
+        return
+}
diff --git a/control/rcE2SmRc.go b/control/rcE2SmRc.go
index 502f017..e2a8498 100644
--- a/control/rcE2SmRc.go
+++ b/control/rcE2SmRc.go
@@ -11,17 +11,67 @@
 	"errors"
 	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
 	"unsafe"
+	_ "log"
+	_"encoding/binary"
+	"encoding/hex"
+	"strings"
+	"strconv"
 )
 
 type E2sm struct {
 }
 
-func (c *E2sm) SetRicControlHeader(buffer []byte, ueIDbuf []byte, ricControlStyleType int64, ricControlActionID int64) (newBuffer []byte, err error) {
-	cptr := unsafe.Pointer(&buffer[0])
-	cptr_ueIDbuf := unsafe.Pointer(&ueIDbuf[0])
-	size := C.e2sm_encode_ric_control_header(cptr, C.size_t(len(buffer)), cptr_ueIDbuf, C.size_t(len(ueIDbuf)),
-		C.long(ricControlStyleType), C.long(ricControlActionID))
+func (c *E2sm) SetRicControlHeader(buffer []byte, ueIdData *UEid, ricControlStyleType int64, ricControlActionID int64) (newBuffer []byte, err error) {
 
+	xapp.Logger.Info("SetRicControlHeader Enter \n")
+	cptr := unsafe.Pointer(&buffer[0])
+	//cptr_ueIDbuf := unsafe.Pointer(&ueIDbuf[0])
+
+	lplmnIdBuf := strings.Join(strings.Fields(ueIdData.pLMNIdentitybuf), "")
+	lIntvar, _ := strconv.Atoi(lplmnIdBuf)
+	xapp.Logger.Info("lIntvar = %d\n", lIntvar)
+
+	lIntegerByte := ConverIntegerToByte(lIntvar)
+	//ml.MavLog(ml.INFO, lTransId, " lIntegerByte = %v\n", lIntegerByte)
+	xapp.Logger.Info(" lIntegerByte = %v\n", lIntegerByte)
+        lOutByte := get_bytepack_plmnId(lIntegerByte)
+        xapp.Logger.Info("lOutByte Len:%d\n", len(lOutByte))
+        xapp.Logger.Info("lOutByte = %02X\n", lOutByte)
+	cptrRanParameterValue := unsafe.Pointer(&lOutByte[0])
+	
+
+		pLMNIdentity := C.CString(ueIdData.pLMNIdentitybuf)
+	defer C.free(unsafe.Pointer(pLMNIdentity))
+        	pLMNIdentity_size := C.size_t(len(ueIdData.pLMNIdentitybuf))
+        	aMFRegionID := C.CString(ueIdData.aMFRegionIDbuf)
+	defer C.free(unsafe.Pointer(aMFRegionID))
+        	aMFSetID := C.CString(ueIdData.aMFSetIDbuf)
+	defer C.free(unsafe.Pointer(aMFSetID))
+        	aMFPointer := C.CString(ueIdData.aMFPointerbuf)
+	defer C.free(unsafe.Pointer(aMFPointer))
+
+	uEID_C := C.struct_uEID{
+                amf_UE_NGAP_Id: C.long(ueIdData.amf_UE_NGAP_Id),
+                pLMNIdentity : pLMNIdentity,
+                pLMNIdentity_size : pLMNIdentity_size,
+                aMFRegionID : aMFRegionID,
+                aMFRegionID_size : 1, //AMFRegionID ::= BIT STRING (SIZE(8))
+                aMFSetID : aMFSetID,
+                aMFSetID_size: 2, //BIT STRING (SIZE(10))
+                aMFPointer : aMFPointer,
+                aMFPointer_size : 1,  //BIT STRING (SIZE(6))
+        }
+
+	xapp.Logger.Debug("uEID_C amf_UE_NGAP_Id  = %l",uEID_C.amf_UE_NGAP_Id)
+	xapp.Logger.Debug("uEID_C pLMNIdentity = %s",uEID_C.pLMNIdentity)
+	xapp.Logger.Debug("uEID_C aMFRegionID %s = ",uEID_C.aMFRegionID)
+	xapp.Logger.Debug("uEID_C aMFSetID  %s = ",uEID_C.aMFSetID)
+	xapp.Logger.Debug("uEID_C aMFPointer %s = ",uEID_C.aMFPointer)
+
+	size := C.e2sm_encode_ric_control_header(cptr, C.size_t(len(buffer)),&uEID_C ,(*C.long)(&ueIdData.F1AP_id[0]),C.size_t(len(ueIdData.F1AP_id)),(*C.long)(&ueIdData.E1AP_id[0]),C.size_t(len(ueIdData.E1AP_id)),(C.long)(ricControlStyleType), (C.long)(ricControlActionID), cptrRanParameterValue,C.size_t(len(lOutByte)))
+
+	//size := C.e2sm_encode_ric_control_header(cptr, C.size_t(len(buffer)),&uEID_C ,(*C.long)(&ueIdData.F1AP_id[0]),(*C.long)(&ueIdData.E1AP_id[0]),(C.long)(ricControlStyleType), (C.long)(ricControlActionID))
+	
 	if size < 0 {
 		return make([]byte, 0), errors.New("e2sm wrapper is unable to set EventTriggerDefinition due to wrong or invalid input")
 	}
@@ -31,11 +81,27 @@
 }
 
 func (c *E2sm) SetRicControlMessage(buffer []byte, targetPrimaryCell int64, targetCell int64, nrCGIOrECGI int64, nrOrEUtraCell int64, ranParameterValue []byte) (newBuffer []byte, err error) {
+	
+	xapp.Logger.Info("SetRicControlMessagei Enter  ")
+
 	cptr := unsafe.Pointer(&buffer[0])
 	cptrRanParameterValue := unsafe.Pointer(&ranParameterValue[0])
 
+	/*
+	lIntvar, _ := strconv.Atoi(string(ranParameterValue))
+	xapp.Logger.Info("lIntvar %d\n", lIntvar)
+	lIntegerByte := ConverIntegerToByte(lIntvar)
+	xapp.Logger.Info("lIntegerByte %v\n", lIntegerByte)
+	lOutByte := get_bytepack_plmnId(lIntegerByte)
+	xapp.Logger.Info("lOutByte Len:%d\n", len(lOutByte))
+	xapp.Logger.Info("lOutByte %02X\n", lOutByte)
+	cptrRanParameterValue := unsafe.Pointer(&lOutByte[0])
+	xapp.Logger.Info("cptrRanParameterValue = %v\n ", cptrRanParameterValue)
+	*/
+
 	size := C.e2sm_encode_ric_control_message(cptr, C.size_t(len(buffer)), C.long(targetPrimaryCell),
 		C.long(targetCell), C.long(nrOrEUtraCell), C.long(nrCGIOrECGI), cptrRanParameterValue, C.size_t(len(ranParameterValue)))
+
 	if size < 0 {
 		return make([]byte, 0), errors.New("e2sm wrapper is unable to set RicControlMessage due to wrong or invalid input")
 	}
@@ -43,3 +109,82 @@
 	xapp.Logger.Info("E2sm SetRicControlMessage is success")
 	return
 }
+
+func (c *E2sm) GetControlOutcome(buffer []byte) (controlOutcome *ControlOutcomeMsg, err error) {
+        cptr := unsafe.Pointer(&buffer[0])
+        controlOutcome = &ControlOutcomeMsg{}
+	//lTransId := gTransIdDefVal
+        //ml.MavLog(ml.INFO, lTransId, "Decode Control Outcome: ")
+	xapp.Logger.Info("Decode Control Outcome: ")
+        decodedMsg := C.e2sm_decode_ric_call_process_outcome(cptr, C.size_t(len(buffer)))
+        if decodedMsg == nil {
+                return controlOutcome, errors.New("e2sm wrapper is unable to get ControlOutcome due to wrong or invalid input")
+        }
+        defer C.e2sm_free_ric_call_process_outcome(decodedMsg)
+        //ml.MavLog(ml.INFO, lTransId, "Decoded Control Outcome: ")
+	controlOutcome.ControlOutcomeType = int32(decodedMsg.ric_controlOutcome_formats.present)
+	if controlOutcome.ControlOutcomeType == 1 {
+                controlOutcome := &ControlOutcomeFormat1{}
+                controlOutcomeFormat1_C := *(**C.E2SM_RC_ControlOutcome_Format1_t)(unsafe.Pointer(&decodedMsg.ric_controlOutcome_formats.choice[0]))
+		controlOutcome.ControlOutcomeFormat1ItemCount = int(controlOutcomeFormat1_C.ranP_List.list.count)
+		controlOutcome.ControlOutcomeFormat1Item = make([]ControlOutcomeFormat1ItemType, controlOutcome.ControlOutcomeFormat1ItemCount +1)
+                //ml.MavLog(ml.INFO, lTransId, "RIC Control Outcome  Format1 Item Count = %d ", controlOutcome.ControlOutcomeFormat1ItemCount)
+                for i := 0; i < controlOutcome.ControlOutcomeFormat1ItemCount; i++ {
+			ControlOutcomeFormat1Item :=  &controlOutcome.ControlOutcomeFormat1Item[i]
+			var sizeof_E2SM_RC_ControlOutcome_Format1_Item_t *C.E2SM_RC_ControlOutcome_Format1_Item_t
+			ControlOutcomeFormat1Item_C :=  *(*(**C.E2SM_RC_ControlOutcome_Format1_Item_t)(unsafe.Pointer(uintptr(unsafe.Pointer(controlOutcomeFormat1_C.ranP_List.list.array)) + (uintptr)(i)*unsafe.Sizeof(sizeof_E2SM_RC_ControlOutcome_Format1_Item_t))))
+			ControlOutcomeFormat1Item.RanParameterID = int64(ControlOutcomeFormat1Item_C.ranParameter_ID)
+			ControlOutcomeFormat1Item.RANParameterValueType = int(ControlOutcomeFormat1Item_C.ranParameter_value.present)
+		        ranParameterValue_C := (C.RANParameter_Value_t)(ControlOutcomeFormat1Item_C.ranParameter_value)
+			if ControlOutcomeFormat1Item.RANParameterValueType == 5 {
+				//ml.MavLog(ml.INFO, lTransId, "RANParameterValueType  is RANParameter_Value_PR_valueOctS")
+				ranParameterValue := &OctetString{}
+				ranParameter_C := (*C.OCTET_STRING_t)(unsafe.Pointer(&ranParameterValue_C.choice[0]))
+                                ranParameterValue.Size = int(ranParameter_C.size)
+                                ranParameterValue.Buf = C.GoBytes(unsafe.Pointer(ranParameter_C.buf), C.int(ranParameter_C.size))
+                                ControlOutcomeFormat1Item.RANParameterValue = ranParameterValue
+				//ml.MavLog(ml.INFO, lTransId, "RANParameterValue = ", ControlOutcomeFormat1Item.RANParameterValue)
+			}
+		}
+	} else {
+		return controlOutcome, errors.New("Unknown RIC Control Outcome type")
+	}
+	return controlOutcome , err
+}
+
+func (c *E2sm) get_plmn_from_mcc_mnc(plmnIdBuf []byte)(bytePackedPlmnId []uint8) {
+	//lTransId := gTransIdDefVal
+	hexResp, _ := hex.DecodeString(string(plmnIdBuf))
+	//ml.MavLog(ml.INFO, lTransId, "get_plmn_from_mcc_mnc plmnIdBuf and hexResp = ", plmnIdBuf,hexResp)
+	var mcc []uint8 = make([]uint8, 3)
+        var mnc []uint8 = make([]uint8, 3)
+
+        mcc[0] = hexResp[0] >> 4
+        mcc[1] = hexResp[0] & 0xf
+        mcc[2] = hexResp[1] >> 4
+        mnc[0] = hexResp[1] & 0xf
+        mnc[1] = hexResp[2] >> 4
+        mnc[2] = hexResp[2] & 0xf
+
+        var tmpPlmnId []uint8 = make([]uint8, 6)
+        tmpPlmnId[0] = mcc[0]
+        tmpPlmnId[1] =  mcc[1]
+        tmpPlmnId[2] =  mcc[2]
+      if len(mcc) == 2 {
+                tmpPlmnId[3] = 0x0f
+                tmpPlmnId[4] = mnc[0]
+                tmpPlmnId[5] = mnc[1]
+        } else {
+                tmpPlmnId[3] = mnc[0]
+                tmpPlmnId[4] = mnc[1]
+                tmpPlmnId[5] = mnc[2]
+        }
+        //ml.MavLog(ml.INFO, lTransId, "\n tmpPlmnId " , tmpPlmnId)
+        bytePackedPlmnId = make([]uint8,3)
+        bytePackedPlmnId[0] = ((tmpPlmnId[1] & 0x0F) << 4) | (tmpPlmnId[0] & 0x0F)
+        bytePackedPlmnId[1] = ((tmpPlmnId[3] & 0x0F) << 4) | (tmpPlmnId[2] & 0x0F)
+        bytePackedPlmnId[2] = ((tmpPlmnId[5] & 0x0F) << 4) | (tmpPlmnId[4] & 0x0F)
+        //ml.MavLog(ml.INFO, lTransId, "\n bytePackedPlmnId " , bytePackedPlmnId)
+        return
+}
+
diff --git a/control/rcService.go b/control/rcService.go
index 005b742..0523562 100644
--- a/control/rcService.go
+++ b/control/rcService.go
@@ -6,8 +6,8 @@
 	_ "strings"
 	"time"
 
-	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
 	"gerrit.o-ran-sc.org/r/ric-app/rc/protocol/grpc/ricmsgcommrpc/rc"
+	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
 	"golang.org/x/net/context"
 )
 
@@ -26,12 +26,13 @@
 	}()
 
 	var lRicControlGrpcRsp rc.RicControlGrpcRsp
-	lRicControlGrpcRsp.RspCode = GRPC_ERROR 
+	lRicControlGrpcRsp.RspCode = GRPC_ERROR
 	lRicControlGrpcRsp.Description = "The client specified an invalid argument. or some parameters are missing "
 	if aPtrRicControlGrpcReq == nil {
 		xapp.Logger.Error("Received nil data from Send error rsp")
 	} else {
-		if len(aPtrRicControlGrpcReq.E2NodeID) == 0 || len(aPtrRicControlGrpcReq.RICControlMessageData.TargetCellID) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID) == 0  || len(aPtrRicControlGrpcReq.RanName) == 0  || len(aPtrRicControlGrpcReq.PlmnID) == 0{
+		//if len(aPtrRicControlGrpcReq.E2NodeID) == 0 || len(aPtrRicControlGrpcReq.RICControlMessageData.TargetCellID) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.PLMNIdentity) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.AMFRegionID) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.AMFSetID) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.AMFPointer) == 0 || len(aPtrRicControlGrpcReq.RanName) == 0 || len(aPtrRicControlGrpcReq.PlmnID) == 0 {
+		if len(aPtrRicControlGrpcReq.E2NodeID) == 0 || len(aPtrRicControlGrpcReq.RICControlMessageData.TargetCellID) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.PLMNIdentity) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.AMFRegionID) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.AMFSetID) == 0 || len(aPtrRicControlGrpcReq.RICControlHeaderData.UEID.GnbUEID.Guami.AMFPointer) == 0 || len(aPtrRicControlGrpcReq.RanName) == 0 || len(aPtrRicControlGrpcReq.PlmnID) == 0 {
 			xapp.Logger.Error("Mandatory parameters are not received send Error rsp to client,no control Request will be initiated ")
 		} else {
 			xapp.Logger.Info("GRPC Control request validated, initiate Control Request to RAN")
diff --git a/control/rcTypes.go b/control/rcTypes.go
index 0204451..e558d02 100644
--- a/control/rcTypes.go
+++ b/control/rcTypes.go
@@ -1,9 +1,10 @@
 package control

 

 import (

-	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"

-	rc "gerrit.o-ran-sc.org/r/ric-app/rc/protocol/grpc/ricmsgcommrpc/rc"

 	"sync"

+

+	rc "gerrit.o-ran-sc.org/r/ric-app/rc/protocol/grpc/ricmsgcommrpc/rc"

+	"gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"

 )

 

 const MAX_CONTROL_REQ_ATTEMPTS = 2

@@ -22,10 +23,10 @@
 const GRPC_ERROR = -1

 

 type Control struct {

-	eventRicControlReqTimePeriod int32                //maximum time for the RIC Subscription Request event creation procedure in the E2 Node

+	eventRicControlReqTimePeriod int32                //maximum time for the RIC Control Request creation procedure in the E2 Node

 	rcChan                       chan *xapp.RMRParams //channel for receiving rmr message

-	eventRicControlReqExpiredMap map[int]bool //map for recording the RIC Subscription Request event creation procedure is expired or not

-	eventRicControlReqExpiredMu  *sync.Mutex  //mutex for eventCreateExpiredMap

+	eventRicControlReqExpiredMap map[int]bool         //map for recording the RIC Control Request event creation procedure is expired or not

+	eventRicControlReqExpiredMu  *sync.Mutex          //mutex for eventCreateExpiredMap

 	ricRequestInstanceID         int

 }

 

@@ -33,3 +34,58 @@
 	RicControlGrpcReqPtr *rc.RicControlGrpcReq

 }

 

+

+type UEid struct {

+        amf_UE_NGAP_Id   int64

+        pLMNIdentitybuf  string

+        aMFRegionIDbuf   string

+        aMFSetIDbuf      string

+        aMFPointerbuf    string

+        F1AP_id         []int64

+        E1AP_id         []int64

+}

+

+type ValueInt int64

+

+type valueReal float64

+

+type Null int32

+

+type PrintableString OctetString

+

+type OctetString struct {

+        Buf  []byte

+        Size int

+}

+

+type BitString struct {

+        Buf        []byte

+        Size       int

+        BitsUnused int

+}

+

+type ControlAckMsg struct {

+        RequestID             int32

+        InstanceId            int32

+        FuncID                int32

+        CallProcessID         []byte

+        CallProcessIDLength   int32

+        ControlOutcome        []byte

+        ControlOutcomeLength  int32

+}

+

+type ControlOutcomeFormat1ItemType struct {

+	RanParameterID     int64

+	RANParameterValueType int

+	RANParameterValue interface{}

+}

+

+type ControlOutcomeFormat1 struct {

+	ControlOutcomeFormat1Item      []ControlOutcomeFormat1ItemType

+        ControlOutcomeFormat1ItemCount int

+}

+

+type ControlOutcomeMsg struct {

+        ControlOutcomeType  int32

+        ControlOutcome      interface{}

+}