RIC-851: Updated submgr to trigger Delete Subscription Procedure 87/10287/15
authorgunjarastogi <gunja.rastogi@capgemini.com>
Wed, 18 Jan 2023 12:21:55 +0000 (17:51 +0530)
committerGunja Rastogi <gunja.rastogi@capgemini.com>
Mon, 6 Mar 2023 13:17:52 +0000 (13:17 +0000)
towards E2 Node for the subscriptions mentioned in
Is_Subscription_Delete_Required procedure

Signed-off-by: gunjarastogi <gunja.rastogi@capgemini.com>
Change-Id: I941fcdbc66e26f62ff15b3a17bf79ab0f2437dd1

14 files changed:
Dockerfile
e2ap/libe2ap_wrapper/E2AP_if.c
e2ap/libe2ap_wrapper/E2AP_if.h
e2ap/pkg/e2ap/e2ap_packerif.go
e2ap/pkg/e2ap/msg_e2ap_subscriptiondelete.go
e2ap/pkg/e2ap_wrapper/packer_e2ap.go
e2ap/pkg/e2ap_wrapper/ut_packer_e2ap.go
go.mod
go.sum
pkg/control/control.go
pkg/control/e2ap.go
pkg/control/metrics.go
pkg/control/metrics_test.go
pkg/control/ut_ric_subs_del_reqd_test.go [new file with mode: 0644]

index 1084cf2..a63043e 100644 (file)
@@ -65,7 +65,7 @@ RUN export GOBIN=/usr/local/bin/ ; \
 #
 # RMR
 #
-ARG RMRVERSION=4.8.5
+ARG RMRVERSION=4.9.0
 ARG RMRLIBURL=https://packagecloud.io/o-ran-sc/release/packages/debian/stretch/rmr_${RMRVERSION}_amd64.deb/download.deb
 ARG RMRDEVURL=https://packagecloud.io/o-ran-sc/release/packages/debian/stretch/rmr-dev_${RMRVERSION}_amd64.deb/download.deb
 RUN wget --content-disposition ${RMRLIBURL} && dpkg -i rmr_${RMRVERSION}_amd64.deb
index 4a2a018..2515b81 100644 (file)
@@ -55,6 +55,7 @@ const uint64_t cE2UnsuccessfulOutcome = 3;
 // Initiating message
 const uint64_t cRICSubscriptionRequest = 1;
 const uint64_t cRICSubscriptionDeleteRequest = 2;
+const uint64_t cRICSubscriptionDeleteRequired = 3;
 
 // Successful outcome
 const uint64_t cRICSubscriptionResponse = 1;
@@ -672,6 +673,18 @@ e2ap_pdu_ptr_t* unpackE2AP_pdu(const size_t dataBufferSize, const byte* dataBuff
                     sprintf(pLogBuffer,"Error. Not supported initiatingMessage MessageId = %u",pE2AP_PDU->choice.initiatingMessage.value.present);
                     return 0;
                 }
+            }else if (pE2AP_PDU->choice.initiatingMessage.procedureCode ==
+                               ProcedureCode_id_RICsubscriptionDeleteRequired) {
+                        if (pE2AP_PDU->choice.initiatingMessage.value.present ==
+                            InitiatingMessage__value_PR_RICsubscriptionDeleteRequired) {
+                            pMessageInfo->messageType = cE2InitiatingMessage;
+                            pMessageInfo->messageId = cRICSubscriptionDeleteRequired;
+                            return (e2ap_pdu_ptr_t *) pE2AP_PDU;
+                        } else {
+                            sprintf(pLogBuffer, "Error. Not supported initiatingMessage MessageId = %u",
+                                    pE2AP_PDU->choice.initiatingMessage.value.present);
+                            return 0;
+                        }
             }
             else {
                 sprintf(pLogBuffer,"Error. Procedure not supported. ProcedureCode = %li",pE2AP_PDU->choice.initiatingMessage.procedureCode);
@@ -1175,3 +1188,158 @@ uint64_t getRICSubscriptionDeleteFailureData(e2ap_pdu_ptr_t* pE2AP_PDU_pointer,
     ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pE2AP_PDU);
     return e2err_OK;
 }
+
+//**************************************************************************************************************************
+uint64_t packRICSubscriptionDeleteRequired(size_t* pDataBufferSize, byte* pDataBuffer, char* pLogBuffer, RICSubsDeleteRequired_t* pRICSubscriptionDeleteRequired) {
+
+    E2AP_PDU_t *pE2AP_PDU = calloc(1, sizeof(E2AP_PDU_t));
+    if (pE2AP_PDU) {
+        pE2AP_PDU->present = E2AP_PDU_PR_initiatingMessage;
+        pE2AP_PDU->choice.initiatingMessage.procedureCode = ProcedureCode_id_RICsubscriptionDeleteRequired;
+        pE2AP_PDU->choice.initiatingMessage.criticality = Criticality_ignore;
+        pE2AP_PDU->choice.initiatingMessage.value.present = InitiatingMessage__value_PR_RICsubscriptionDeleteRequired;
+
+        {
+            RICsubscriptionDeleteRequired_IEs_t *ricSubsDeleteRequiredIEs = calloc(1,
+                                                                                   sizeof(RICsubscriptionDeleteRequired_IEs_t));
+            ricSubsDeleteRequiredIEs->id = ProtocolIE_ID_id_RICsubscriptionToBeRemoved;
+            ricSubsDeleteRequiredIEs->criticality = Criticality_ignore;
+            ricSubsDeleteRequiredIEs->value.present = RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause;
+
+            for (int idx = 0; idx < pRICSubscriptionDeleteRequired->noOfRanSubscriptions; idx++) {
+                RICsubscription_withCause_ItemIEs_t *ricSubsListWithCauseItem = calloc(1,
+                                                                                       sizeof(RICsubscription_withCause_ItemIEs_t));
+                ricSubsListWithCauseItem->id = ProtocolIE_ID_id_RICsubscription_withCause_Item;
+                ricSubsListWithCauseItem->criticality = Criticality_ignore;
+                ricSubsListWithCauseItem->value.present = RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item;
+
+                // RIC RequestID
+                ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.ricRequestID.ricRequestorID =
+                        pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].ricRequestID.ricRequestorID;
+                ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.ricRequestID.ricInstanceID =
+                        pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].ricRequestID.ricInstanceID;
+
+                // RANFunctionID
+                ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.ranFunctionID =
+                        pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].ranFunctionID;
+
+                // RICCause
+                if (pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content ==
+                    Cause_PR_ricRequest) {
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.present = Cause_PR_ricRequest;
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.choice.ricRequest =
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal;
+                } else if (pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content ==
+                           Cause_PR_ricService) {
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.present = Cause_PR_ricService;
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.choice.ricService =
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal;
+                } else if (pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content ==
+                           Cause_PR_e2Node) {
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.present = Cause_PR_e2Node;
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.choice.e2Node =
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal;
+                } else if (pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content ==
+                           Cause_PR_protocol) {
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.present = Cause_PR_protocol;
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.choice.protocol =
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal;
+                } else if (pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content ==
+                           Cause_PR_transport) {
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.present = Cause_PR_transport;
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.choice.transport =
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal;
+                } else if (pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content ==
+                           Cause_PR_misc) {
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.present = Cause_PR_misc;
+                    ricSubsListWithCauseItem->value.choice.RICsubscription_withCause_Item.cause.choice.misc =
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal;
+                }
+                asn_sequence_add(&ricSubsDeleteRequiredIEs->value.choice.RICsubscription_List_withCause.list,
+                                 ricSubsListWithCauseItem);
+            }
+            asn_sequence_add(
+                    &pE2AP_PDU->choice.initiatingMessage.value.choice.RICsubscriptionDeleteRequired.protocolIEs.list,
+                    ricSubsDeleteRequiredIEs);
+
+            if (E2encode(pE2AP_PDU, pDataBufferSize, pDataBuffer, pLogBuffer))
+                return e2err_OK;
+            else
+                return e2err_RICSubscriptionDeleteRequiredEncodeFail;
+        }
+    }
+    else
+        return e2err_RICSubscriptionDeleteRequiredAllocE2AP_PDUFail;
+}
+
+//**************************************************************************************************************************
+uint64_t getRICSubscriptionDeleteRequiredData(e2ap_pdu_ptr_t *pE2AP_PDU_pointer,
+                                                  RICSubsDeleteRequired_t *pRICSubscriptionDeleteRequired) {
+
+        E2AP_PDU_t *pE2AP_PDU = (E2AP_PDU_t *) pE2AP_PDU_pointer;
+
+        RICsubscriptionDeleteRequired_t *asnRicSubscriptionDeleteRequired = &pE2AP_PDU->choice.initiatingMessage.value.choice.RICsubscriptionDeleteRequired;
+
+        if (asnRicSubscriptionDeleteRequired->protocolIEs.list.count > 0 &&
+            asnRicSubscriptionDeleteRequired->protocolIEs.list.array[0]->id ==
+            ProtocolIE_ID_id_RICsubscriptionToBeRemoved) {
+            if (asnRicSubscriptionDeleteRequired->protocolIEs.list.array[0]->value.present ==
+                RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause) {
+                RICsubscription_List_withCause_t riCsubscriptionListWithCause = asnRicSubscriptionDeleteRequired->protocolIEs.list.array[0]->value.choice.RICsubscription_List_withCause;
+                pRICSubscriptionDeleteRequired->noOfRanSubscriptions = riCsubscriptionListWithCause.list.count;
+                for (int idx = 0; idx < riCsubscriptionListWithCause.list.count; idx++) {
+                    RICsubscription_withCause_ItemIEs_t *riCsubscriptionWithCauseItemIEs = (RICsubscription_withCause_ItemIEs_t*)riCsubscriptionListWithCause.list.array[idx];
+                    if (riCsubscriptionWithCauseItemIEs->id == ProtocolIE_ID_id_RICsubscription_withCause_Item &&
+                            riCsubscriptionWithCauseItemIEs->value.present ==
+                        RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item) {
+                        // RIC RequestID
+                        pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].ricRequestID.ricRequestorID = riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.ricRequestID.ricRequestorID;
+                        pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].ricRequestID.ricInstanceID = riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.ricRequestID.ricInstanceID;
+
+                        // RANFunctionID
+                        pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].ranFunctionID = riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.ranFunctionID;
+
+                        // RICCause
+                        if (riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.present ==
+                            Cause_PR_ricRequest) {
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content = Cause_PR_ricRequest;
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal =
+                                    riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.choice.ricRequest;
+                        }
+                            //TODO : RIC Cause
+                        else if (riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.present ==
+                                 Cause_PR_ricService) {
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content = Cause_PR_ricService;
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal =
+                                    riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.choice.ricService;
+                        } else if (
+                                riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.present ==
+                                Cause_PR_transport) {
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content = Cause_PR_transport;
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal =
+                                    riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.choice.transport;
+                        } else if (
+                                riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.present ==
+                                Cause_PR_protocol) {
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content = Cause_PR_protocol;
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal =
+                                    riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.choice.protocol;
+                        } else if (
+                                riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.present ==
+                                Cause_PR_misc) {
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.content = Cause_PR_misc;
+                            pRICSubscriptionDeleteRequired->ranSubscriptionsDelRequired[idx].cause.causeVal =
+                                    riCsubscriptionWithCauseItemIEs->value.choice.RICsubscription_withCause_Item.cause.choice.misc;
+                        }
+                    }
+                }
+
+            }
+
+        }
+
+
+        ASN_STRUCT_FREE(asn_DEF_E2AP_PDU, pE2AP_PDU);
+        return e2err_OK;
+    }
+
index 2678151..32f1c19 100644 (file)
@@ -282,7 +282,12 @@ enum e2err {
     e2err_RICsubscriptionDeleteResponseRANfunctionIDMissing,
     e2err_RICsubscriptionDeleteFailureRICrequestIDMissing,
     e2err_RICsubscriptionDeleteFailureRANfunctionIDMissing,
-    e2err_RICsubscriptionDeleteFailureRICcauseMissing
+    e2err_RICsubscriptionDeleteFailureRICcauseMissing,
+    e2err_RICSubscriptionDeleteRequiredRICrequestIDMissing,
+    e2err_RICSubscriptionDeleteRequiredRANfunctionIDMissing,
+    e2err_RICSubscriptionDeleteRequiredRICcauseMissing,
+    e2err_RICSubscriptionDeleteRequiredEncodeFail,
+    e2err_RICSubscriptionDeleteRequiredAllocE2AP_PDUFail
 };
 
 static const char* const E2ErrorStrings[] = {
@@ -338,7 +343,12 @@ static const char* const E2ErrorStrings[] = {
     "e2err_RICsubscriptionDeleteResponseRANfunctionIDMissing",
     "e2err_RICsubscriptionDeleteFailureRICrequestIDMissing",
     "e2err_RICsubscriptionDeleteFailureRANfunctionIDMissing",
-    "e2err_RICsubscriptionDeleteFailureRICcauseMissing"
+    "e2err_RICsubscriptionDeleteFailureRICcauseMissing",
+    "e2err_RICSubscriptionDeleteRequiredRICrequestIDMissing",
+    "e2err_RICSubscriptionDeleteRequiredRANfunctionIDMissing",
+    "e2err_RICSubscriptionDeleteRequiredRICcauseMissing",
+    "e2err_RICSubscriptionDeleteRequiredEncodeFail",
+    "e2err_RICSubscriptionDeleteRequiredAllocE2AP_PDUFail",
 };
 
 typedef struct {
@@ -359,6 +369,7 @@ extern const uint64_t cE2UnsuccessfulOutcome;
 // Initiating message
 extern const uint64_t cRICSubscriptionRequest;
 extern const uint64_t cRICSubscriptionDeleteRequest;
+extern const uint64_t cRICSubscriptionDeleteRequired;
 
 // Successful outcome
 extern const uint64_t cRICSubscriptionResponse;
@@ -408,6 +419,18 @@ typedef struct  {
     CriticalityDiagnostics__t criticalityDiagnostics; // OPTIONAL. Not used in RIC currently
 } RICSubscriptionDeleteFailure_t;
 
+typedef struct {
+    RICRequestID_t ricRequestID;
+    RANFunctionID_t ranFunctionID;
+    RICCause_t cause;
+} RICSubscriptionDeleteRequired_t;
+
+typedef struct {
+    int noOfRanSubscriptions;
+    RICSubscriptionDeleteRequired_t ranSubscriptionsDelRequired[1024];
+
+} RICSubsDeleteRequired_t;
+
 //////////////////////////////////////////////////////////////////////
 // Function declarations
 
@@ -423,6 +446,7 @@ uint64_t packRICSubscriptionFailure(size_t*, byte*, char*,RICSubscriptionFailure
 uint64_t packRICSubscriptionDeleteRequest(size_t*, byte*, char*,RICSubscriptionDeleteRequest_t*);
 uint64_t packRICSubscriptionDeleteResponse(size_t*, byte*, char*,RICSubscriptionDeleteResponse_t*);
 uint64_t packRICSubscriptionDeleteFailure(size_t*, byte*, char*,RICSubscriptionDeleteFailure_t*);
+uint64_t packRICSubscriptionDeleteRequired(size_t*, byte*, char*,RICSubsDeleteRequired_t*);
 
 e2ap_pdu_ptr_t* unpackE2AP_pdu(const size_t, const byte*, char*, E2MessageInfo_t*);
 uint64_t getRICSubscriptionRequestData(e2ap_pdu_ptr_t*, RICSubscriptionRequest_t*);
@@ -431,7 +455,7 @@ uint64_t getRICSubscriptionFailureData(e2ap_pdu_ptr_t*, RICSubscriptionFailure_t
 uint64_t getRICSubscriptionDeleteRequestData(e2ap_pdu_ptr_t*, RICSubscriptionDeleteRequest_t*);
 uint64_t getRICSubscriptionDeleteResponseData(e2ap_pdu_ptr_t*, RICSubscriptionDeleteResponse_t*);
 uint64_t getRICSubscriptionDeleteFailureData(e2ap_pdu_ptr_t*, RICSubscriptionDeleteFailure_t*);
-
+uint64_t getRICSubscriptionDeleteRequiredData(e2ap_pdu_ptr_t*, RICSubsDeleteRequired_t*);
 
 #if DEBUG
 bool TestRICSubscriptionRequest();
@@ -440,6 +464,7 @@ bool TestRICSubscriptionFailure();
 bool TestRICSubscriptionDeleteRequest();
 bool TestRICSubscriptionDeleteResponse();
 bool TestRICSubscriptionDeleteFailure();
+bool TestRICSubscriptionDeleteRequired();
 
 void printRICSubscriptionRequest(const RICSubscriptionRequest_t*);
 void printRICSubscriptionResponse(const RICSubscriptionResponse_t*);
@@ -447,6 +472,7 @@ void printRICSubscriptionFailure(const RICSubscriptionFailure_t*);
 void printRICSubscriptionDeleteRequest(const RICSubscriptionDeleteRequest_t*);
 void printRICSubscriptionDeleteResponse(const RICSubscriptionDeleteResponse_t*);
 void printRICSubscriptionDeleteFailure(const RICSubscriptionDeleteFailure_t*);
+void printRICSubscriptionDeleteRequired(const RICSubsDeleteRequired_t*);
 #endif
 
 #ifdef __cplusplus
index 9a06589..5e327d5 100644 (file)
@@ -73,6 +73,15 @@ type E2APMsgPackerSubscriptionDeleteFailureIf interface {
        String() string
 }
 
+//-----------------------------------------------------------------------------
+// Changes to support "RIC_SUB_DEL_REQUIRED"
+//-----------------------------------------------------------------------------
+type E2APMsgPackerSubscriptionDeleteRequiredIf interface {
+       Pack(list *SubscriptionDeleteRequiredList) (error, *PackedData)
+       UnPack(msg *PackedData) (error, *SubscriptionDeleteRequiredList)
+       String() string
+}
+
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
@@ -83,6 +92,7 @@ type E2APPackerIf interface {
        NewPackerSubscriptionDeleteRequest() E2APMsgPackerSubscriptionDeleteRequestIf
        NewPackerSubscriptionDeleteResponse() E2APMsgPackerSubscriptionDeleteResponseIf
        NewPackerSubscriptionDeleteFailure() E2APMsgPackerSubscriptionDeleteFailureIf
+       NewPackerSubscriptionDeleteRequired() E2APMsgPackerSubscriptionDeleteRequiredIf
        //UnPack(*PackedData) (error, interface{})
        //Pack(interface{}, *PackedData) (error, *PackedData)
 }
index b6bb179..174f00d 100644 (file)
@@ -44,3 +44,19 @@ type E2APSubscriptionDeleteFailure struct {
        Cause
        CriticalityDiagnostics
 }
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+type SubscriptionDeleteRequiredList struct {
+       E2APSubscriptionDeleteRequiredRequests []E2APSubscriptionDeleteRequired
+}
+
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+type E2APSubscriptionDeleteRequired struct {
+       RequestId
+       FunctionId
+       Cause
+}
index 2d02f81..3ebd689 100644 (file)
@@ -43,6 +43,9 @@ package e2ap_wrapper
 // void initSubsDeleteFailure(RICSubscriptionDeleteFailure_t *data){
 //   bzero(data,sizeof(RICSubscriptionDeleteFailure_t));
 // }
+// void initSubsDeleteRequired(RICSubsDeleteRequired_t *data){
+//      bzero(data,sizeof(RICSubsDeleteRequired_t));
+// }
 //
 import "C"
 
@@ -1107,6 +1110,96 @@ func (e2apMsg *e2apMsgPackerSubscriptionDeleteFailure) String() string {
        return b.String()
 }
 
+//-----------------------------------------------------------------------------
+// Changes to support "RIC_SUB_DEL_REQUIRED"
+//-----------------------------------------------------------------------------
+type e2apMsgPackerSubscriptionDeleteRequired struct {
+       e2apMessagePacker
+       msgC *C.RICSubsDeleteRequired_t
+       msgG *e2ap.SubscriptionDeleteRequiredList
+}
+
+func (e2apMsg *e2apMsgPackerSubscriptionDeleteRequired) init() {
+       e2apMsg.e2apMessagePacker.init(C.E2MessageInfo_t{C.cE2InitiatingMessage, C.cRICSubscriptionDeleteRequired})
+       e2apMsg.msgC = &C.RICSubsDeleteRequired_t{}
+       e2apMsg.msgG = &e2ap.SubscriptionDeleteRequiredList{}
+       C.initSubsDeleteRequired(e2apMsg.msgC)
+}
+
+func (e2apMsg *e2apMsgPackerSubscriptionDeleteRequired) Pack(data *e2ap.SubscriptionDeleteRequiredList) (error, *e2ap.PackedData) {
+       e2apMsg.init()
+       defer e2apMsg.fini()
+       e2apMsg.msgG = data
+
+       e2apMsg.msgC.noOfRanSubscriptions = C.int(len(e2apMsg.msgG.E2APSubscriptionDeleteRequiredRequests))
+       for idx, subs := range e2apMsg.msgG.E2APSubscriptionDeleteRequiredRequests {
+
+               // RIC Request ID
+               e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ricRequestID.ricInstanceID = (C.uint32_t)(subs.RequestId.InstanceId)
+               e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ricRequestID.ricRequestorID = (C.uint32_t)(subs.RequestId.Id)
+
+               // RAN Function ID
+               e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ranFunctionID = (C.uint16_t)(subs.FunctionId)
+
+               // RIC Cause
+               e2apMsg.msgC.ranSubscriptionsDelRequired[idx].cause.content = (C.uint8_t)(subs.Cause.Content)
+               e2apMsg.msgC.ranSubscriptionsDelRequired[idx].cause.causeVal = (C.uint8_t)(subs.Cause.Value)
+
+       }
+
+       errorNro := C.packRICSubscriptionDeleteRequired(&e2apMsg.plen, (*C.uchar)(e2apMsg.p), (*C.char)(unsafe.Pointer(&e2apMsg.lb[0])), e2apMsg.msgC)
+       if err := e2apMsg.checkerr(errorNro); err != nil {
+               fmt.Printf("ERROR: %s", err.Error())
+               return err, nil
+       }
+       return nil, e2apMsg.packeddata()
+}
+
+func (e2apMsg *e2apMsgPackerSubscriptionDeleteRequired) UnPack(msg *e2ap.PackedData) (error, *e2ap.SubscriptionDeleteRequiredList) {
+       e2apMsg.init()
+       defer e2apMsg.fini()
+
+       if err := e2apMsg.e2apMessagePacker.unpacktopdu(msg); err != nil {
+               return err, e2apMsg.msgG
+       }
+       errorNro := C.getRICSubscriptionDeleteRequiredData(e2apMsg.e2apMessagePacker.pdu, e2apMsg.msgC)
+       if err := e2apMsg.checkerr(errorNro); err != nil {
+               return err, e2apMsg.msgG
+       }
+
+       //TODO: Fill List of RIC Subscriptions to be Removed
+       for idx := 0; idx < int(e2apMsg.msgC.noOfRanSubscriptions); idx++ {
+               var ricSubsToBeRemove e2ap.E2APSubscriptionDeleteRequired
+               // RIC RequestID
+               if err := (&e2apEntryRequestID{entry: &e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ricRequestID}).get(&ricSubsToBeRemove.RequestId); err != nil {
+                       return err, e2apMsg.msgG
+               }
+               // RAN Function ID
+               ricSubsToBeRemove.FunctionId = (e2ap.FunctionId)(e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ranFunctionID)
+
+               // RIC Cause
+               ricSubsToBeRemove.Cause.Content = (uint8)(e2apMsg.msgC.ranSubscriptionsDelRequired[idx].cause.content)
+               ricSubsToBeRemove.Cause.Value = (uint8)(e2apMsg.msgC.ranSubscriptionsDelRequired[idx].cause.causeVal)
+
+               e2apMsg.msgG.E2APSubscriptionDeleteRequiredRequests = append(e2apMsg.msgG.E2APSubscriptionDeleteRequiredRequests, ricSubsToBeRemove)
+       }
+
+       return nil, e2apMsg.msgG
+}
+
+func (e2apMsg *e2apMsgPackerSubscriptionDeleteRequired) String() string {
+       var b bytes.Buffer
+       for idx := 0; idx < int(e2apMsg.msgC.noOfRanSubscriptions); idx++ {
+               fmt.Fprintln(&b, "ricSubscriptionDeleteRequired.")
+               fmt.Fprintln(&b, "  ricRequestID.")
+               fmt.Fprintln(&b, "    ricRequestorID =", e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ricRequestID.ricRequestorID)
+               fmt.Fprintln(&b, "    ricInstanceID =", e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ricRequestID.ricInstanceID)
+               fmt.Fprintln(&b, "  ranFunctionID =", e2apMsg.msgC.ranSubscriptionsDelRequired[idx].ranFunctionID)
+       }
+
+       return b.String()
+}
+
 //-----------------------------------------------------------------------------
 //
 //-----------------------------------------------------------------------------
@@ -1150,6 +1243,11 @@ func (*cppasn1E2APPacker) NewPackerSubscriptionDeleteFailure() e2ap.E2APMsgPacke
        return &e2apMsgPackerSubscriptionDeleteFailure{}
 }
 
+// Changes to support "RIC_SUB_DEL_REQUIRED"
+func (*cppasn1E2APPacker) NewPackerSubscriptionDeleteRequired() e2ap.E2APMsgPackerSubscriptionDeleteRequiredIf {
+       return &e2apMsgPackerSubscriptionDeleteRequired{}
+}
+
 func NewAsn1E2Packer() e2ap.E2APPackerIf {
        return &cppasn1E2APPacker{}
 }
index ea21995..fd2439b 100644 (file)
@@ -230,6 +230,32 @@ func (e2apMsg *utMsgPackerSubscriptionDeleteFailure) String() string {
        return "utMsgPackerSubscriptionDeleteFailure"
 }
 
+//-----------------------------------------------------------------------------
+//
+//-----------------------------------------------------------------------------
+type utMsgPackerSubscriptionDeleteRequired struct {
+       e2apMsgPackerSubscriptionDeleteFailure
+}
+
+func (e2apMsg *utMsgPackerSubscriptionDeleteRequired) init() {
+}
+
+func (e2apMsg *utMsgPackerSubscriptionDeleteRequired) Pack(data *e2ap.SubscriptionDeleteRequiredList) (error, *e2ap.PackedData) {
+       if allowAction[SUB_DEL_FAILURE] {
+               e2sub := origPackerif.NewPackerSubscriptionDeleteRequired()
+               return e2sub.Pack(data)
+       }
+       return fmt.Errorf("Error: Set to be fail by UT"), nil
+}
+
+func (e2apMsg *utMsgPackerSubscriptionDeleteRequired) UnPack(msg *e2ap.PackedData) (error, *e2ap.SubscriptionDeleteRequiredList) {
+       if allowAction[SUB_DEL_FAILURE] {
+               e2sub := origPackerif.NewPackerSubscriptionDeleteRequired()
+               return e2sub.UnPack(msg)
+       }
+       return fmt.Errorf("Error: Set to be fail by UT"), nil
+}
+
 //-----------------------------------------------------------------------------
 // Public E2AP packer creators
 //-----------------------------------------------------------------------------
@@ -260,6 +286,10 @@ func (*utAsn1E2APPacker) NewPackerSubscriptionDeleteFailure() e2ap.E2APMsgPacker
        return &utMsgPackerSubscriptionDeleteFailure{}
 }
 
+func (p *utAsn1E2APPacker) NewPackerSubscriptionDeleteRequired() e2ap.E2APMsgPackerSubscriptionDeleteRequiredIf {
+       return &utMsgPackerSubscriptionDeleteRequired{}
+}
+
 func NewUtAsn1E2APPacker() e2ap.E2APPackerIf {
        return &utAsn1E2APPacker{}
 }
diff --git a/go.mod b/go.mod
index 703be55..aef4a74 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -4,7 +4,7 @@ go 1.18
 
 replace gerrit.o-ran-sc.org/r/ric-plt/sdlgo => gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.8.0
 
-replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.3
+replace gerrit.o-ran-sc.org/r/ric-plt/xapp-frame => gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.16
 
 replace gerrit.o-ran-sc.org/r/com/golog => gerrit.o-ran-sc.org/r/com/golog.git v0.0.2
 
@@ -15,59 +15,10 @@ require (
        gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.1
        gerrit.o-ran-sc.org/r/ric-plt/sdlgo v0.8.0
        gerrit.o-ran-sc.org/r/ric-plt/xapp-frame v0.0.0-00010101000000-000000000000
-       github.com/go-openapi/errors v0.19.3
        github.com/go-openapi/runtime v0.19.4
        github.com/go-openapi/strfmt v0.19.4
-       github.com/go-openapi/swag v0.19.7
-       github.com/go-openapi/validate v0.19.6
        github.com/gorilla/mux v1.7.1
        github.com/segmentio/ksuid v1.0.3
        github.com/spf13/viper v1.4.0
        github.com/stretchr/testify v1.5.1
 )
-
-require (
-       gerrit.o-ran-sc.org/r/com/golog v0.0.2 // indirect
-       gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm v0.5.0 // indirect
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.2.1 // indirect
-       gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1 // indirect
-       github.com/PuerkitoBio/purell v1.1.1 // indirect
-       github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
-       github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
-       github.com/beorn7/perks v1.0.0 // indirect
-       github.com/davecgh/go-spew v1.1.1 // indirect
-       github.com/docker/go-units v0.4.0 // indirect
-       github.com/fsnotify/fsnotify v1.4.9 // indirect
-       github.com/go-openapi/analysis v0.19.5 // indirect
-       github.com/go-openapi/jsonpointer v0.19.3 // indirect
-       github.com/go-openapi/jsonreference v0.19.3 // indirect
-       github.com/go-openapi/loads v0.19.4 // indirect
-       github.com/go-openapi/spec v0.19.3 // indirect
-       github.com/go-redis/redis v6.15.9+incompatible // indirect
-       github.com/go-stack/stack v1.8.0 // indirect
-       github.com/golang/protobuf v1.4.2 // indirect
-       github.com/hashicorp/hcl v1.0.0 // indirect
-       github.com/jessevdk/go-flags v1.4.0 // indirect
-       github.com/magiconair/properties v1.8.0 // indirect
-       github.com/mailru/easyjson v0.7.0 // indirect
-       github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
-       github.com/mitchellh/mapstructure v1.1.2 // indirect
-       github.com/pelletier/go-toml v1.2.0 // indirect
-       github.com/pmezard/go-difflib v1.0.0 // indirect
-       github.com/prometheus/client_golang v0.9.3 // indirect
-       github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 // indirect
-       github.com/prometheus/common v0.4.0 // indirect
-       github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 // indirect
-       github.com/spf13/afero v1.2.2 // indirect
-       github.com/spf13/cast v1.3.0 // indirect
-       github.com/spf13/jwalterweatherman v1.0.0 // indirect
-       github.com/spf13/pflag v1.0.3 // indirect
-       github.com/stretchr/objx v0.2.0 // indirect
-       go.mongodb.org/mongo-driver v1.1.2 // indirect
-       golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 // indirect
-       golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 // indirect
-       golang.org/x/text v0.3.2 // indirect
-       google.golang.org/protobuf v1.23.0 // indirect
-       gopkg.in/yaml.v2 v2.3.0 // indirect
-       k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect
-)
diff --git a/go.sum b/go.sum
index c36348a..a75d8f1 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -1,8 +1,8 @@
 cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
 gerrit.o-ran-sc.org/r/com/golog.git v0.0.2 h1:Ix6SgFuzd6yW6Ur6+qDlGhDO65UYs8PiIkeAL1VaQ2o=
 gerrit.o-ran-sc.org/r/com/golog.git v0.0.2/go.mod h1:A7hUL52YQSO4dFIZNcj76XQ09C9PftAe3LyL7kqBnok=
-gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm v0.5.0 h1:OKDsIDlttbaoHwleyjflIWVZPgPvYbDhim6gWF0zf5E=
-gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm v0.5.0/go.mod h1:AdEWKtERGvOQy9ybLhyhrb9w9LLVn8i9xzTwoR5n4BY=
+gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm v0.5.1-0.20211223104552-f7d2cf80e85c h1:37zz2XYjQHw7G5EJf7WxBNaxbH6fk0qBkpDwq4GNoP4=
+gerrit.o-ran-sc.org/r/ric-plt/alarm-go.git/alarm v0.5.1-0.20211223104552-f7d2cf80e85c/go.mod h1:4bLQ7iuVwDrQPdgv5CgSwJJQpYmWqt6cVPp5v7wbhbc=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.2.1 h1:3FFbXx55BODThXfyWAiz6cPXVELXFICDQUmJi13EoxM=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common v1.2.1/go.mod h1:QJ1uPPZosGbhxUWpUpeM5fLqFHdnWTrVnvW2DgyOCes=
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities v1.2.1 h1:8Z60JRsPgcS1Ona4fEh6d0/03nLq1WHoZcNnBsni5+g=
@@ -11,8 +11,8 @@ gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1 h1:BG3kste8PLVTG0m8CR
 gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader v1.2.1/go.mod h1:zX8rW6YEsagHrRGVW5YO50Ku/Csrpzsuvblhr4DbYi4=
 gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.8.0 h1:H7GtCRC+pGn6oOxYalUZr7LinQX5jQCVa+ConX7PB5Q=
 gerrit.o-ran-sc.org/r/ric-plt/sdlgo.git v0.8.0/go.mod h1:KCHu4JkWnw2Ro6P747wU9S2t7zxFLmBNCiYvGZo3CHo=
-gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.3 h1:JokT2aaJkKjYFMayvZHvGb+/IhkqZdnxEdwOZVfzIpg=
-gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.3/go.mod h1:foKMPQZ+RlM0Pos2GlEPAg6ux7Y9PRQmCUglYM7/Qt8=
+gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.16 h1:sXJSaCU8m2CXqX5JnqWAfV8hlM6snPfVihkHS/ygM2A=
+gerrit.o-ran-sc.org/r/ric-plt/xapp-frame.git v0.9.16/go.mod h1:M8cnd1lgNS0Rtf9X/bD+jYoHg1Uee5gpdt4Fv46EkKM=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
index 706dc3b..3dacc59 100755 (executable)
@@ -362,7 +362,7 @@ func (c *Control) HandleUncompletedSubscriptions(register map[uint32]*Subscripti
                        if subs.PolicyUpdate == false {
                                subs.NoRespToXapp = true
                                xapp.Logger.Debug("SendSubscriptionDeleteReq. subId = %v", subId)
-                               c.SendSubscriptionDeleteReq(subs)
+                               c.SendSubscriptionDeleteReq(subs, false)
                        }
                }
        }
@@ -944,6 +944,8 @@ func (c *Control) Consume(msg *xapp.RMRParams) (err error) {
                go c.handleE2TSubscriptionDeleteResponse(msg)
        case xapp.RIC_SUB_DEL_FAILURE:
                go c.handleE2TSubscriptionDeleteFailure(msg)
+       case xapp.RIC_SUB_DEL_REQUIRED:
+               go c.handleE2TSubscriptionDeleteRequired(msg)
        default:
                xapp.Logger.Debug("Unknown Message Type '%d', discarding", msg.Mtype)
        }
@@ -1521,7 +1523,7 @@ func (c *Control) RemoveRESTSubscriptionFromDb(restSubId string) {
        }
 }
 
-func (c *Control) SendSubscriptionDeleteReq(subs *Subscription) {
+func (c *Control) SendSubscriptionDeleteReq(subs *Subscription, e2SubsDelRequired bool) {
 
        if c.UTTesting == true {
                // Reqistry mutex is not locked after real restart but it can be when restart is simulated in unit tests
@@ -1553,7 +1555,11 @@ func (c *Control) SendSubscriptionDeleteReq(subs *Subscription) {
                        params.Payload = payload.Buf
                        params.Mbuf = nil
                        subs.DeleteFromDb = true
-                       c.handleXAPPSubscriptionDeleteRequest(params)
+                       if !e2SubsDelRequired {
+                               c.handleXAPPSubscriptionDeleteRequest(params)
+                       } else {
+                               c.SendSubscriptionDeleteReqToE2T(subs, params)
+                       }
                }
        }
 }
@@ -1627,3 +1633,83 @@ func (c *Control) PrintRESTSubscriptionRequest(p *models.SubscriptionParams) {
                }
        }
 }
+
+//-------------------------------------------------------------------
+// handle from E2T Subscription Delete Required
+//-------------------------------------------------------------------
+func (c *Control) handleE2TSubscriptionDeleteRequired(params *xapp.RMRParams) {
+       xapp.Logger.Info("MSG from E2T: %s", params.String())
+       c.UpdateCounter(cSubDelRequFromE2)
+       subsDelRequMsg, err := c.e2ap.UnpackSubscriptionDeleteRequired(params.Payload)
+       if err != nil {
+               xapp.Logger.Error("MSG-SubDelRequired: %s", idstring(err, params))
+               //c.sendE2TErrorIndication(nil)
+               return
+       }
+       var subscriptions = map[string][]e2ap.E2APSubscriptionDeleteRequired{}
+       var subDB = []*Subscription{}
+       for _, subsTobeRemove := range subsDelRequMsg.E2APSubscriptionDeleteRequiredRequests {
+               subs, err := c.registry.GetSubscriptionFirstMatch([]uint32{subsTobeRemove.RequestId.InstanceId})
+               if err != nil {
+                       xapp.Logger.Error("MSG-SubDelFail: %s", idstring(err, params))
+                       continue
+               }
+               // Check if Delete Subscription Already triggered
+               if subs.OngoingDelCount > 0 {
+                       continue
+               }
+               subDB = append(subDB, subs)
+               for _, endpoint := range subs.EpList.Endpoints {
+                       subscriptions[endpoint.Addr] = append(subscriptions[endpoint.Addr], subsTobeRemove)
+               }
+               // Sending Subscription Delete Request to E2T
+               //      c.SendSubscriptionDeleteReq(subs, true)
+       }
+       for _, subsTobeRemove := range subDB {
+               // Sending Subscription Delete Request to E2T
+               c.SendSubscriptionDeleteReq(subsTobeRemove, true)
+       }
+}
+
+//-----------------------------------------------------------------
+// Initiate RIC Subscription Delete Request after receiving
+// RIC Subscription Delete Required from E2T
+//-----------------------------------------------------------------
+func (c *Control) SendSubscriptionDeleteReqToE2T(subs *Subscription, params *xapp.RMRParams) {
+       xapp.Logger.Debug("MSG TO E2T: %s", params.String())
+       c.UpdateCounter(cSubDelReqToE2)
+
+       if c.e2IfState.IsE2ConnectionUp(&params.Meid.RanName) == false {
+               xapp.Logger.Error("No E2 connection for ranName %v", params.Meid.RanName)
+               return
+       }
+
+       trans := c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subs.ReqId.RequestId, params.Meid)
+       if trans == nil {
+               xapp.Logger.Error("XAPP-SubDelReq: %s", idstring(fmt.Errorf("transaction not created"), params))
+               return
+       }
+       defer trans.Release()
+
+       err := c.tracker.Track(trans)
+       if err != nil {
+               xapp.Logger.Error("XAPP-SubReq: %s", idstring(err, trans))
+               return
+       }
+
+       //
+       // Wake subs delete
+       //
+       subs.OngoingDelCount++
+       go c.handleSubscriptionDelete(subs, trans, waitRouteCleanup_ms)
+       trans.WaitEvent(0) //blocked wait as timeout is handled in subs side
+       subs.OngoingDelCount--
+
+       xapp.Logger.Debug("XAPP-SubDelReq: Handling event %s ", idstring(nil, trans, subs))
+
+       if subs.NoRespToXapp == true {
+               // Do no send delete responses to xapps due to submgr restart is deleting uncompleted subscriptions
+               xapp.Logger.Debug("XAPP-SubDelReq: subs.NoRespToXapp == true")
+               return
+       }
+}
index 93bd42d..ae8c999 100644 (file)
@@ -266,3 +266,24 @@ func (e *E2ap) PackSubscriptionDeleteFailure(req *e2ap.E2APSubscriptionDeleteFai
        return xapp.RIC_SUB_DEL_FAILURE, packedData, nil
 }
 */
+
+//-----------------------------------------------------------------------------
+// Changes to support "RIC_SUB_DEL_REQUIRED"
+//-----------------------------------------------------------------------------
+func (c *E2ap) UnpackSubscriptionDeleteRequired(payload []byte) (*e2ap.SubscriptionDeleteRequiredList, error) {
+       e2SubDelRequ := packerif.NewPackerSubscriptionDeleteRequired()
+       err, subsToBeRemove := e2SubDelRequ.UnPack(&e2ap.PackedData{payload})
+       if err != nil {
+               return nil, fmt.Errorf("%s buf[%s]", err.Error(), hex.EncodeToString(payload))
+       }
+       return subsToBeRemove, nil
+}
+
+func (c *E2ap) PackSubscriptionDeleteRequired(req *e2ap.SubscriptionDeleteRequiredList) (int, *e2ap.PackedData, error) {
+       e2SubDelRequ := packerif.NewPackerSubscriptionDeleteRequired()
+       err, packedData := e2SubDelRequ.Pack(req)
+       if err != nil {
+               return 0, nil, err
+       }
+       return xapp.RIC_SUB_DEL_REQUIRED, packedData, nil
+}
index 12f3f8e..4b1b12e 100644 (file)
@@ -34,6 +34,7 @@ const (
        cSubDelRespFromE2       string = "SubDelRespFromE2"
        cSubDelFailFromE2       string = "SubDelFailFromE2"
        cSubDelReqTimerExpiry   string = "SubDelReqTimerExpiry"
+       cSubDelRequFromE2       string = "SubDelRequiredFromE2"
        cRouteDeleteFail        string = "RouteDeleteFail"
        cRouteDeleteUpdateFail  string = "RouteDeleteUpdateFail"
        cUnmergedSubscriptions  string = "UnmergedSubscriptions"
@@ -79,6 +80,7 @@ func GetMetricsOpts() []xapp.CounterOpts {
                {Name: cSubDelRespFromE2, Help: "The total number of SubscriptionDeleteResponse messages from E2Term"},
                {Name: cSubDelFailFromE2, Help: "The total number of SubscriptionDeleteFailure messages from E2Term"},
                {Name: cSubDelReqTimerExpiry, Help: "The total number of SubscriptionDeleteRequest timer expires"},
+               {Name: cSubDelRequFromE2, Help: "The total number of SubscriptionDeleteRequired messages from E2Term"},
                {Name: cRouteDeleteFail, Help: "The total number of subscription route delete failure"},
                {Name: cRouteDeleteUpdateFail, Help: "The total number of subscription route delete update failure"},
                {Name: cUnmergedSubscriptions, Help: "The total number of unmerged Subscriptions"},
index 5ad6723..bf44a62 100644 (file)
@@ -55,6 +55,7 @@ func TestAddAllCountersOnce(t *testing.T) {
                Counter{cSubDelRespFromE2, 1},
                Counter{cSubDelFailFromE2, 1},
                Counter{cSubDelReqTimerExpiry, 1},
+               Counter{cSubDelRequFromE2, 1},
                Counter{cRouteDeleteFail, 1},
                Counter{cRouteDeleteUpdateFail, 1},
                Counter{cUnmergedSubscriptions, 1},
@@ -93,6 +94,7 @@ func TestAddAllCountersOnce(t *testing.T) {
        mainCtrl.c.UpdateCounter(cSubDelRespFromE2)
        mainCtrl.c.UpdateCounter(cSubDelFailFromE2)
        mainCtrl.c.UpdateCounter(cSubDelReqTimerExpiry)
+       mainCtrl.c.UpdateCounter(cSubDelRequFromE2)
        mainCtrl.c.UpdateCounter(cRouteDeleteFail)
        mainCtrl.c.UpdateCounter(cRouteDeleteUpdateFail)
        mainCtrl.c.UpdateCounter(cUnmergedSubscriptions)
diff --git a/pkg/control/ut_ric_subs_del_reqd_test.go b/pkg/control/ut_ric_subs_del_reqd_test.go
new file mode 100644 (file)
index 0000000..b844eb4
--- /dev/null
@@ -0,0 +1,206 @@
+package control
+
+import (
+       "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
+       "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststub"
+       "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
+       "github.com/stretchr/testify/assert"
+       "testing"
+       "time"
+)
+
+func initMock() *Control {
+
+       var payload = []byte{0, 8, 0, 50, 0, 0, 3, 0, 29, 0, 5, 0, 0, 3, 0, 159, 0, 5, 0, 2, 0, 2, 0, 30, 0, 28, 0, 7, 8, 0, 0, 5, 0, 0, 0, 0, 0, 19, 64, 14, 64, 122, 32, 10, 0, 1, 4, 64, 0, 0, 0, 0, 0, 23}
+       var payload1 = []byte{0, 8, 0, 50, 0, 0, 3, 0, 29, 0, 5, 0, 0, 3, 0, 160, 0, 5, 0, 2, 0, 2, 0, 30, 0, 28, 0, 7, 8, 0, 0, 5, 0, 0, 0, 0, 0, 19, 64, 14, 64, 122, 32, 10, 0, 2, 4, 64, 0, 0, 0, 0, 0, 23}
+       meid := &xapp.RMRMeid{}
+       meid.RanName = "RAN_NAME_20"
+       var params = &xapp.RMRParams{
+               Mtype:      12023,
+               Payload:    payload,
+               PayloadLen: len(payload),
+               Meid:       meid,
+               Xid:        "457945551669",
+               SubId:      -1,
+               Src:        "service-ricplt-e2term-rmr-alpha.ricplt:38000",
+               Mbuf:       nil,
+               Whid:       0,
+               Callid:     0,
+               Timeout:    0,
+       }
+       C1 := &Control{
+               RMRClient:         mainCtrl.c.RMRClient,
+               e2ap:              mainCtrl.c.e2ap,
+               registry:          mainCtrl.c.registry,
+               tracker:           mainCtrl.c.tracker,
+               restDuplicateCtrl: mainCtrl.c.restDuplicateCtrl,
+               e2IfState:         mainCtrl.c.e2IfState,
+               e2IfStateDb:       mainCtrl.c.e2IfStateDb,
+               e2SubsDb:          mainCtrl.c.e2SubsDb,
+               restSubsDb:        mainCtrl.c.restSubsDb,
+               CntRecvMsg:        mainCtrl.c.CntRecvMsg,
+               ResetTestFlag:     mainCtrl.c.ResetTestFlag,
+               Counters:          mainCtrl.c.Counters,
+               LoggerLevel:       mainCtrl.c.LoggerLevel,
+               UTTesting:         mainCtrl.c.UTTesting,
+       }
+
+       subReqMsg, _ := C1.e2ap.UnpackSubscriptionRequest(params.Payload)
+       subReqMsg1, _ := C1.e2ap.UnpackSubscriptionRequest(payload1)
+
+       trans := C1.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subReqMsg.RequestId, params.Meid)
+       trans1 := C1.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subReqMsg1.RequestId, params.Meid)
+
+       for _, acts := range subReqMsg.ActionSetups {
+               acts.ActionType = e2ap.E2AP_ActionTypeInsert
+       }
+       for _, acts := range subReqMsg1.ActionSetups {
+               acts.ActionType = e2ap.E2AP_ActionTypeInsert
+       }
+       _, _, _ = C1.registry.AssignToSubscription(trans, subReqMsg, C1.ResetTestFlag, C1, true)
+       _, _, _ = C1.registry.AssignToSubscription(trans1, subReqMsg1, C1.ResetTestFlag, C1, true)
+
+       controlObj := testingSubmgrControl{
+               RmrControl: teststub.RmrControl{},
+               c:          C1,
+       }
+       handler := controlObj.c
+       return handler
+}
+
+func TestControl_handleE2TSubscriptionDeleteRequired(t *testing.T) {
+       handler := initMock()
+       var payload = []byte{0, 12, 64, 20, 0, 0, 1, 0, 50, 64, 13, 1, 0, 51, 64, 8, 0, 0, 123, 0, 1, 0, 2, 86}
+       meid := &xapp.RMRMeid{}
+       meid.RanName = "RAN_NAME_20"
+       var params = &xapp.RMRParams{
+               Mtype:      12023,
+               Payload:    payload,
+               PayloadLen: len(payload),
+               Meid:       meid,
+               Xid:        "457945551669",
+               SubId:      -1,
+               Src:        "service-ricplt-e2term-rmr-alpha.ricplt:38000",
+               Mbuf:       nil,
+               Whid:       0,
+               Callid:     0,
+               Timeout:    0,
+       }
+       type fields struct {
+               RMRClient         *xapp.RMRClient
+               e2ap              *E2ap
+               registry          *Registry
+               tracker           *Tracker
+               restDuplicateCtrl *DuplicateCtrl
+               e2IfState         *E2IfState
+               e2IfStateDb       XappRnibInterface
+               e2SubsDb          Sdlnterface
+               restSubsDb        Sdlnterface
+               CntRecvMsg        uint64
+               ResetTestFlag     bool
+               Counters          map[string]xapp.Counter
+               LoggerLevel       int
+               UTTesting         bool
+       }
+       type args struct {
+               params *xapp.RMRParams
+       }
+       tests := []struct {
+               name   string
+               fields fields
+               args   args
+       }{
+               {
+                       name: "abc",
+                       fields: fields{
+                               RMRClient:         handler.RMRClient,
+                               e2ap:              handler.e2ap,
+                               registry:          handler.registry,
+                               tracker:           handler.tracker,
+                               restDuplicateCtrl: handler.restDuplicateCtrl,
+                               e2IfState:         handler.e2IfState,
+                               e2IfStateDb:       handler.e2IfStateDb,
+                               e2SubsDb:          handler.e2SubsDb,
+                               restSubsDb:        handler.restSubsDb,
+                               CntRecvMsg:        handler.CntRecvMsg,
+                               ResetTestFlag:     handler.ResetTestFlag,
+                               Counters:          handler.Counters,
+                               LoggerLevel:       handler.LoggerLevel,
+                               UTTesting:         handler.UTTesting,
+                       },
+
+                       args: args{params: params},
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       c := &Control{
+                               RMRClient:         tt.fields.RMRClient,
+                               e2ap:              tt.fields.e2ap,
+                               registry:          tt.fields.registry,
+                               tracker:           tt.fields.tracker,
+                               restDuplicateCtrl: tt.fields.restDuplicateCtrl,
+                               e2IfState:         tt.fields.e2IfState,
+                               e2IfStateDb:       tt.fields.e2IfStateDb,
+                               e2SubsDb:          tt.fields.e2SubsDb,
+                               restSubsDb:        tt.fields.restSubsDb,
+                               CntRecvMsg:        tt.fields.CntRecvMsg,
+                               ResetTestFlag:     tt.fields.ResetTestFlag,
+                               Counters:          tt.fields.Counters,
+                               LoggerLevel:       tt.fields.LoggerLevel,
+                               UTTesting:         tt.fields.UTTesting,
+                       }
+                       c.e2IfState.NbIdMap[params.Meid.RanName] = "_CONNECTED"
+                       c.handleE2TSubscriptionDeleteRequired(tt.args.params)
+                       subs, _ := c.registry.GetSubscriptionFirstMatch([]uint32{uint32(1)})
+                       subs1, _ := c.registry.GetSubscriptionFirstMatch([]uint32{uint32(2)})
+                       assert.Nil(t, subs)
+                       assert.NotNil(t, subs1)
+                       time.Sleep(1 * time.Second)
+               })
+       }
+}
+
+func TestE2ap_UnpackSubscriptionDeleteRequired(t *testing.T) {
+       var payload = []byte{0, 12, 64, 20, 0, 0, 1, 0, 50, 64, 13, 1, 0, 51, 64, 8, 0, 0, 123, 0, 1, 0, 2, 86}
+       var e2ap1 = E2ap{}
+       list, _ := e2ap1.UnpackSubscriptionDeleteRequired(payload)
+       expectedList := &e2ap.SubscriptionDeleteRequiredList{E2APSubscriptionDeleteRequiredRequests: []e2ap.E2APSubscriptionDeleteRequired{{
+               RequestId: e2ap.RequestId{
+                       Id:         123,
+                       InstanceId: 1,
+               },
+               FunctionId: 2,
+               Cause: e2ap.Cause{
+                       Content: 6,
+                       Value:   3,
+               },
+       }}}
+       assert.Equal(t, expectedList, list)
+}
+func TestE2ap_UnpackSubscriptionDeleteRequiredForWrongPayload(t *testing.T) {
+       var payload = []byte{12, 64, 20, 0, 0, 1, 0, 50, 64, 13, 1, 0, 51, 64, 8, 0, 0, 123, 0, 1, 0, 2, 86}
+       var e2ap1 = E2ap{}
+       _, err := e2ap1.UnpackSubscriptionDeleteRequired(payload)
+       assert.NotNil(t, err)
+
+}
+
+func TestE2ap_PackSubscriptionDeleteRequired(t *testing.T) {
+       list := &e2ap.SubscriptionDeleteRequiredList{E2APSubscriptionDeleteRequiredRequests: []e2ap.E2APSubscriptionDeleteRequired{{
+               RequestId: e2ap.RequestId{
+                       Id:         123,
+                       InstanceId: 1,
+               },
+               FunctionId: 2,
+               Cause: e2ap.Cause{
+                       Content: 6,
+                       Value:   3,
+               },
+       }}}
+       e2ap1 := E2ap{}
+       payload1 := []byte{0, 12, 64, 20, 0, 0, 1, 0, 50, 64, 13, 1, 0, 51, 64, 8, 0, 0, 123, 0, 1, 0, 2, 86}
+       payload := &e2ap.PackedData{Buf: payload1}
+       _, packedata, _ := e2ap1.PackSubscriptionDeleteRequired(list)
+       assert.Equal(t, payload, packedata)
+}