+/*******************************************************************
+ *
+ * @brief Free RIC Subscription Delete Request Message
+ *
+ * @details
+ *
+ * Function : freeAperDecodingOfRicSubsDeleteReq
+ *
+ * Functionality: Free RIC Subscription Delete Request
+ *
+ * @param E2AP Message PDU
+ * @return void
+ *
+ ******************************************************************/
+void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg)
+{
+ uint8_t ieIdx = 0;
+ RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
+
+ if(e2apMsg)
+ {
+ if(e2apMsg->choice.initiatingMessage)
+ {
+ ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
+ if(ricSubsDelReq->protocolIEs.list.array)
+ {
+ for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
+ {
+ if(ricSubsDelReq->protocolIEs.list.array[ieIdx])
+ {
+ free(ricSubsDelReq->protocolIEs.list.array[ieIdx]);
+ }
+ }
+ free(ricSubsDelReq->protocolIEs.list.array);
+ }
+ }
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Process RIC Subscription delete request
+ *
+ * @details
+ *
+ * Function : procRicSubscriptionDeleteRequest
+ *
+ * Functionality: Process RIC subscription delete request.
+ * Fetch RAN Function and RIC subscription to be deleted.
+ * Send statistics delete request to MAC for all action sequence
+ * within this RIC subscription.
+ *
+ * @params[in] E2AP PDU
+ * @return void
+ *
+ ******************************************************************/
+void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg)
+{
+ uint8_t ieIdx = 0;
+ uint16_t ranFuncId = 0;
+ bool procFailure = false;
+ RicRequestId ricReqId;
+ RanFunction *ranFuncDb = NULLP;
+ CmLList *ricSubsNode = NULLP;
+ RicSubscription *ricSubsDb = NULLP;
+ RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP;
+ RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP;
+
+ DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Delete Request", __func__);
+
+ do{
+ if(!e2apMsg)
+ {
+ DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__);
+ break;
+ }
+
+ if(!e2apMsg->choice.initiatingMessage)
+ {
+ DU_LOG("\nERROR --> E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__);
+ break;
+ }
+
+ ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest;
+ if(!ricSubsDelReq->protocolIEs.list.array)
+ {
+ DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__);
+ break;
+ }
+
+ for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++)
+ {
+ if(!ricSubsDelReq->protocolIEs.list.array[ieIdx])
+ {
+ DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx);
+ break;
+ }
+
+ ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx];
+ switch(ricSubsDelReqIe->id)
+ {
+ case ProtocolIE_IDE2_id_RICrequestID:
+ {
+ memset(&ricReqId, 0, sizeof(RicRequestId));
+ ricReqId.requestorId = ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID;
+ ricReqId.instanceId = ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID;
+ break;
+ }
+
+ case ProtocolIE_IDE2_id_RANfunctionID:
+ {
+ ranFuncId = ricSubsDelReqIe->value.choice.RANfunctionID;
+ ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId);
+ if(!ranFuncDb)
+ {
+ DU_LOG("\nERROR --> E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId);
+ procFailure = true;
+ break;
+ }
+
+ ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode);
+ if(!ricSubsDb)
+ {
+ DU_LOG("\nERROR --> E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\
+ __func__, ricReqId.requestorId, ricReqId.instanceId);
+ procFailure = true;
+ break;
+ }
+
+ //TODO : Send statistics delete request to MAC
+ break;
+ }
+
+ default:
+ break;
+ } /* End of switch for Protocol IE Id */
+
+ if(procFailure)
+ break;
+ } /* End of for loop for Protocol IE list */
+
+ break;
+ }while(true);
+
+ freeAperDecodingOfRicSubsDeleteReq(e2apMsg);
+ return;
+}
+
+/*******************************************************************
+ *
+ * @brief Deallocate the memory allocated for E2 node configuration
+ * update ack msg by aper decoder
+ *
+ * @details
+ *
+ * Function : freeAperDecodingOfE2NodeConfigUpdateAck
+ *
+ * Functionality:
+ * - Deallocate the memory allocated for E2 node configuration
+ * update ack msg by aper decoder
+ *
+ * @params[in] E2AP_PDU_t *e2apMsg
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+
+void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg)
+{
+ uint8_t arrIdx =0, e2NodeConfigIdx=0;
+ E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL;
+ E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL;
+ E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL;
+ E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL;
+ E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL;
+ E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL;
+
+ E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP;
+ if(updateAckMsg->protocolIEs.list.array != NULLP)
+ {
+ for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++)
+ {
+ if(updateAckMsg->protocolIEs.list.array[arrIdx])
+ {
+ switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id)
+ {
+ case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
+ {
+ additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
+ if(additionAckList->list.array)
+ {
+ for(e2NodeConfigIdx=0; e2NodeConfigIdx<additionAckList->list.count; e2NodeConfigIdx++)
+ {
+ additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx];
+ if(additionAckItemIte)
+ {
+ switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present)
+ {
+ case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
+ {
+ f1InterfaceInfo = additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
+ free(f1InterfaceInfo->gNB_DU_ID.buf);
+ free(f1InterfaceInfo);
+ break;
+ }
+ default:
+ break;
+ }
+ free(additionAckItemIte);
+ }
+ free(additionAckList->list.array);
+ }
+ break;
+ }
+ }
+ case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
+ {
+ updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
+ if(updateAckList->list.array)
+ {
+ for(e2NodeConfigIdx=0; e2NodeConfigIdx<updateAckList->list.count; e2NodeConfigIdx++)
+ {
+ updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx];
+ if(updateAckItemIe)
+ {
+ switch(updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.present)
+ {
+ case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
+ {
+ f1InterfaceInfo = updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
+ free(f1InterfaceInfo->gNB_DU_ID.buf);
+ free(f1InterfaceInfo);
+ break;
+ }
+ default:
+ break;
+ }
+ free(updateAckItemIe);
+ }
+ }
+ free(updateAckList->list.array);
+ }
+ break;
+ }
+ case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
+ {
+ removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
+ if(removalAckList->list.array)
+ {
+ for(e2NodeConfigIdx=0; e2NodeConfigIdx<removalAckList->list.count; e2NodeConfigIdx++)
+ {
+ removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx];
+ if(removalAckItemIe)
+ {
+ switch(removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.present)
+ {
+ case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1:
+ {
+ f1InterfaceInfo = removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1;
+ free(f1InterfaceInfo->gNB_DU_ID.buf);
+ free(f1InterfaceInfo);
+ break;
+ }
+ default:
+ break;
+ }
+ free(removalAckItemIe);
+ }
+ }
+ free(removalAckList->list.array);
+ }
+ break;
+ }
+ }
+ free(updateAckMsg->protocolIEs.list.array[arrIdx]);
+ }
+ }
+ free(updateAckMsg->protocolIEs.list.array);
+ }
+}
+
+/******************************************************************
+ *
+ * @brief Processes the E2 node config update ack msg
+ *
+ * @details
+ *
+ * Function :procE2NodeConfigUpdateAck
+ *
+ * Functionality: Processes the E2 node config update ack msg
+ *
+ * @params[in] E2AP_PDU_t ASN decoded E2AP message
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+
+void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg)
+{
+ uint8_t arrIdx =0;
+ uint16_t e2CfgIdx =0;
+ E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck =NULLP;
+ E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList=NULLP;
+ E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULLP;
+ E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList=NULLP;
+ E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULLP;
+ E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULLP;
+ E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAdditionAckItem=NULLP;
+
+ e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge;
+
+ if(e2NodeConfigUpdateAck->protocolIEs.list.array)
+ {
+ for(arrIdx =0; arrIdx<e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++)
+ {
+ switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id)
+ {
+ case ProtocolIE_IDE2_id_TransactionID:
+ {
+ break;
+ }
+ case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck:
+ {
+ e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List;
+ if(e2NodeConfigAdditionAckList->list.array)
+ {
+ for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigAdditionAckList->list.count; e2CfgIdx++)
+ {
+ e2NodeAdditionAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2CfgIdx];
+ handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAdditionAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\
+ ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck);
+ }
+ }
+ break;
+ }
+ case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck:
+ {
+ e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List;
+ if(e2NodeConfigUpdateAckList->list.array)
+ {
+ for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigUpdateAckList->list.count; e2CfgIdx++)
+ {
+ e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[e2CfgIdx];
+ handleE2NodeConfigUpdateAckIes((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item,\
+ ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck);
+ }
+ }
+ break;
+ }
+ case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck:
+ {
+ e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List;
+ if(e2NodeConfigRemovalAckList->list.array)
+ {
+ for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigRemovalAckList->list.count; e2CfgIdx++)
+ {
+ e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[e2CfgIdx];
+ handleE2NodeConfigUpdateAckIes((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item,\
+ ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck);
+}
+