X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fdu_app%2Fdu_e2ap_msg_hdl.c;h=4f04acab14891be7bad98e267477dde4c3633485;hb=61f1d2eec53a339d27c720eee5ded1869ec72fbb;hp=a1c7d8c2a9bf93fc7fd4904a006b0eefca1cf8b4;hpb=760f81397ca10d4983c4b21414edbaa13d181173;p=o-du%2Fl2.git diff --git a/src/du_app/du_e2ap_msg_hdl.c b/src/du_app/du_e2ap_msg_hdl.c index a1c7d8c2a..4f04acab1 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -26,8 +26,10 @@ #include "du_e2ap_mgr.h" #include "du_e2ap_msg_hdl.h" #include "du_cfg.h" +#include "du_sctp.h" #include "du_mgr.h" #include "du_mgr_main.h" +#include "du_msg_hdl.h" #include "du_utils.h" #include "GlobalE2node-gNB-ID.h" #include "ProtocolIE-FieldE2.h" @@ -482,7 +484,6 @@ uint8_t BuildAndSendRemovalResponse(uint16_t transId) }while(true); FreeE2RemovalResponse(e2apMsg); - removeE2NodeInformation(); return ret; } @@ -3244,6 +3245,108 @@ uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefD return RFAILED; } +/******************************************************************* + * + * @brief add RIC Subs action info + * + * @details + * + * Function : addRicSubsAction + * + * Functionality: add Ric Subs action info + * + * @parameter + * RAN function DB + * Pointer to Ric Subc info + * Action Sequence list + * Procedure Code + * E2 Failure Cause + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +CmLList *addRicSubsAction(RanFunction *ranFuncDb, PTR ricSubsInfo, CmLListCp *actionSequence, uint8_t procedureCode, E2FailureCause *failureCause) +{ + CmLList *actionNode = NULLP; + ActionInfo *actionDb = NULLP; + RICactionID_t ricActionID; + RICactionType_t ricActionType; + RICactionDefinition_t *ricActionDefinition= NULLP; + RICaction_ToBeSetup_Item_t *setupItem= NULLP; + RICaction_ToBeAddedForModification_Item_t *addIem= NULLP; + RICaction_ToBeModifiedForModification_Item_t *modifiedItem= NULLP; + + switch(procedureCode) + { + case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item: + { + setupItem = (RICaction_ToBeSetup_Item_t *)ricSubsInfo; + ricActionID= setupItem->ricActionID; + ricActionType= setupItem->ricActionType; + if(setupItem->ricActionDefinition) + { + ricActionDefinition = setupItem->ricActionDefinition; + } + break; + } + case ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item: + { + addIem = (RICaction_ToBeAddedForModification_Item_t*) ricSubsInfo; + ricActionID= addIem->ricActionID; + ricActionType= addIem->ricActionType; + ricActionDefinition = &addIem->ricActionDefinition; + + break; + } + case ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item: + { + modifiedItem= (RICaction_ToBeModifiedForModification_Item_t*)ricSubsInfo; + ricActionID= modifiedItem->ricActionID; + /* Added since ricActionType IE is not present in case of + * modification */ + ricActionType = RICactionType_report; + if(modifiedItem->ricActionDefinition) + { + ricActionDefinition = modifiedItem->ricActionDefinition; + } + break; + } + } + + + DU_ALLOC(actionDb, sizeof(ActionInfo)); + if(actionDb==NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__); + return NULLP; + } + if(ricActionType== RICactionType_report) + { + actionDb->actionId = ricActionID; + actionDb->type = REPORT; + + if(extractRicActionDef(ranFuncDb, &actionDb->definition, ricActionDefinition, failureCause) == ROK) + { + actionDb->action = CONFIG_ADD; + } + + DU_ALLOC(actionNode, sizeof(CmLList)); + if(actionNode) + { + actionNode->node = (PTR) actionDb; + cmLListAdd2Tail(actionSequence, actionNode); + } + else + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at %d",__func__,__LINE__); + DU_FREE(actionDb, sizeof(ActionInfo)); + return NULLP; + } + } + return actionNode; + +} /******************************************************************* * * @brief Extract RIC Action to be setup @@ -3266,6 +3369,7 @@ uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefD uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp) { + CmLList *actionNode = NULLP; uint8_t actionIdx = 0; uint8_t ricActionId = 0; RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP; @@ -3283,35 +3387,23 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu * If RIC action definition's extraction and validation passes, * Then : * This action is added to action sequence list of subscription info */ - ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; - - if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report) + actionNode = addRicSubsAction(ranFuncDb, (PTR)&actionItem->value.choice.RICaction_ToBeSetup_Item,\ + &ricSubscriptionInfo->actionSequence, ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item, failureCause); + + if(!actionNode) { - ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId; - ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT; - - if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \ - actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK) + /* In case of any failure, action is rejected + * Added to rejected-action-list in subscription response */ + subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId; + if(failureCause->causeType == E2_NOTHING) { - ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD; - ricSubscriptionInfo->numOfActions++; - break; + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_CONTROL_FAILED_TO_EXECUTE; } + memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \ + failureCause, sizeof(E2FailureCause)); + subsRsp->numOfRejectedActions++; } - - /* In case of any failure, action is rejected - * Added to rejected-action-list in subscription response */ - deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]); - - subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId; - if(failureCause->causeType == E2_NOTHING) - { - failureCause->causeType = E2_RIC_REQUEST; - failureCause->cause = E2_ACTION_NOT_SUPPORTED; - } - memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \ - failureCause, sizeof(E2FailureCause)); - subsRsp->numOfRejectedActions++; break; } default: @@ -3322,7 +3414,7 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu } /* If there is even 1 action that can be added, return ROK */ - if(ricSubscriptionInfo->numOfActions) + if(ricSubscriptionInfo->actionSequence.count) return ROK; if(failureCause->causeType == E2_NOTHING) @@ -3350,7 +3442,7 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu * ****************************************************************/ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) { - uint8_t idx = 0, actionIdx = 0; + uint8_t idx = 0; uint8_t ret = ROK; uint16_t ranFuncId = 0; RicRequestId ricReqId; @@ -3417,11 +3509,6 @@ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId; ricSubscriptionInfo->ranFuncId = ranFuncId; - for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) - { - ricSubscriptionInfo->actionSequence[actionIdx].actionId = -1; - } - memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo)); memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, &ricReqId, sizeof(RicRequestId)); @@ -3496,7 +3583,6 @@ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) /* Send RIC Subcription Failure */ BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause); } - return ret; } @@ -6208,10 +6294,12 @@ void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg) * RFAILED - failure * ******************************************************************/ -uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \ - RicSubscription *ricSubscription) +uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod,\ + RicSubscription *ricSubscription) { - uint8_t arrIdx = 0, actionIdx = 0; + uint8_t arrIdx = 0; + CmLList *actionNode = NULLP; + ActionInfo *actionDb = NULLP; RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL; actionToBeModList->list.count = numActionsMod; @@ -6224,9 +6312,11 @@ uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *action } arrIdx = 0; - for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + CM_LLIST_FIRST_NODE(&ricSubscription->actionSequence, actionNode); + while(actionNode) { - if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD) + actionDb = (ActionInfo*)(actionNode->node); + if(actionDb->action == CONFIG_MOD) { DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t)); if(!actionToBeModList->list.array[arrIdx]) @@ -6241,7 +6331,7 @@ uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *action actionToBeMod->value.present = \ RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item; actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \ - ricSubscription->actionSequence[actionIdx].actionId; + actionDb->actionId; actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms; arrIdx++; @@ -6251,7 +6341,6 @@ uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *action return ROK; } #endif - /******************************************************************* * * @brief Fill Action required to be removed list @@ -6272,7 +6361,9 @@ uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *action uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \ RicSubscription *ricSubscription) { - uint8_t arrIdx = 0, actionIdx = 0; + uint8_t arrIdx = 0; + CmLList *actionNode = NULLP; + ActionInfo *actionDb = NULLP; RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL; actionToBeRmvList->list.count = numActionsRmv; @@ -6285,9 +6376,11 @@ uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionT } arrIdx = 0; - for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + CM_LLIST_FIRST_NODE(&ricSubscription->actionSequence, actionNode); + while(actionNode) { - if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL) + actionDb = (ActionInfo*)(actionNode->node); + if(actionDb->action == CONFIG_DEL) { DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t)); if(!actionToBeRmvList->list.array[arrIdx]) @@ -6301,11 +6394,8 @@ uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionT actionToBeRmv->criticality = CriticalityE2_reject; actionToBeRmv->value.present = \ RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item; - actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \ - ricSubscription->actionSequence[actionIdx].actionId; - fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \ - ricSubscription->actionSequence[actionIdx].failureCause); - + actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = actionDb->actionId; + fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, actionDb->failureCause); arrIdx++; } } @@ -6331,7 +6421,9 @@ uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionT ******************************************************************/ uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription) { - uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0; + ActionInfo * actionDb=NULLP; + CmLList *actionNode = NULLP; + uint8_t ieIdx = 0, elementCnt=0; uint8_t numActionsMod = 0, numActionsRmv = 0; RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP; RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList = NULLP; @@ -6342,12 +6434,15 @@ uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsMod #endif /* Count number of Actions to be modified or deleted */ - for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + CM_LLIST_FIRST_NODE(&ricSubscription->actionSequence, actionNode); + while(actionNode) { - if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD) - numActionsMod++; - else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL) - numActionsRmv++; + actionDb = (ActionInfo*)(actionNode->node); + if(actionDb->action == CONFIG_MOD) + numActionsMod++; + else if(actionDb->action == CONFIG_DEL) + numActionsRmv++; + actionNode = actionNode->next; } /* Count number of IEs to be added to messages */ @@ -6660,6 +6755,7 @@ void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) RicRequestId ricReqId; RanFunction *ranFuncDb = NULLP; CmLList *ricSubsNode = NULLP; + CmLList *actionNode= NULLP; RicSubscription *ricSubsDb = NULLP; ActionInfo *actionDb = NULLP; @@ -6759,7 +6855,7 @@ void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx]; actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID; - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb, &actionNode, CONFIG_UNKNOWN); if(!actionDb) { DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); @@ -6782,7 +6878,7 @@ void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) { modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx]; actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID; - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb, &actionNode, CONFIG_UNKNOWN); if(!actionDb) { DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); @@ -6807,16 +6903,16 @@ void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) { rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx]; actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID; - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb, &actionNode, CONFIG_UNKNOWN); if(!actionDb) { DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); } else { - deleteActionSequence(actionDb); + cmLListDelFrm(&ricSubsDb->actionSequence, actionNode); + deleteActionSequence(actionNode); actionDb =NULLP; - ricSubsDb->numOfActions--; /* Further handling can include : * Deletion of this action from all DU layers */ @@ -6833,7 +6929,7 @@ void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) { rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx]; actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID; - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb, &actionNode, CONFIG_UNKNOWN); if(!actionDb) { DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); @@ -7513,203 +7609,541 @@ uint8_t BuildAndSendRicSubscriptionDeleteRequired() /******************************************************************* * - * @brief Free RIC Subscription Delete Request Message + * @brief Free RIC Subscription Delete Failure Message * * @details * - * Function : freeAperDecodingOfRicSubsDeleteReq + * Function : FreeRicSubscriptionDeleteFailure * - * Functionality: Free RIC Subscription Delete Request + * Functionality: Free RIC Subscription Delete Failure * * @param E2AP Message PDU * @return void * ******************************************************************/ -void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg) +void FreeRicSubscriptionDeleteFailure(E2AP_PDU_t *e2apMsg) { uint8_t ieIdx = 0; - RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP; + RICsubscriptionDeleteFailure_t *ricSubsDelFailure = NULLP; if(e2apMsg) { - if(e2apMsg->choice.initiatingMessage) + if(e2apMsg->choice.unsuccessfulOutcome) { - ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest; - if(ricSubsDelReq->protocolIEs.list.array) + ricSubsDelFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure; + if(ricSubsDelFailure->protocolIEs.list.array) { - for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++) + for(ieIdx = 0; ieIdx < ricSubsDelFailure->protocolIEs.list.count; ieIdx++) { - if(ricSubsDelReq->protocolIEs.list.array[ieIdx]) - { - free(ricSubsDelReq->protocolIEs.list.array[ieIdx]); - } + DU_FREE(ricSubsDelFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteFailure_IEs_t)); } - free(ricSubsDelReq->protocolIEs.list.array); + DU_FREE(ricSubsDelFailure->protocolIEs.list.array, ricSubsDelFailure->protocolIEs.list.size); } + DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));; } } /******************************************************************* * - * @brief Process RIC Subscription delete request + * @brief Builds and Send RIC Subscription Delete Failure * * @details * - * Function : procRicSubscriptionDeleteRequest + * Function : BuildAndSendRicSubscriptionDeleteFailure * - * 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. + * Functionality: Build and send RIC Subscription Delete Failure. * - * @params[in] E2AP PDU - * @return void + * @params[in] + * Ran Func Id + * Ric Req Id + * E2 failure cause + * @return ROK - success + * RFAILED - failure * ******************************************************************/ -void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg) +uint8_t BuildAndSendRicSubscriptionDeleteFailure(uint16_t ranFuncId, RicRequestId requestId, E2FailureCause failureCause) { - 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; + uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionDeleteFailure_t *ricSubsDelFailure = NULLP; + RICsubscriptionDeleteFailure_IEs_t *ricSubsDelFailureIe = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ - DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Delete Request", __func__); + while(true) + { + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Delete Failure Message\n"); - do{ - if(!e2apMsg) + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) { - DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } - if(!e2apMsg->choice.initiatingMessage) + e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + if(e2apMsg->choice.unsuccessfulOutcome == NULLP) { - DU_LOG("\nERROR --> E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } + e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete; + e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteFailure; - ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest; - if(!ricSubsDelReq->protocolIEs.list.array) + + ricSubsDelFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionDeleteFailure; + + elementCnt = 3; + ricSubsDelFailure->protocolIEs.list.count = elementCnt; + ricSubsDelFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteFailure_IEs_t *); + + DU_ALLOC(ricSubsDelFailure->protocolIEs.list.array, ricSubsDelFailure->protocolIEs.list.size); + if(ricSubsDelFailure->protocolIEs.list.array == NULLP) { - DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__); break; } - for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++) + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) { - if(!ricSubsDelReq->protocolIEs.list.array[ieIdx]) + DU_ALLOC(ricSubsDelFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteFailure_IEs_t)); + if(ricSubsDelFailure->protocolIEs.list.array[ieIdx] == NULLP) { - DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for index [%d] at line %d", \ + __func__, ieIdx, __LINE__); break; } + } + if(ieIdx < elementCnt) + 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; - } + ieIdx = 0; + ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx]; + ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsDelFailureIe->criticality = CriticalityE2_reject; + ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RICrequestID; + ricSubsDelFailureIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId; + ricSubsDelFailureIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId; - 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; - } + ieIdx++; + ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx]; + ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsDelFailureIe->criticality = CriticalityE2_reject; + ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_RANfunctionID; + ricSubsDelFailureIe->value.choice.RANfunctionID = ranFuncId; + + ieIdx++; + ricSubsDelFailureIe = ricSubsDelFailure->protocolIEs.list.array[ieIdx]; + ricSubsDelFailureIe->id = ProtocolIE_IDE2_id_CauseE2; + ricSubsDelFailureIe->criticality = CriticalityE2_ignore; + ricSubsDelFailureIe->value.present = RICsubscriptionDeleteFailure_IEs__value_PR_CauseE2; + fillE2Cause(&ricSubsDelFailureIe->value.choice.CauseE2, failureCause); - //TODO : Send statistics delete request to MAC - break; - } + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Delete Failure Message (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Delete Failure Message \n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); + } +#endif + } - default: - break; - } /* End of switch for Protocol IE Id */ - - if(procFailure) - break; - } /* End of for loop for Protocol IE list */ + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send RIC Susbcription Delete Failure Message"); + break; + } + ret = ROK; break; - }while(true); + } - freeAperDecodingOfRicSubsDeleteReq(e2apMsg); - return; + FreeRicSubscriptionDeleteFailure(e2apMsg); + return ret; } + /******************************************************************* * - * @brief Deallocate the memory allocated for E2 node configuration - * update ack msg by aper decoder + * @brief Free RIC Subscription Delete Response Message * * @details * - * Function : freeAperDecodingOfE2NodeConfigUpdateAck + * Function : FreeRicSubscriptionDeleteResponse * - * Functionality: - * - Deallocate the memory allocated for E2 node configuration - * update ack msg by aper decoder + * Functionality: Free RIC Subscription Delete Response * - * @params[in] E2AP_PDU_t *e2apMsg - * @return ROK - success - * RFAILED - failure + * @param E2AP Message PDU + * @return void * - * ****************************************************************/ - -void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg) + ******************************************************************/ +void FreeRicSubscriptionDeleteResponse(E2AP_PDU_t *e2apMsg) { - 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; + uint8_t ieIdx = 0; + RICsubscriptionDeleteResponse_t *ricSubsDelRsp = NULLP; - E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP; - if(updateAckMsg->protocolIEs.list.array != NULLP) + if(e2apMsg) { - for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++) + if(e2apMsg->choice.successfulOutcome) { - if(updateAckMsg->protocolIEs.list.array[arrIdx]) + ricSubsDelRsp = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse; + if(ricSubsDelRsp->protocolIEs.list.array) { - switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id) + for(ieIdx = 0; ieIdx < ricSubsDelRsp->protocolIEs.list.count; ieIdx++) { - case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: - { - additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; - if(additionAckList->list.array) - { - for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) - { - additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx]; - if(additionAckItemIte) - { - switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present) - { - case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + DU_FREE(ricSubsDelRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteResponse_IEs_t)); + } + DU_FREE(ricSubsDelRsp->protocolIEs.list.array, ricSubsDelRsp->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));; + } +} + +/******************************************************************* + * + * @brief Builds and Send RIC Subscription delete Response + * + * @details + * + * Function : BuildAndSendRicSubscriptionDeleteResponse + * + * Functionality: Build and send RIC subscription delete Response. + * + * @params[in] + * Ran Func Id + * Ric Req Id + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t BuildAndSendRicSubscriptionDeleteResponse(uint16_t ranFuncId, RicRequestId requestId) +{ + uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionDeleteResponse_t *ricSubsDelRsp = NULLP; + RICsubscriptionDeleteResponse_IEs_t *ricSubsDelRspIe = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + while(true) + { + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Delete Response Message\n"); + + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + break; + } + + e2apMsg->present = E2AP_PDU_PR_successfulOutcome; + DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(e2apMsg->choice.successfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + break; + } + e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionDelete; + e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionDeleteResponse; + + + ricSubsDelRsp = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionDeleteResponse; + + elementCnt = 2; + ricSubsDelRsp->protocolIEs.list.count = elementCnt; + ricSubsDelRsp->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteResponse_IEs_t *); + + DU_ALLOC(ricSubsDelRsp->protocolIEs.list.array, ricSubsDelRsp->protocolIEs.list.size); + if(ricSubsDelRsp->protocolIEs.list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__); + break; + } + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(ricSubsDelRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteResponse_IEs_t)); + if(ricSubsDelRsp->protocolIEs.list.array[ieIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for index [%d] at line %d", \ + __func__, ieIdx, __LINE__); + break; + } + } + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + ricSubsDelRspIe = ricSubsDelRsp->protocolIEs.list.array[ieIdx]; + ricSubsDelRspIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsDelRspIe->criticality = CriticalityE2_reject; + ricSubsDelRspIe->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RICrequestID; + ricSubsDelRspIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId; + ricSubsDelRspIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId; + + ieIdx++; + ricSubsDelRspIe = ricSubsDelRsp->protocolIEs.list.array[ieIdx]; + ricSubsDelRspIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsDelRspIe->criticality = CriticalityE2_reject; + ricSubsDelRspIe->value.present = RICsubscriptionDeleteResponse_IEs__value_PR_RANfunctionID; + ricSubsDelRspIe->value.choice.RANfunctionID = ranFuncId; + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Delete Response Message (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Delete Response Message \n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); + } +#endif + } + + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send RIC Susbcription Delete Response Message"); + break; + } + + ret = ROK; + break; + } + + FreeRicSubscriptionDeleteResponse(e2apMsg); + return ret; +} + +/******************************************************************* + * + * @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; + } + + if(BuildAndSendStatsDeleteReq(ricSubsDb, true) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send ric subscription delete req to du layers"); + } + 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; e2NodeConfigIdxlist.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); @@ -7719,304 +8153,2174 @@ void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledg default: break; } - free(additionAckItemIte); + 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; e2NodeConfigIdxlist.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; e2NodeConfigIdxlist.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; arrIdxprotocolIEs.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); +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for RemovalRequest msg + * + * @details + * + * Function : FreeRemovalRequest + * + * Functionality: + * - freeing the memory allocated for RemovalRequest + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void FreeRemovalRequest(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0; + E2RemovalRequest_t *removalReq = NULLP; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.initiatingMessage != NULLP) + { + removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest; + if(removalReq->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < removalReq->protocolIEs.list.count; ieIdx++) + { + DU_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t)); + } + DU_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Build and send the removal request msg + * + * @details + * + * Function : BuildAndSendRemovalRequest + * + * Functionality: + * - Buld and send the removal request msg to E2 node + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +uint8_t BuildAndSendRemovalRequest() +{ + uint8_t ieIdx = 0, elementCnt = 0, transId = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + E2RemovalRequest_t *removalReq = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building Removal Request\n"); + + do + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2removal; + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2RemovalRequest; + removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest; + + elementCnt = 1; + removalReq->protocolIEs.list.count = elementCnt; + removalReq->protocolIEs.list.size = elementCnt * sizeof(E2RemovalRequestIEs_t *); + + DU_ALLOC(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size); + if(!removalReq->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t)); + if(!removalReq->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + } + + /* In case of failure */ + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + removalReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + removalReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + removalReq->protocolIEs.list.array[ieIdx]->value.present = E2RemovalRequestIEs__value_PR_TransactionID; + transId = assignTransactionId(); + removalReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\ + encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode removal request structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for removal request\n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); + } +#endif + } + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Sending removal request failed"); + break; + } + + + ret = ROK; + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; + break; + }while(true); + + /* Free all memory */ + FreeRemovalRequest(e2apMsg); + + return ret; +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder + * for Removal failure + * + * @details + * + * Function : freeAperDecodingOfE2RemovalFailure + * + * Functionality: Deallocation of memory allocated by aper decoder + * for Removal failure + * + * @params[in] Pointer to removalFailure + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfE2RemovalFailure(E2RemovalFailure_t *removalFailure) +{ + uint8_t arrIdx=0; + + if(removalFailure) + { + if(removalFailure->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(removalFailure->protocolIEs.list.array[arrIdx]) + { + free(removalFailure->protocolIEs.list.array[arrIdx]); + } + } + free(removalFailure->protocolIEs.list.array); + } + } +} + +/****************************************************************** + * + * @brief Processes the E2 removal failure msg + * + * @details + * + * Function : procE2RemovalFailure + * + * Functionality: Processes the E2 removal failure msg + * + * @params[in] + * E2AP_PDU_t *e2apMsg + * + * @return void + * + * ****************************************************************/ +void ProcE2RemovalFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0, transId=0; + CauseE2_t *cause = NULLP; + E2RemovalFailure_t *e2RemovalFailure=NULLP; + + e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure; + + if(!e2RemovalFailure->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : e2RemovalFailure array pointer is null"); + return; + } + + for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++) + { + if(e2RemovalFailure->protocolIEs.list.array[ieIdx]) + { + switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; + if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\ + (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode)) + { + memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); + } + else + { + DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); + } + break; + } + case ProtocolIE_IDE2_id_CauseE2: + { + cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2; + printE2ErrorCause(cause); + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Received Invalid Ie [%ld]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id); + break; + } + } + } + } + freeAperDecodingOfE2RemovalFailure(e2RemovalFailure); +} + + /****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder + * for Removal failure + * + * @details + * + * Function : freeAperDecodingOfE2RemovalResponse + * + * Functionality: Deallocation of memory allocated by aper decoder + * for Removal failure + * + * @params[in] Pointer to removalResponse + * @return void + * + * ****************************************************************/ + void freeAperDecodingOfE2RemovalResponse(E2RemovalResponse_t *removalResponse) + { + uint8_t arrIdx=0; + + if(removalResponse) + { + if(removalResponse->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(removalResponse->protocolIEs.list.array[arrIdx]) + { + free(removalResponse->protocolIEs.list.array[arrIdx]); + } + } + free(removalResponse->protocolIEs.list.array); + } + } + } + +/******************************************************************* + * + * @brief process the E2 Removal Response + * + * @details + * + * Function : ProcE2RemovalResponse + * + * Functionality: Process E2 Removal Response + * + * @params[in] + * E2AP_PDU_t *e2apMsg + * @return void + * + ******************************************************************/ + +void ProcE2RemovalResponse(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0, transId=0; + E2RemovalResponse_t *removalRsp = NULLP; + + removalRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse; + + if(!removalRsp->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : removalRsp array pointer is null"); + return; + } + + for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++) + { + if(removalRsp->protocolIEs.list.array[ieIdx]) + { + switch(removalRsp->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = removalRsp->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; + if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\ + (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode)) + { + DU_LOG("\nINFO --> E2AP : Sending request to close the sctp connection"); + cmInetClose(&ricParams.sockFd); + memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); + removeE2NodeInformation(); + } + else + { + DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); + } + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id); + break; + } + } + } + } + + freeAperDecodingOfE2RemovalResponse(removalRsp); +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for E2 Connection Update Failure + * + * @details + * + * Function : FreeE2ConnectionUpdateFailure + * + * Functionality: + * - freeing the memory allocated for E2ConnectionUpdateFailure + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void FreeE2ConnectionUpdateFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0; + E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.unsuccessfulOutcome != NULLP) + { + e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure; + if(e2ConnectionUpdateFailure->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < e2ConnectionUpdateFailure->protocolIEs.list.count; ieIdx++) + { + DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t)); + } + DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Buld and send the E2 Connection Update Failure msg + * + * @details + * + * Function : BuildAndSendE2ConnectionUpdateFailure + * + * Functionality: + * - Buld and send the E2 Connection Update Failure Message + * @params[in] + * Trans Id + * Failure Cause + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +uint8_t BuildAndSendE2ConnectionUpdateFailure(uint16_t transId, E2FailureCause failureCause) +{ + uint8_t ieIdx = 0, elementCnt = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building E2 Connection Update Failure Message\n"); + do + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; + + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + if(e2apMsg->choice.unsuccessfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate; + e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure; + e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure; + + elementCnt = 2; + e2ConnectionUpdateFailure->protocolIEs.list.count = elementCnt; + e2ConnectionUpdateFailure->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateFailure_IEs_t *); + DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size); + if(!e2ConnectionUpdateFailure->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t)); + if(!e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + } + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_TransactionID; + e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + /* Cause */ + ieIdx++; + e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2; + e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore; + e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_CauseE2; + fillE2Cause(&e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause); + + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2 connection update failure structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Connection Update Failure \n"); + for(int i=0; i< encBufSize; i++) + { + DU_LOG("%x",encBuf[i]); + } + } + + /* Sending msg */ + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 Connection Update Failure"); + break; + } + + ret = ROK; + break; + }while(true); + + FreeE2ConnectionUpdateFailure(e2apMsg); + return ret; +} + +/******************************************************************* + * + * @brief fill E2 connection update item + * + * @details + * + * Function : fillE2connectionUpdateItem + * + * Functionality: fill E2 connection update item + * + * @params[in] + * E2connectionUpdate Item to be filled + * Protocol Id + * IP Address + * Usage + * @return ROK - success + * RFAILED - failure + * ****************************************************************/ + +uint8_t fillE2connectionUpdateItem(PTR connectionInfo, uint8_t protocolId, uint32_t ipAddress, AssocUsage usage) +{ + CauseE2_t *cause=NULLP; + TNLusage_t *tnlUsage=NULLP; + E2FailureCause failureCause; + TNLinformation_t *tnlInformation = NULLP; + E2connectionUpdate_Item_t *connectionModifyItem=NULLP; + E2connectionSetupFailed_Item_t *connectionRemoveITem=NULLP; + + switch(protocolId) + { + case ProtocolIE_IDE2_id_E2connectionUpdate_Item: + { + connectionModifyItem = (E2connectionUpdate_Item_t*)connectionInfo; + tnlInformation = &connectionModifyItem->tnlInformation; + tnlUsage = &connectionModifyItem->tnlUsage; + break; + } + + case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item: + { + connectionRemoveITem = (E2connectionSetupFailed_Item_t*)connectionInfo; + tnlInformation= &connectionRemoveITem->tnlInformation; + cause = &connectionRemoveITem->cause; + break; + } + default: + return RFAILED; + } + + tnlInformation->tnlAddress.size = 4*sizeof(uint8_t); + DU_ALLOC(tnlInformation->tnlAddress.buf, tnlInformation->tnlAddress.size); + if(!tnlInformation->tnlAddress.buf) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + return RFAILED; + } + + tnlInformation->tnlAddress.buf[3] = ipAddress & 0xFF; + tnlInformation->tnlAddress.buf[2] = (ipAddress>> 8) & 0xFF; + tnlInformation->tnlAddress.buf[1] = (ipAddress>> 16) & 0xFF; + tnlInformation->tnlAddress.buf[0] = (ipAddress>> 24) & 0xFF; + tnlInformation->tnlAddress.bits_unused = 0; + + switch(protocolId) + { + case ProtocolIE_IDE2_id_E2connectionUpdate_Item: + { + *tnlUsage = usage; + break; + } + case ProtocolIE_IDE2_id_E2connectionSetupFailed_Item: + { + failureCause.causeType = E2_TRANSPORT; + failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED; + fillE2Cause(cause, failureCause); + break; + } + default: + return RFAILED; + } + return ROK; +} + + +/******************************************************************* + * + * @brief Build E2 connection modification list + * + * @details + * + * Function :BuildE2ConnectionUpdateList + * + * Functionality: Build E2 connection modification list + * + * @params[in] + * E2 connection update list to be filled + * Count of E2 connection to be added in the list + * Received list of E2 connection + * + * @return ROK - success + * RFAILED - failure + * ****************************************************************/ + +uint8_t BuildE2ConnectionUpdateList(E2connectionUpdate_List_t *connectionSetupList, uint8_t count, E2ConnectionItem *tmpConnectionList) +{ + uint8_t arrIdx = 0; + E2connectionUpdate_ItemIEs_t *connectionSetupItem=NULLP; + + connectionSetupList->list.count = count; + + connectionSetupList->list.size = connectionSetupList->list.count*sizeof(E2connectionUpdate_ItemIEs_t*); + DU_ALLOC(connectionSetupList->list.array, connectionSetupList->list.size); + if(connectionSetupList->list.array) + { + for(arrIdx = 0; arrIdx< connectionSetupList->list.count; arrIdx++) + { + DU_ALLOC(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t)); + if(connectionSetupList->list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + return RFAILED; + } + connectionSetupItem = (E2connectionUpdate_ItemIEs_t*)connectionSetupList->list.array[arrIdx]; + connectionSetupItem->id = ProtocolIE_IDE2_id_E2connectionUpdate_Item; + connectionSetupItem->criticality= CriticalityE2_ignore; + connectionSetupItem->value.present = E2connectionUpdate_ItemIEs__value_PR_E2connectionUpdate_Item; + if(fillE2connectionUpdateItem((PTR)&connectionSetupItem->value.choice.E2connectionUpdate_Item, ProtocolIE_IDE2_id_E2connectionUpdate_Item,\ + tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill E2 connection update item"); + return RFAILED; + } + + } + } + else + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + return RFAILED; + } + return ROK; +} + +/******************************************************************* + * + * @brief Build E2 connection setup failed list + * + * @details + * + * Function : BuildE2ConnectionSetupFailedList + * + * Functionality: Build E2 connection setup failed list + * + * @params[in] + * E2 connection setup failed list to be filled + * Count of E2 connection to be added in the list + * Received list of E2 connection + * + * @return ROK - success + * RFAILED - failure + * ****************************************************************/ + +uint8_t BuildE2ConnectionSetupFailedList(E2connectionSetupFailed_List_t *setupFailedList, uint8_t count, E2ConnectionItem *tmpConnectionList) +{ + uint8_t arrIdx = 0; + E2connectionSetupFailed_ItemIEs_t *setupFailedItem=NULLP; + + setupFailedList->list.count = 1; + + setupFailedList->list.size = setupFailedList->list.count*sizeof(E2connectionSetupFailed_ItemIEs_t *); + DU_ALLOC(setupFailedList->list.array, setupFailedList->list.size); + if(setupFailedList->list.array) + { + for(arrIdx = 0; arrIdx< setupFailedList->list.count; arrIdx++) + { + DU_ALLOC(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t)); + if(setupFailedList->list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + return RFAILED; + } + setupFailedItem = (E2connectionSetupFailed_ItemIEs_t*)setupFailedList->list.array[arrIdx]; + setupFailedItem->id = ProtocolIE_IDE2_id_E2connectionSetupFailed_Item; + setupFailedItem->criticality= CriticalityE2_ignore; + setupFailedItem->value.present = E2connectionSetupFailed_ItemIEs__value_PR_E2connectionSetupFailed_Item; + if(fillE2connectionUpdateItem((PTR)&setupFailedItem->value.choice.E2connectionSetupFailed_Item, ProtocolIE_IDE2_id_E2connectionSetupFailed_Item,\ + tmpConnectionList[arrIdx].ipV4Addr, tmpConnectionList[arrIdx].usage) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill E2 connection failed to update item"); + return RFAILED; + } + + } + } + else + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + return RFAILED; + } + return ROK; +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for E2 Connection + * Update ack msg + * + * @details + * + * Function :FreeE2ConnectionUpdateAcknowledge + * + * Functionality: + * - freeing the memory allocated for E2 Connection + * Update ack msg + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void FreeE2ConnectionUpdateAcknowledge(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0, arrIdx=0; + E2connectionUpdateAcknowledge_t *connectionUpdate = NULLP; + E2connectionUpdate_List_t *connectionSetupList = NULLP; + E2connectionSetupFailed_List_t *setupFailedList = NULLP; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.successfulOutcome != NULLP) + { + connectionUpdate = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge; + if(connectionUpdate->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++) + { + if(connectionUpdate->protocolIEs.list.array[ieIdx]) + { + switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + break; + + case ProtocolIE_IDE2_id_E2connectionSetup: + { + connectionSetupList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List; + if(connectionSetupList->list.array) + { + for(arrIdx = 0; arrIdx < connectionSetupList->list.count; arrIdx++) + { + DU_FREE(connectionSetupList->list.array[arrIdx], sizeof(E2connectionUpdate_ItemIEs_t)); + } + DU_FREE(connectionSetupList->list.array, connectionSetupList->list.size); } - free(additionAckList->list.array); + break; } - break; + + case ProtocolIE_IDE2_id_E2connectionSetupFailed: + { + setupFailedList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List; + if(setupFailedList->list.array) + { + for(arrIdx = 0; arrIdx < setupFailedList->list.count; arrIdx++) + { + DU_FREE(setupFailedList->list.array[arrIdx], sizeof(E2connectionSetupFailed_ItemIEs_t)); + } + DU_FREE(setupFailedList->list.array, setupFailedList->list.size); + } + break; + } + } + DU_FREE(connectionUpdate->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t)); + } + } + DU_FREE(connectionUpdate->protocolIEs.list.array, connectionUpdate->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Buld and send the E2 Connection Update Acknowledge msg + * + * @details + * + * Function : BuildAndSendE2ConnectionUpdateAcknowledge + * + * Functionality: + * - Buld and send the E2 Connection Update Acknowledge Message + * @params[in] + * Trans Id + * List of E2 connection needs to fill in IE + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +uint8_t BuildAndSendE2ConnectionUpdateAcknowledge(uint16_t transId, E2ConnectionList connectionInfoList) +{ + uint8_t ieIdx = 0, elementCnt = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + asn_enc_rval_t encRetVal; + E2connectionUpdateAcknowledge_t *e2ConnectionUpdateAcknowledge=NULLP; + + DU_LOG("\nINFO --> E2AP : Building E2 Connection Update Acknowledge Message\n"); + do + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + e2apMsg->present = E2AP_PDU_PR_successfulOutcome; + + DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(e2apMsg->choice.successfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate; + e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2connectionUpdateAcknowledge; + e2ConnectionUpdateAcknowledge = &e2apMsg->choice.successfulOutcome->value.choice.E2connectionUpdateAcknowledge; + + elementCnt = 1; + if(connectionInfoList.numOfE2ConnectionSetup) + elementCnt++; + if(connectionInfoList.numOfE2ConnectionFailedToSetup) + elementCnt++; + + e2ConnectionUpdateAcknowledge->protocolIEs.list.count = elementCnt; + e2ConnectionUpdateAcknowledge->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateAck_IEs_t*); + DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array, e2ConnectionUpdateAcknowledge->protocolIEs.list.size); + if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateAck_IEs_t)); + if(!e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + } + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_TransactionID; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + if(connectionInfoList.numOfE2ConnectionSetup) + { + ieIdx++; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_E2connectionSetup; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionUpdate_List; + if(BuildE2ConnectionUpdateList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List, \ + connectionInfoList.numOfE2ConnectionSetup, connectionInfoList.setupE2Connection) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 Connection setup list"); + break; + } + } + + if(connectionInfoList.numOfE2ConnectionFailedToSetup) + { + ieIdx++; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_E2connectionSetupFailed; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateAck_IEs__value_PR_E2connectionSetupFailed_List; + if(BuildE2ConnectionSetupFailedList(&e2ConnectionUpdateAcknowledge->protocolIEs.list.array[ieIdx]->value.choice.E2connectionSetupFailed_List, \ + connectionInfoList.numOfE2ConnectionFailedToSetup, connectionInfoList.failedToSetupE2Connection) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 Connection failed to setup list"); + break; + } + } + + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2 connection update acknowledge failure structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Connection Update Acknowledge \n"); + for(int i=0; i< encBufSize; i++) + { + DU_LOG("%x",encBuf[i]); + } + } + + /* Sending msg */ + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 Connection Update Acknowledge"); + break; + } + + ret = ROK; + break; + }while(true); + + FreeE2ConnectionUpdateAcknowledge(e2apMsg); + return ret; +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for + * E2 Connection Update + * + * @details + * + * Function :freeAperDecodingOfE2ConnectionUpdate + * + * Functionality: Deallocation of memory allocated by aper decoder for + * E2 Connection Update + * + * @params[in] Pointer to connectionUpdate + * @return void + * + * ****************************************************************/ + +void freeAperDecodingOfE2ConnectionUpdate(E2connectionUpdate_t *connectionUpdate) +{ + uint8_t ieIdx =0, arrIdx=0; + E2connectionUpdate_List_t *connectionToBeModifyList = NULLP; + E2connectionUpdateRemove_List_t *connectionToBeRemoveList = NULLP; + + if(connectionUpdate->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++) + { + if(connectionUpdate->protocolIEs.list.array[ieIdx]) + { + switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + break; + + case ProtocolIE_IDE2_id_E2connectionUpdateModify: + { + connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List; + if(connectionToBeModifyList->list.array) + { + for(arrIdx= 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++) + { + free(connectionToBeModifyList->list.array[arrIdx]); + } + free(connectionToBeModifyList->list.array); } + break; + } + case ProtocolIE_IDE2_id_E2connectionUpdateRemove: + { + connectionToBeRemoveList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdateRemove_List; + if(connectionToBeRemoveList->list.array) + { + for(arrIdx= 0; arrIdx< connectionToBeRemoveList->list.count; arrIdx++) + { + free(connectionToBeRemoveList->list.array[arrIdx]); + } + free(connectionToBeRemoveList->list.array); + } + break; + } + } + free(connectionUpdate->protocolIEs.list.array[ieIdx]); + } + } + free(connectionUpdate->protocolIEs.list.array); + } +} + +/******************************************************************* + * + * @brief Handling of E2 connection modification Ie + * + * @details + * + * Function : handleE2ConnectionModification + * + * Functionality: Handling of E2 connection modification Ie + * + * @param + * E2 Connection update list + * E2 connection list which needs to be filled + * @return void + * + ******************************************************************/ + +void handleE2ConnectionModification(E2connectionUpdate_List_t *connectionUpdateList, E2ConnectionList *connectionInfoList) +{ + uint32_t ipAddress=0; + bool infoFound = false; + uint8_t arrIdx=0,idx=0, count =0; + E2connectionUpdate_ItemIEs_t *connectionModifyItem=NULLP; + + if(connectionUpdateList->list.array) + { + for(arrIdx = 0; arrIdx < connectionUpdateList->list.count; arrIdx++) + { + connectionModifyItem= (E2connectionUpdate_ItemIEs_t*)connectionUpdateList->list.array[arrIdx]; + bitStringToInt(&connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlInformation.tnlAddress, &ipAddress); + for(idx=0; idxvalue.choice.E2connectionUpdate_Item.tnlUsage; + infoFound = true; + break; + } + } + + /* If the TNL information is found in the data base, then add the + * information in setupE2Connection array else add in failedToSetupE2Connection array */ + if(infoFound == true) + { + count =connectionInfoList->numOfE2ConnectionSetup; + connectionInfoList->setupE2Connection[count].ipV4Addr = duCb.e2apDb.tnlAssoc[idx].destIpAddress.ipV4Addr; + connectionInfoList->setupE2Connection[count].usage = duCb.e2apDb.tnlAssoc[idx].usage; + connectionInfoList->numOfE2ConnectionSetup++; + } + else + { + count = connectionInfoList->numOfE2ConnectionFailedToSetup; + connectionInfoList->failedToSetupE2Connection[count].ipV4Addr = ipAddress; + connectionInfoList->failedToSetupE2Connection[count].usage = connectionModifyItem->value.choice.E2connectionUpdate_Item.tnlUsage; + connectionInfoList->numOfE2ConnectionFailedToSetup++; + } + } + + } +} + +/******************************************************************* + * + * @brief Handling of E2 connection removal Ie + * + * @details + * + * Function : handleE2ConnectionRemoval + * + * Functionality: Handling of E2 connection removal Ie + * + * @param + * E2 Connection removal List + * @return void + * + ******************************************************************/ + +void handleE2ConnectionRemoval(E2connectionUpdateRemove_List_t *connectionRemovalList) +{ + uint32_t ipAddress=0; + uint8_t arrIdx=0,idx=0; + E2connectionUpdateRemove_ItemIEs_t *connectionRemovalItem=NULLP; + + if(connectionRemovalList->list.array) + { + for(arrIdx = 0; arrIdx < connectionRemovalList->list.count; arrIdx++) + { + connectionRemovalItem= (E2connectionUpdateRemove_ItemIEs_t*)connectionRemovalList->list.array[arrIdx]; + bitStringToInt(&connectionRemovalItem->value.choice.E2connectionUpdateRemove_Item.tnlInformation.tnlAddress, &ipAddress); + for(idx=0; idx E2AP : E2 connection update received"); + connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate; + + memset(&connectionInfoList, 0, sizeof(E2ConnectionList)); + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(connectionUpdate->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; + if(transId>255) + { + failureCause.causeType = E2_PROTOCOL; + failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE; + invalidTransId = true; + } + break; + } + + case ProtocolIE_IDE2_id_E2connectionUpdateModify: + { + handleE2ConnectionModification(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdate_List,\ + &connectionInfoList); + if((connectionInfoList.numOfE2ConnectionSetup == 0) && (connectionInfoList.numOfE2ConnectionFailedToSetup > 0)) + { + failureCause.causeType = E2_TRANSPORT; + failureCause.cause = E2_TRANSPORT_CAUSE_UNSPECIFIED; + connectionFailedToUpdate =true; + } + + break; + } + + case ProtocolIE_IDE2_id_E2connectionUpdateRemove: + { + handleE2ConnectionRemoval(&connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2connectionUpdateRemove_List); + break; + } + + default: + { + DU_LOG("\nERROR --> E2AP : Invalid IE received[%ld]",connectionUpdate->protocolIEs.list.array[arrIdx]->id); + break; + } + } + + if(invalidTransId == true || connectionFailedToUpdate ==true) + break; + } + + if(invalidTransId == true || connectionFailedToUpdate == true) + { + if(BuildAndSendE2ConnectionUpdateFailure(transId, failureCause) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send E2 connection update failure"); + } + } + else + { + if(BuildAndSendE2ConnectionUpdateAcknowledge(transId, connectionInfoList) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send E2 connection update ack"); + } + } + + freeAperDecodingOfE2ConnectionUpdate(connectionUpdate); +} + +/******************************************************************* + * + * @brief Free RIC Subscription action to be added list + * + * @details + * + * Function : freeAperDecodingOfRicSubsActionToBeAdded + * + * Functionality: Free the RIC Subscription action to be added list + * + * @params[in] RICactions_ToBeAddedForModification_List_t *subsDetails + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfRicSubsActionToBeAdded(RICactions_ToBeAddedForModification_List_t *subsDetails) +{ + uint8_t elementIdx = 0; + RICaction_ToBeAddedForModification_ItemIEs_t *addedActionItemIe=NULLP; + + if(subsDetails->list.array) + { + for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++) + { + if(subsDetails->list.array[elementIdx]) + { + addedActionItemIe = (RICaction_ToBeAddedForModification_ItemIEs_t*)subsDetails->list.array[elementIdx]; + free(addedActionItemIe->value.choice.RICaction_ToBeAddedForModification_Item.ricActionDefinition.buf); + free(subsDetails->list.array[elementIdx]); + } + } + free(subsDetails->list.array); + } +} + +/******************************************************************* + * + * @brief Deallocation of memory allocated by aper decoder for + * RIC Subscription action to be removed list + * + * @details + * + * Function : freeAperDecodingOfRicSubsActionToBeRemoved + * + * Functionality: Free the RIC Subscription action to be removed list + * + * @params[in] RICactions_ToBeRemovedForModification_List_t *subsDetails + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfRicSubsActionToBeRemoved(RICactions_ToBeRemovedForModification_List_t *subsDetails) +{ + uint8_t elementIdx = 0; + + if(subsDetails->list.array) + { + for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++) + { + if(subsDetails->list.array[elementIdx]) + { + free(subsDetails->list.array[elementIdx]); + } + } + free(subsDetails->list.array); + } +} + +/******************************************************************* + * + * @brief Deallocation of memory allocated by aper decoder for + * RIC Subscription action to be modify + * + * @details + * + * Function : freeAperDecodingOfRicSubsActionToBeModified + * + * Functionality: Free the RIC Subscription action to be modify + * + * @params[in] RICactions_ToBeModifiedForModification_List_t List + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfRicSubsActionToBeModified(RICactions_ToBeModifiedForModification_List_t *subsDetails) +{ + uint8_t elementIdx = 0; + RICaction_ToBeModifiedForModification_ItemIEs_t *actionItem = NULLP; + + if(subsDetails->list.array) + { + for(elementIdx = 0; elementIdx < subsDetails->list.count; elementIdx++) + { + if(subsDetails->list.array[elementIdx]) + { + actionItem = (RICaction_ToBeModifiedForModification_ItemIEs_t *)subsDetails->list.array[elementIdx]; + if(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition) + { + free(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition->buf); + free(actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionDefinition); + } + free(subsDetails->list.array[elementIdx]); + } + } + free(subsDetails->list.array); + } +} + +/******************************************************************* + * + * @brief Deallocation of memory allocated by aper decoder for + * RIC Subscription modification Request + * + * @details + * + * Function freeAperDecodingOfRicSubsModificationReq + * + * Functionality : Free RIC Subscription modification Request + * + * @params[in] E2AP_PDU + * @return void + * + ******************************************************************/ +void freeAperDecodingOfRicSubsModificationReq(E2AP_PDU_t *e2apRicMsg) +{ + uint8_t idx = 0; + RICsubscriptionModificationRequest_t *ricSubscriptionModReq; + RICsubscriptionModificationRequest_IEs_t *ricSubscriptionModReqIe; + + ricSubscriptionModReq = &e2apRicMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest; + + if(ricSubscriptionModReq->protocolIEs.list.array) + { + for(idx=0; idx < ricSubscriptionModReq->protocolIEs.list.count; idx++) + { + if(ricSubscriptionModReq->protocolIEs.list.array[idx]) + { + ricSubscriptionModReqIe = ricSubscriptionModReq->protocolIEs.list.array[idx]; + + switch(ricSubscriptionModReq->protocolIEs.list.array[idx]->id) + { + case ProtocolIE_IDE2_id_RICrequestID: + break; + + case ProtocolIE_IDE2_id_RANfunctionID: + break; + + case ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List: + { + freeAperDecodingOfRicSubsActionToBeRemoved(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeRemovedForModification_List)); + break; } - case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + case ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List: + { + freeAperDecodingOfRicSubsActionToBeModified(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeModifiedForModification_List)); + break; + } + case ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List: + { + freeAperDecodingOfRicSubsActionToBeAdded(&(ricSubscriptionModReqIe->value.choice.RICactions_ToBeAddedForModification_List)); + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Received Invalid Ie [%ld]", ricSubscriptionModReq->protocolIEs.list.array[idx]->id); + break; + } + + } + + free(ricSubscriptionModReq->protocolIEs.list.array[idx]); + } + } + free(ricSubscriptionModReq->protocolIEs.list.array); + } +} +/******************************************************************* + * + * @brief Extract RIC Action to be added + * + * @details + * + * Function : extractRicActionToBeAddedForModification + * + * Functionality : This function : + * - [Step -1] Traverse each AddedForModification item indexes. + * - [Step -2] Add each action id related information in + * RicSubscription Db. + * - [Step -3] If failed to store then add action related info in + * pending rsp's rejectedActionList. + * - [Step -4] Else increment action added count + * - [Step -5] If there is even 1 action that can be added, + * return ROK, else RFAILED. + * + * @params[in] RAN Function Database structure + * RIC Subscription Info to be added to RAN function + * RIC Action To Be AddedForModification List received from RIC + * failure Cause + * Pending Subs Mod Rsp Info + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t extractRicActionToBeAddedForModification(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ + RICactions_ToBeAddedForModification_List_t *actionList, E2FailureCause *failureCause, PendingSubsModRspInfo *subsModRsp) +{ + uint8_t actionAdded=0; + CmLList *actionNode = NULLP; + uint8_t actionIdx = 0; + uint8_t ricActionId = 0; + RICaction_ToBeAddedForModification_ItemIEs_t *actionItem = NULLP; + + if(actionList->list.array) + { + for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++) + { + /* Step -1 */ + actionItem =(RICaction_ToBeAddedForModification_ItemIEs_t *)actionList->list.array[actionIdx]; + switch(actionItem->id) + { + case ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item: + { + /* Step -2 */ + actionNode = addRicSubsAction(ranFuncDb, (PTR)&actionItem->value.choice.RICaction_ToBeAddedForModification_Item,\ + &ricSubscriptionInfo->actionSequence, ProtocolIE_IDE2_id_RICaction_ToBeAddedForModification_Item, failureCause); + + if(!actionNode) { - updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List; - if(updateAckList->list.array) + /* Step -3 */ + subsModRsp->addActionStatus.rejectedActionList[subsModRsp->addActionStatus.numOfRejectedActions].id = ricActionId; + if(failureCause->causeType == E2_NOTHING) { - for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.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); + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_CONTROL_FAILED_TO_EXECUTE; } - break; + memcpy(&subsModRsp->addActionStatus.rejectedActionList[subsModRsp->addActionStatus.numOfRejectedActions].failureCause, \ + failureCause, sizeof(E2FailureCause)); + subsModRsp->addActionStatus.numOfRejectedActions++; } - case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + else { - removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List; - if(removalAckList->list.array) + /* Step -4 */ + actionAdded++; + } + break; + } + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in RicAddedForModificationLst:%ld",actionItem->id); + break; + } + } + } + + /* Step -5 */ + if(actionAdded) + return ROK; + + if(failureCause->causeType == E2_NOTHING) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + } + return RFAILED; +} + +/******************************************************************* + * + * @brief Extract RIC Action to be Modified + * + * @details + * + * Function : extractRicActionToBeModifiedForModification + * + * Functionality : This function : + * - [Step -1] Traverse each Modification item indexes. + * - [Step -2] Find each action id related information in + * RicSubscription Db. + * - [Step -3] If not found store the action related info in pending + * rsp's action rejected. + * - [Step -4] If found store the new node in action seq list. + * [Step -4.1] If action failed to store, add the action + * info in pending subscription rsp's rejected list. + * [Step -4.2] If action stored successfully, change the status + * of added action to modified because action added as part of + * ric subscription modification req. + * - [Step -5] If there is even 1 action that can be modified, + * return ROK, else RFAILED. + * + * @params[in] RAN Function Database structure + * RIC Subscription Info to be Modified to RAN function + * RIC Action To Be ModifiedForModification List received from RIC + * failure Cause + * Pending Subs Mod Rsp Info + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t extractRicActionToBeModifiedForModification(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ + RICactions_ToBeModifiedForModification_List_t *actionList, E2FailureCause *failureCause, PendingSubsModRspInfo *subsModRsp) +{ + uint8_t actionId=0; + uint8_t actionIdx = 0; + uint8_t actionFound=0; + CmLList *actionNode = NULLP; + ActionInfo *actionDb = NULLP; + RICaction_ToBeModifiedForModification_ItemIEs_t *actionItem = NULLP; + + if(actionList->list.array) + { + for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++) + { + /* [Step -1] */ + actionItem =(RICaction_ToBeModifiedForModification_ItemIEs_t *)actionList->list.array[actionIdx]; + switch(actionItem->id) + { + case ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item: + { + /* [Step -2] */ + actionId=actionItem->value.choice.RICaction_ToBeModifiedForModification_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubscriptionInfo, &actionNode, CONFIG_UNKNOWN); + if(!actionNode) + { + /* [Step -3] */ + subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].id = actionDb->actionId; + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + memcpy(&subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].failureCause, \ + failureCause, sizeof(E2FailureCause)); + subsModRsp->modActionStatus.numOfRejectedActions++; + } + else + { + /* [Step -4] */ + actionNode = NULLP; + actionNode = addRicSubsAction(ranFuncDb, (PTR)&actionItem->value.choice.RICaction_ToBeModifiedForModification_Item,\ + &ricSubscriptionInfo->actionSequence, ProtocolIE_IDE2_id_RICaction_ToBeModifiedForModification_Item, failureCause); + + if(!actionNode) { - for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) + /* [Step -4.1] */ + subsModRsp->modActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].id = actionId; + if(failureCause->causeType == E2_NOTHING) { - 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); - } + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_CONTROL_FAILED_TO_EXECUTE; } - free(removalAckList->list.array); + memcpy(&subsModRsp->modActionStatus.rejectedActionList[subsModRsp->modActionStatus.numOfRejectedActions].failureCause, \ + failureCause, sizeof(E2FailureCause)); + subsModRsp->addActionStatus.numOfRejectedActions++; + } + else + { + /* [Step -4.2] */ + actionDb = (ActionInfo*)actionNode->node; + actionDb->action=CONFIG_MOD; + actionFound++; } break; } - } - free(updateAckMsg->protocolIEs.list.array[arrIdx]); + break; + } + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in RicModifiedForModificationLst:%ld",actionItem->id); + break; } } - free(updateAckMsg->protocolIEs.list.array); } + + /* [Step -5] */ + if(actionFound) + return ROK; + + return RFAILED; } -/****************************************************************** +/******************************************************************* * - * @brief Processes the E2 node config update ack msg + * @brief Extract RIC Action to be Removed * * @details * - * Function :procE2NodeConfigUpdateAck + * Function : extractRicActionToBeRemovedForModification * - * Functionality: Processes the E2 node config update ack msg + * Functionality : This function : + * - [Step -1] Traverse each RemovedForModification item indexes. + * - [Step -2] Find each action id related information in + * RicSubscription Db. + * - [Step -3] If not found store the action related info in pending + * rsp's rejectedActionList. + * - [Step -4] If found mark action's status CONFIG_DEL. + * - [Step -5] If there is even 1 action that can be Removed, + * return ROK, else RFAILED. * - * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @params[in] RAN Function Database structure + * RIC Subscription Info to be Removed to RAN function + * RIC Action To Be RemovedForModification List received from RIC + * failure Cause + * Pending ric subs mod Rsp Info to store failure result * @return ROK - success * RFAILED - failure * - * ****************************************************************/ + ******************************************************************/ +uint8_t extractRicActionToBeRemovedForModification(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ + RICactions_ToBeRemovedForModification_List_t *actionList, E2FailureCause *failureCause, PendingSubsModRspInfo *subsModRsp) +{ + uint8_t actionId=0; + uint8_t actionIdx = 0; + uint8_t actionFound=0; + CmLList *actionNode = NULLP; + ActionInfo *actionDb = NULLP; + RICaction_ToBeRemovedForModification_ItemIEs_t *actionItem = NULLP; -void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg) + if(actionList->list.array) + { + for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++) + { + /* [Step -1] */ + actionItem =(RICaction_ToBeRemovedForModification_ItemIEs_t *)actionList->list.array[actionIdx]; + switch(actionItem->id) + { + case ProtocolIE_IDE2_id_RICaction_ToBeRemovedForModification_Item: + { + /* [Step -2] */ + actionId = actionItem->value.choice.RICaction_ToBeRemovedForModification_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubscriptionInfo, &actionNode, CONFIG_UNKNOWN); + if(!actionNode) + { + /* [Step -3] */ + subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->removeActionStatus.numOfRejectedActions].id = actionDb->actionId; + if(failureCause->causeType == E2_NOTHING) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + } + memcpy(&subsModRsp->removeActionStatus.rejectedActionList[subsModRsp->removeActionStatus.numOfRejectedActions].failureCause, \ + failureCause, sizeof(E2FailureCause)); + subsModRsp->removeActionStatus.numOfRejectedActions++; + } + else + { + /* [Step -4] */ + actionDb->action=CONFIG_DEL; + actionFound++; + } + break; + } + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in RicRemovedForModificationLst:%ld",actionItem->id); + break; + } + } + } + + /* [Step -5] */ + if(actionFound) + return ROK; + + return RFAILED; +} + +/******************************************************************* + * + * @brief Process RIC Subscription modification request + * + * @details + * + * Function : procRicSubscriptionModificationRequest + * + * Functionality: Process RIC subscription modification request. + * + * @params[in] E2AP PDU + * @return void + * + ******************************************************************/ +void procRicSubscriptionModificationRequest(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; + uint8_t ieIdx = 0; + uint16_t ranFuncId = 0; + RicRequestId ricReqId; + E2FailureCause failureCause; + bool procFailure = false; + bool addActionIeProcessed=false; + bool modActionIeProcessed =false; + bool removeActionIeProcessed =false; + CmLList *ricSubsNode = NULLP; + RanFunction *ranFuncDb = NULLP; + RicSubscription *ricSubsDb = NULLP; + RICsubscriptionModificationRequest_t *ricSubsModifyReq = NULLP; + RICsubscriptionModificationRequest_IEs_t *ricSubsModifyReqIe = NULLP; + + DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Modification Request", __func__); - e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge; + do{ + if(!e2apMsg) + { + DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + break; + } - if(e2NodeConfigUpdateAck->protocolIEs.list.array) - { - for(arrIdx =0; arrIdxprotocolIEs.list.count; arrIdx++) - { - switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: + if(!e2apMsg->choice.initiatingMessage) + { + DU_LOG("\nERROR --> E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__); + break; + } + + ricSubsModifyReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequest; + for(ieIdx = 0; ieIdx < ricSubsModifyReq->protocolIEs.list.count; ieIdx++) + { + if(!ricSubsModifyReq->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + break; + } + + ricSubsModifyReqIe = ricSubsModifyReq->protocolIEs.list.array[ieIdx]; + switch(ricSubsModifyReqIe->id) + { + case ProtocolIE_IDE2_id_RICrequestID: { + memset(&ricReqId, 0, sizeof(RicRequestId)); + ricReqId.requestorId = ricSubsModifyReqIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsModifyReqIe->value.choice.RICrequestID.ricInstanceID; break; } - case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + + case ProtocolIE_IDE2_id_RANfunctionID: { - e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; - if(e2NodeConfigAdditionAckList->list.array) + ranFuncId = ricSubsModifyReqIe->value.choice.RANfunctionID; + ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId); + if(!ranFuncDb) { - 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); - } + 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; } + memset(&ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp], 0, sizeof(PendingSubsModRspInfo)); + memcpy(&ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp].requestId, + &ricReqId, sizeof(RicRequestId)); + ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp].ranFuncId = ranFuncId; + break; } - case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + case ProtocolIE_IDE2_id_RICactionsToBeRemovedForModification_List: { - e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List; - if(e2NodeConfigUpdateAckList->list.array) + if(extractRicActionToBeRemovedForModification(ranFuncDb, ricSubsDb,\ + &ricSubsModifyReqIe->value.choice.RICactions_ToBeRemovedForModification_List,\ + &failureCause, &ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp]) == ROK) { - 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); - } + removeActionIeProcessed= true; + } + + break; + } + case ProtocolIE_IDE2_id_RICactionsToBeModifiedForModification_List: + { + if(extractRicActionToBeModifiedForModification(ranFuncDb, ricSubsDb,\ + &ricSubsModifyReqIe->value.choice.RICactions_ToBeModifiedForModification_List,\ + &failureCause, &ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp]) == ROK) + { + modActionIeProcessed = true; } break; } - case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + case ProtocolIE_IDE2_id_RICactionsToBeAddedForModification_List: { - e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List; - if(e2NodeConfigRemovalAckList->list.array) + if(extractRicActionToBeAddedForModification(ranFuncDb, ricSubsDb,\ + &ricSubsModifyReqIe->value.choice.RICactions_ToBeAddedForModification_List,\ + &failureCause, &ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp]) == ROK) { - 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); - } + addActionIeProcessed = true; } break; } - } - } + default: + break; + } /* End of switch for Protocol IE Id */ + + if(procFailure) + break; + } /* End of for loop for Protocol IE list */ + + break; + }while(true); + + if(!removeActionIeProcessed && !addActionIeProcessed && !modActionIeProcessed) + { + BuildAndSendRicSubscriptionModificationFailure(ranFuncId, ricReqId, failureCause); } + else + { + if(duChkTmr((PTR)ricSubsDb, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR) == true) + { + duStopTmr((PTR)ricSubsDb, EVENT_RIC_SUBSCRIPTION_REPORTING_TMR); + } - freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck); + ricSubsDb->action = CONFIG_MOD; + ranFuncDb->numPendingSubsModRsp++; + + /*If the remove-action ie is present, send a stats delete request; + * otherwise, change removeActionCompleted to true in the pendingSubsModRspInfo. */ + if(removeActionIeProcessed) + { + BuildAndSendStatsDeleteReq(ricSubsDb, false); + } + else + { + ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp-1].removeActionCompleted = true; + } + + /*If the mod-action ie is present, send a stats modification request; + * otherwise, change modActionCompleted to true in the pendingSubsModRspInfo. */ + if(modActionIeProcessed) + { + BuildAndSendStatsModificationReq(ricSubsDb); + } + else + { + ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp-1].modActionCompleted= true; + } + + /*If the add-action ie is present, send a stats add request; + * otherwise, change addActionCompleted to true in the pendingSubsModRspInfo. */ + if(addActionIeProcessed) + { + BuildAndSendStatsReq(ricSubsDb); + } + else + { + ranFuncDb->pendingSubsModRspInfo[ranFuncDb->numPendingSubsModRsp-1].addActionCompleted= true; + } + + } + + freeAperDecodingOfRicSubsModificationReq(e2apMsg); } /******************************************************************* - * - * @brief Deallocate the memory allocated for RemovalRequest msg + * @brief Free RIC Subscription Modification Failure Message * * @details * - * Function : FreeRemovalRequest + * Function : FreeRicSubscriptionModificationFailure * - * Functionality: - * - freeing the memory allocated for RemovalRequest + * Functionality: Free RIC Subscription Modification Failure * - * @params[in] E2AP_PDU_t *e2apMsg - * @return ROK - success - * RFAILED - failure + * @param E2AP Message PDU + * @return void * - * ****************************************************************/ -void FreeRemovalRequest(E2AP_PDU_t *e2apMsg) + ******************************************************************/ +void FreeRicSubscriptionModificationFailure(E2AP_PDU_t *e2apMsg) { - uint8_t ieIdx =0; - E2RemovalRequest_t *removalReq = NULLP; + uint8_t ieIdx = 0; + RICsubscriptionModificationFailure_t *ricSubsModFailure = NULLP; - if(e2apMsg != NULLP) + if(e2apMsg) { - if(e2apMsg->choice.initiatingMessage != NULLP) + if(e2apMsg->choice.unsuccessfulOutcome) { - removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest; - if(removalReq->protocolIEs.list.array) + ricSubsModFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationFailure; + if(ricSubsModFailure->protocolIEs.list.array) { - for(ieIdx = 0; ieIdx < removalReq->protocolIEs.list.count; ieIdx++) + for(ieIdx = 0; ieIdx < ricSubsModFailure->protocolIEs.list.count; ieIdx++) { - DU_FREE(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t)); + DU_FREE(ricSubsModFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationFailure_IEs_t)); } - DU_FREE(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size); + DU_FREE(ricSubsModFailure->protocolIEs.list.array, ricSubsModFailure->protocolIEs.list.size); } - DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); } - DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));; } } - /******************************************************************* * - * @brief Build and send the removal request msg + * @brief Builds and Send RIC Subscription Modification Failure * * @details * - * Function : BuildAndSendRemovalRequest + * Function : BuildAndSendRicSubscriptionModificationFailure * - * Functionality: - * - Buld and send the removal request msg to E2 node + * Functionality: Build and send RIC Subscription Modification Failure. * + * @params[in] + * Ran Func Id + * Ric Req Id + * E2 failure cause * @return ROK - success * RFAILED - failure * - * ****************************************************************/ - -uint8_t BuildAndSendRemovalRequest() + ******************************************************************/ +uint8_t BuildAndSendRicSubscriptionModificationFailure(uint16_t ranFuncId, RicRequestId requestId, E2FailureCause failureCause) { - uint8_t ieIdx = 0, elementCnt = 0, transId = 0; - uint8_t ret = RFAILED; - E2AP_PDU_t *e2apMsg = NULLP; - E2RemovalRequest_t *removalReq = NULLP; - asn_enc_rval_t encRetVal; /* Encoder return value */ - - DU_LOG("\nINFO --> E2AP : Building Removal Request\n"); + uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionModificationFailure_t *ricSubsModFailure = NULLP; + RICsubscriptionModificationFailure_IEs_t *ricSubsModFailureIe = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ - do + while(true) { + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Modification Failure Message\n"); + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); if(e2apMsg == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } - e2apMsg->present = E2AP_PDU_PR_initiatingMessage; - DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); - if(e2apMsg->choice.initiatingMessage == NULLP) + e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + if(e2apMsg->choice.unsuccessfulOutcome == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } + e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModification; + e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationFailure; - e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2removal; - e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; - e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_E2RemovalRequest; - removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest; - elementCnt = 1; - removalReq->protocolIEs.list.count = elementCnt; - removalReq->protocolIEs.list.size = elementCnt * sizeof(E2RemovalRequestIEs_t *); + ricSubsModFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationFailure; - DU_ALLOC(removalReq->protocolIEs.list.array, removalReq->protocolIEs.list.size); - if(!removalReq->protocolIEs.list.array) + elementCnt = 3; + ricSubsModFailure->protocolIEs.list.count = elementCnt; + ricSubsModFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationFailure_IEs_t *); + + DU_ALLOC(ricSubsModFailure->protocolIEs.list.array, ricSubsModFailure->protocolIEs.list.size); + if(ricSubsModFailure->protocolIEs.list.array == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__); break; } for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) { - DU_ALLOC(removalReq->protocolIEs.list.array[ieIdx], sizeof(E2RemovalRequestIEs_t)); - if(!removalReq->protocolIEs.list.array[ieIdx]) + DU_ALLOC(ricSubsModFailure->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationFailure_IEs_t)); + if(ricSubsModFailure->protocolIEs.list.array[ieIdx] == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for index [%d] at line %d", \ + __func__, ieIdx, __LINE__); break; } } - - /* In case of failure */ if(ieIdx < elementCnt) break; ieIdx = 0; - removalReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; - removalReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; - removalReq->protocolIEs.list.array[ieIdx]->value.present = E2RemovalRequestIEs__value_PR_TransactionID; - transId = assignTransactionId(); - removalReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + ricSubsModFailureIe = ricSubsModFailure->protocolIEs.list.array[ieIdx]; + ricSubsModFailureIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsModFailureIe->criticality = CriticalityE2_reject; + ricSubsModFailureIe->value.present = RICsubscriptionModificationFailure_IEs__value_PR_RICrequestID; + ricSubsModFailureIe->value.choice.RICrequestID.ricRequestorID= requestId.requestorId; + ricSubsModFailureIe->value.choice.RICrequestID.ricInstanceID = requestId.instanceId; + + ieIdx++; + ricSubsModFailureIe = ricSubsModFailure->protocolIEs.list.array[ieIdx]; + ricSubsModFailureIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsModFailureIe->criticality = CriticalityE2_reject; + ricSubsModFailureIe->value.present = RICsubscriptionModificationFailure_IEs__value_PR_RANfunctionID; + ricSubsModFailureIe->value.choice.RANfunctionID = ranFuncId; + + ieIdx++; + ricSubsModFailureIe = ricSubsModFailure->protocolIEs.list.array[ieIdx]; + ricSubsModFailureIe->id = ProtocolIE_IDE2_id_CauseE2; + ricSubsModFailureIe->criticality = CriticalityE2_reject; + ricSubsModFailureIe->value.present = RICsubscriptionModificationFailure_IEs__value_PR_CauseE2; + fillE2Cause(&ricSubsModFailureIe->value.choice.CauseE2, failureCause); /* Prints the Msg formed */ xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); - memset(encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\ - encBuf); + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode removal request structure (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Modification Failure Message (at %s)\n",\ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); break; } else { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for removal request\n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Modification Failure Message \n"); #ifdef DEBUG_ASN_PRINT for(int i=0; i< encBufSize; i++) { @@ -8024,331 +10328,543 @@ uint8_t BuildAndSendRemovalRequest() } #endif } + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { - DU_LOG("\nERROR --> E2AP : Sending removal request failed"); - break; + DU_LOG("\nERROR --> E2AP : Failed to send RIC Susbcription Modification Failure Message"); + break; + } + + ret = ROK; + break; + } + + FreeRicSubscriptionModificationFailure(e2apMsg); + return ret; +} + +/******************************************************************* + * @brief Free RIC Subscription Modification Response Message + * + * @details + * + * Function : FreeRicSubscriptionModificationResponse + * + * Functionality: Free RIC Subscription Modification Response + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void FreeRicSubscriptionModificationResponse(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0, elementIdx=0; + RICactions_AddedForModification_List_t *actionsAdded = NULLP; + RICactions_RemovedForModification_List_t *actionsRemoved = NULLP; + RICactions_ModifiedForModification_List_t *actionsModified = NULLP; + RICactions_FailedToBeAddedForModification_List_t *actionsFailedToBeAdded = NULLP; + RICactions_FailedToBeRemovedForModification_List_t *actionsFailedToBeRemoved = NULLP; + RICactions_FailedToBeModifiedForModification_List_t *actionsFailedToBeModified = NULLP; + + RICsubscriptionModificationResponse_t *ricSubsModResponse = NULLP; + + if(e2apMsg) + { + if(e2apMsg->choice.successfulOutcome) + { + ricSubsModResponse = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationResponse; + if(ricSubsModResponse->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < ricSubsModResponse->protocolIEs.list.count; ieIdx++) + { + if(ricSubsModResponse->protocolIEs.list.array[ieIdx]) + { + switch(ricSubsModResponse->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_RANfunctionID: + case ProtocolIE_IDE2_id_RICrequestID: + break; + case ProtocolIE_IDE2_id_RICactionsRemovedForModification_List: + { + actionsRemoved = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_RemovedForModification_List; + if(actionsRemoved->list.array) + { + for(elementIdx = 0; elementIdx < actionsRemoved->list.count; elementIdx++) + { + DU_FREE(actionsRemoved->list.array[elementIdx], sizeof(RICaction_RemovedForModification_ItemIEs_t)); + } + DU_FREE(actionsRemoved->list.array, actionsRemoved->list.size); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsFailedToBeRemovedForModification_List: + { + actionsFailedToBeRemoved = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeRemovedForModification_List; + if(actionsFailedToBeRemoved->list.array) + { + for(elementIdx = 0; elementIdx < actionsFailedToBeRemoved->list.count; elementIdx++) + { + DU_FREE(actionsFailedToBeRemoved->list.array[elementIdx], sizeof(RICaction_FailedToBeRemovedForModification_ItemIEs_t)); + } + DU_FREE(actionsFailedToBeRemoved->list.array, actionsFailedToBeRemoved->list.size); + } + break; + } + case ProtocolIE_IDE2_id_RICactionsModifiedForModification_List: + { + actionsModified = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_ModifiedForModification_List; + if(actionsModified->list.array) + { + for(elementIdx = 0; elementIdx < actionsModified->list.count; elementIdx++) + { + DU_FREE(actionsModified->list.array[elementIdx], sizeof(RICaction_ModifiedForModification_ItemIEs_t)); + } + DU_FREE(actionsModified->list.array, actionsModified->list.size); + } + break; + } + case ProtocolIE_IDE2_id_RICactionsFailedToBeModifiedForModification_List: + { + actionsFailedToBeModified = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeModifiedForModification_List; + if(actionsFailedToBeModified->list.array) + { + for(elementIdx = 0; elementIdx < actionsFailedToBeModified->list.count; elementIdx++) + { + DU_FREE(actionsFailedToBeModified->list.array[elementIdx], sizeof(RICaction_FailedToBeModifiedForModification_ItemIEs_t)); + } + DU_FREE(actionsFailedToBeModified->list.array, actionsFailedToBeModified->list.size); + } + break; + } + case ProtocolIE_IDE2_id_RICactionsAddedForModification_List: + { + actionsAdded = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_AddedForModification_List; + if(actionsAdded->list.array) + { + for(elementIdx = 0; elementIdx < actionsAdded->list.count; elementIdx++) + { + DU_FREE(actionsAdded->list.array[elementIdx], sizeof(RICaction_AddedForModification_ItemIEs_t)); + } + DU_FREE(actionsAdded->list.array, actionsAdded->list.size); + } + break; + } + case ProtocolIE_IDE2_id_RICactionsFailedToBeAddedForModification_List: + { + actionsFailedToBeAdded = &ricSubsModResponse->protocolIEs.list.array[ieIdx]->value.choice.RICactions_FailedToBeAddedForModification_List; + if(actionsFailedToBeAdded->list.array) + { + for(elementIdx = 0; elementIdx < actionsFailedToBeAdded->list.count; elementIdx++) + { + DU_FREE(actionsFailedToBeAdded->list.array[elementIdx], sizeof(RICaction_FailedToBeAddedForModification_ItemIEs_t)); + } + DU_FREE(actionsFailedToBeAdded->list.array, actionsFailedToBeAdded->list.size); + } + break; + } + } + DU_FREE(ricSubsModResponse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationResponse_IEs_t)); + } + } + DU_FREE(ricSubsModResponse->protocolIEs.list.array, ricSubsModResponse->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));; + } +} + +/******************************************************************* +* +* @brief Build Ric subscription action removed list +* +* @details +* +* Function : BuildActionRemovedList +* +* Functionality: Build Ric subs action removed list +* +* @params[in] +* RICactions_RemovedForModification_List_t to be filled +* Num Of Action removed +* Action removed list +* +* @return ROK - success +* RFAILED - failure +* +******************************************************************/ + +uint8_t BuildActionRemovedList(RICactions_RemovedForModification_List_t *removedActionList, uint8_t numOfActionRemoved, uint8_t *actionRemoved) +{ + uint8_t arrIdx=0; + RICaction_RemovedForModification_ItemIEs_t *removedActionItemIe =NULLP; + + removedActionList->list.count = numOfActionRemoved; + removedActionList->list.size = removedActionList->list.count * sizeof(RICaction_RemovedForModification_ItemIEs_t*); + DU_ALLOC(removedActionList->list.array, removedActionList->list.size); + if(!removedActionList->list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } + + for(arrIdx = 0; arrIdx< removedActionList->list.count; arrIdx++) + { + DU_ALLOC(removedActionList->list.array[arrIdx], sizeof(RICaction_RemovedForModification_ItemIEs_t)); + if(!removedActionList->list.array[arrIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } + removedActionItemIe = (RICaction_RemovedForModification_ItemIEs_t*)removedActionList->list.array[arrIdx]; + removedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_RemovedForModification_Item; + removedActionItemIe->criticality = CriticalityE2_ignore; + removedActionItemIe->value.present = RICaction_RemovedForModification_ItemIEs__value_PR_RICaction_RemovedForModification_Item; + removedActionItemIe->value.choice.RICaction_RemovedForModification_Item.ricActionID = actionRemoved[arrIdx]; + } + return ROK; +} +/******************************************************************* +* +* @brief Build Ric subscription action added list +* +* @details +* +* Function : BuildActionAddedList +* +* Functionality: Build Ric subs action added list +* +* @params[in] +* RICactions_AddedForModification_List_t to be filled +* Num Of Action added +* Action added list +* +* @return ROK - success +* RFAILED - failure +* +******************************************************************/ - ret = ROK; - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; - break; - }while(true); +uint8_t BuildActionAddedList(RICactions_AddedForModification_List_t *addedActionList, uint8_t numOfActionAdded, uint8_t *actionAdded) +{ + uint8_t arrIdx=0; + RICaction_AddedForModification_ItemIEs_t *addedActionItemIe =NULLP; - /* Free all memory */ - FreeRemovalRequest(e2apMsg); - - return ret; + addedActionList->list.count = numOfActionAdded; + addedActionList->list.size = addedActionList->list.count * sizeof(RICaction_AddedForModification_ItemIEs_t*); + DU_ALLOC(addedActionList->list.array, addedActionList->list.size); + if(!addedActionList->list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } + + for(arrIdx = 0; arrIdx< addedActionList->list.count; arrIdx++) + { + DU_ALLOC(addedActionList->list.array[arrIdx], sizeof(RICaction_AddedForModification_ItemIEs_t)); + if(!addedActionList->list.array[arrIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } + addedActionItemIe = (RICaction_AddedForModification_ItemIEs_t*)addedActionList->list.array[arrIdx]; + addedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_AddedForModification_Item; + addedActionItemIe->criticality = CriticalityE2_ignore; + addedActionItemIe->value.present = RICaction_AddedForModification_ItemIEs__value_PR_RICaction_AddedForModification_Item; + addedActionItemIe->value.choice.RICaction_AddedForModification_Item.ricActionID = actionAdded[arrIdx]; + } + return ROK; } -/****************************************************************** - * - * @brief Deallocation of memory allocated by aper decoder - * for Removal failure - * - * @details - * - * Function : freeAperDecodingOfE2RemovalFailure - * - * Functionality: Deallocation of memory allocated by aper decoder - * for Removal failure - * - * @params[in] Pointer to removalFailure - * @return void - * - * ****************************************************************/ -void freeAperDecodingOfE2RemovalFailure(E2RemovalFailure_t *removalFailure) +/******************************************************************* +* +* @brief Build Ric subscription action modified list +* +* @details +* +* Function : BuildActionModifiedList +* +* Functionality: Build Ric subs action modified list +* +* @params[in] +* RICactions_ModifiedForModification_List_t to be filled +* Num Of Action modified +* Action modified list +* +* @return ROK - success +* RFAILED - failure +* +******************************************************************/ + +uint8_t BuildActionModifiedList(RICactions_ModifiedForModification_List_t *modifiedActionList, uint8_t numOfActionModified, uint8_t *actionModified) { uint8_t arrIdx=0; + RICaction_ModifiedForModification_ItemIEs_t *modifiedActionItemIe =NULLP; - if(removalFailure) + modifiedActionList->list.count = numOfActionModified; + modifiedActionList->list.size = modifiedActionList->list.count * sizeof(RICaction_ModifiedForModification_ItemIEs_t*); + DU_ALLOC(modifiedActionList->list.array, modifiedActionList->list.size); + if(!modifiedActionList->list.array) { - if(removalFailure->protocolIEs.list.array) + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } + + for(arrIdx = 0; arrIdx< modifiedActionList->list.count; arrIdx++) + { + DU_ALLOC(modifiedActionList->list.array[arrIdx], sizeof(RICaction_ModifiedForModification_ItemIEs_t)); + if(!modifiedActionList->list.array[arrIdx]) { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - if(removalFailure->protocolIEs.list.array[arrIdx]) - { - free(removalFailure->protocolIEs.list.array[arrIdx]); - } - } - free(removalFailure->protocolIEs.list.array); + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } + modifiedActionItemIe = (RICaction_ModifiedForModification_ItemIEs_t*)modifiedActionList->list.array[arrIdx]; + modifiedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_ModifiedForModification_Item; + modifiedActionItemIe->criticality = CriticalityE2_ignore; + modifiedActionItemIe->value.present = RICaction_ModifiedForModification_ItemIEs__value_PR_RICaction_ModifiedForModification_Item; + modifiedActionItemIe->value.choice.RICaction_ModifiedForModification_Item.ricActionID = actionModified[arrIdx]; } + return ROK; } -/****************************************************************** +/******************************************************************* * - * @brief Processes the E2 removal failure msg + * @brief Build Ric subscription action failed to be removed list * * @details * - * Function : procE2RemovalFailure + * Function : BuildActionFailedToBeRemovedList * - * Functionality: Processes the E2 removal failure msg + * Functionality: Build Ric subs action failed to be removed list * - * @params[in] - * E2AP_PDU_t *e2apMsg + * @params[in] + * RICactions_FailedToBeRemovedForModification_List_t to be filled + * Num Of Action failed to be removed + * Action failed to be removed list * - * @return void + * @return ROK - success + * RFAILED - failure * - * ****************************************************************/ -void ProcE2RemovalFailure(E2AP_PDU_t *e2apMsg) -{ - uint8_t ieIdx = 0, transId=0; - CauseE2_t *cause = NULLP; - E2RemovalFailure_t *e2RemovalFailure=NULLP; + ******************************************************************/ - e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure; +uint8_t BuildActionFailedToBeRemovedList(RICactions_FailedToBeRemovedForModification_List_t *failedToBeRemovedActionList,\ +uint8_t numOfActionFailedToBeRemoved, RejectedAction *actionFailedToBeRemoved) +{ + uint8_t arrIdx=0; + RICaction_FailedToBeRemovedForModification_ItemIEs_t *failedToBeRemovedActionItemIe =NULLP; - if(!e2RemovalFailure->protocolIEs.list.array) + failedToBeRemovedActionList->list.count = numOfActionFailedToBeRemoved; + failedToBeRemovedActionList->list.size = failedToBeRemovedActionList->list.count * sizeof(RICaction_FailedToBeRemovedForModification_ItemIEs_t*); + DU_ALLOC(failedToBeRemovedActionList->list.array, failedToBeRemovedActionList->list.size); + if(!failedToBeRemovedActionList->list.array) { - DU_LOG("\nERROR --> E2AP : e2RemovalFailure array pointer is null"); - return; + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } - - for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++) + + for(arrIdx = 0; arrIdx< failedToBeRemovedActionList->list.count; arrIdx++) { - if(e2RemovalFailure->protocolIEs.list.array[ieIdx]) + DU_ALLOC(failedToBeRemovedActionList->list.array[arrIdx], sizeof(RICaction_FailedToBeRemovedForModification_ItemIEs_t)); + if(!failedToBeRemovedActionList->list.array[arrIdx]) { - switch(e2RemovalFailure->protocolIEs.list.array[ieIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: - { - transId = e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; - if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\ - (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode)) - { - memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); - } - else - { - DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - } - break; - } - case ProtocolIE_IDE2_id_CauseE2: - { - cause = &e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2; - printE2ErrorCause(cause); - break; - } - default: - { - DU_LOG("\nERROR --> E2AP : Received Invalid Ie [%ld]", e2RemovalFailure->protocolIEs.list.array[ieIdx]->id); - break; - } - } + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } + failedToBeRemovedActionItemIe = (RICaction_FailedToBeRemovedForModification_ItemIEs_t*)failedToBeRemovedActionList->list.array[arrIdx]; + failedToBeRemovedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_FailedToBeRemovedForModification_Item; + failedToBeRemovedActionItemIe->criticality = CriticalityE2_ignore; + failedToBeRemovedActionItemIe->value.present = RICaction_FailedToBeRemovedForModification_ItemIEs__value_PR_RICaction_FailedToBeRemovedForModification_Item; + failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.ricActionID = actionFailedToBeRemoved[arrIdx].id; + fillE2Cause(&failedToBeRemovedActionItemIe->value.choice.RICaction_FailedToBeRemovedForModification_Item.cause, actionFailedToBeRemoved[arrIdx].failureCause); } - freeAperDecodingOfE2RemovalFailure(e2RemovalFailure); + return ROK; } - /****************************************************************** - * - * @brief Deallocation of memory allocated by aper decoder - * for Removal failure - * - * @details - * - * Function : freeAperDecodingOfE2RemovalResponse - * - * Functionality: Deallocation of memory allocated by aper decoder - * for Removal failure - * - * @params[in] Pointer to removalResponse - * @return void - * - * ****************************************************************/ - void freeAperDecodingOfE2RemovalResponse(E2RemovalResponse_t *removalResponse) - { - uint8_t arrIdx=0; - - if(removalResponse) - { - if(removalResponse->protocolIEs.list.array) - { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - if(removalResponse->protocolIEs.list.array[arrIdx]) - { - free(removalResponse->protocolIEs.list.array[arrIdx]); - } - } - free(removalResponse->protocolIEs.list.array); - } - } - } - /******************************************************************* * - * @brief process the E2 Removal Response + * @brief Build Ric subscription action failed to be modified list * * @details * - * Function : ProcE2RemovalResponse + * Function : BuildActionFailedToBeModifiedList * - * Functionality: Process E2 Removal Response + * Functionality: Build Ric subs action failed to be modified list * - * @params[in] - * E2AP_PDU_t *e2apMsg - * @return void + * @params[in] + * RICactions_FailedToBeModifiedForModification_List_t to be filled + * Num Of Action failed to be modified + * Action failed to be modified list + * + * @return ROK - success + * RFAILED - failure * ******************************************************************/ -void ProcE2RemovalResponse(E2AP_PDU_t *e2apMsg) +uint8_t BuildActionFailedToBeModifiedList(RICactions_FailedToBeModifiedForModification_List_t *failedToBeModifiedActionList,\ +uint8_t numOfActionFailedToBeModified, RejectedAction *actionFailedToBeModified) { - uint8_t ieIdx = 0, transId=0; - E2RemovalResponse_t *removalRsp = NULLP; - - removalRsp = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse; + uint8_t arrIdx=0; + RICaction_FailedToBeModifiedForModification_ItemIEs_t *failedToBeModifiedActionItemIe =NULLP; - if(!removalRsp->protocolIEs.list.array) + failedToBeModifiedActionList->list.count = numOfActionFailedToBeModified; + failedToBeModifiedActionList->list.size = failedToBeModifiedActionList->list.count * sizeof(RICaction_FailedToBeModifiedForModification_ItemIEs_t*); + DU_ALLOC(failedToBeModifiedActionList->list.array, failedToBeModifiedActionList->list.size); + if(!failedToBeModifiedActionList->list.array) { - DU_LOG("\nERROR --> E2AP : removalRsp array pointer is null"); - return; + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } - for(ieIdx=0; ieIdx < removalRsp->protocolIEs.list.count; ieIdx++) + for(arrIdx = 0; arrIdx< failedToBeModifiedActionList->list.count; arrIdx++) { - if(removalRsp->protocolIEs.list.array[ieIdx]) + DU_ALLOC(failedToBeModifiedActionList->list.array[arrIdx], sizeof(RICaction_FailedToBeModifiedForModification_ItemIEs_t)); + if(!failedToBeModifiedActionList->list.array[arrIdx]) { - switch(removalRsp->protocolIEs.list.array[ieIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: - { - transId = removalRsp->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; - if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) &&\ - (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode)) - { - removeE2NodeInformation(); - memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); - } - else - { - DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - } - break; - } - default: - { - DU_LOG("\nERROR --> E2AP : Received Invalid Ie [%ld]", removalRsp->protocolIEs.list.array[ieIdx]->id); - break; - } - } + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } + failedToBeModifiedActionItemIe = (RICaction_FailedToBeModifiedForModification_ItemIEs_t*)failedToBeModifiedActionList->list.array[arrIdx]; + failedToBeModifiedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_FailedToBeModifiedForModification_Item; + failedToBeModifiedActionItemIe->criticality = CriticalityE2_ignore; + failedToBeModifiedActionItemIe->value.present = RICaction_FailedToBeModifiedForModification_ItemIEs__value_PR_RICaction_FailedToBeModifiedForModification_Item; + failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.ricActionID = actionFailedToBeModified[arrIdx].id; + fillE2Cause(&failedToBeModifiedActionItemIe->value.choice.RICaction_FailedToBeModifiedForModification_Item.cause, actionFailedToBeModified[arrIdx].failureCause); } - - freeAperDecodingOfE2RemovalResponse(removalRsp); + return ROK; } /******************************************************************* * - * @brief Deallocate the memory allocated for E2 Connection Update Failure + * @brief Build Ric subscription action failed to be added list * * @details * - * Function : FreeE2ConnectionUpdateFailure + * Function : BuildActionFailedToBeAddedList * - * Functionality: - * - freeing the memory allocated for E2ConnectionUpdateFailure + * Functionality: Build Ric subs action failed to be added list + * + * @params[in] + * RICactions_FailedToBeAddedForModification_List_t to be filled + * Num Of Action failed to be added + * Action failed to be added list * - * @params[in] E2AP_PDU_t *e2apMsg * @return ROK - success * RFAILED - failure * - * ****************************************************************/ -void FreeE2ConnectionUpdateFailure(E2AP_PDU_t *e2apMsg) + ******************************************************************/ + +uint8_t BuildActionFailedToBeAddedList(RICactions_FailedToBeAddedForModification_List_t *failedToBeAddedActionList, uint8_t numOfActionFailedToBeAdded, RejectedAction *actionFailedToBeAdded) { - uint8_t ieIdx =0; - E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP; + uint8_t arrIdx=0; + RICaction_FailedToBeAddedForModification_ItemIEs_t *failedToBeAddedActionItemIe =NULLP; + + failedToBeAddedActionList->list.count = numOfActionFailedToBeAdded; + failedToBeAddedActionList->list.size = failedToBeAddedActionList->list.count * sizeof(RICaction_FailedToBeAddedForModification_ItemIEs_t*); + DU_ALLOC(failedToBeAddedActionList->list.array, failedToBeAddedActionList->list.size); + if(!failedToBeAddedActionList->list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } - if(e2apMsg != NULLP) + for(arrIdx = 0; arrIdx< failedToBeAddedActionList->list.count; arrIdx++) { - if(e2apMsg->choice.unsuccessfulOutcome != NULLP) + DU_ALLOC(failedToBeAddedActionList->list.array[arrIdx], sizeof(RICaction_FailedToBeAddedForModification_ItemIEs_t)); + if(!failedToBeAddedActionList->list.array[arrIdx]) { - e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure; - if(e2ConnectionUpdateFailure->protocolIEs.list.array) - { - for(ieIdx=0; ieIdx < e2ConnectionUpdateFailure->protocolIEs.list.count; ieIdx++) - { - DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t)); - } - DU_FREE(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size); - } - DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } - DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + failedToBeAddedActionItemIe = (RICaction_FailedToBeAddedForModification_ItemIEs_t*)failedToBeAddedActionList->list.array[arrIdx]; + failedToBeAddedActionItemIe->id = ProtocolIE_IDE2_id_RICaction_FailedToBeAddedForModification_Item; + failedToBeAddedActionItemIe->criticality = CriticalityE2_ignore; + failedToBeAddedActionItemIe->value.present = RICaction_FailedToBeAddedForModification_ItemIEs__value_PR_RICaction_FailedToBeAddedForModification_Item; + failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.ricActionID = actionFailedToBeAdded[arrIdx].id; + fillE2Cause(&failedToBeAddedActionItemIe->value.choice.RICaction_FailedToBeAddedForModification_Item.cause, actionFailedToBeAdded[arrIdx].failureCause); } + return ROK; } /******************************************************************* * - * @brief Buld and send the E2 Connection Update Failure msg + * @brief Builds and Send RIC Subscription Modification Response * * @details * - * Function : BuildAndSendE2ConnectionUpdateFailure + * Function : BuildAndSendRicSubscriptionModificationResponse * - * Functionality: - * - Buld and send the E2 Connection Update Failure Message - * @params[in] - * Trans Id - * Failure Cause + * Functionality: Build and send RIC Subscription Modification Response. + * + * @params[in] + * PendingSubsModRspInfo * @return ROK - success * RFAILED - failure * - * ****************************************************************/ - -uint8_t BuildAndSendE2ConnectionUpdateFailure(uint16_t transId, E2FailureCause failureCause) + ******************************************************************/ +uint8_t BuildAndSendRicSubscriptionModificationResponse(PendingSubsModRspInfo *pendingSubsModRsp) { - uint8_t ieIdx = 0, elementCnt = 0; - uint8_t ret = RFAILED; - E2AP_PDU_t *e2apMsg = NULLP; - E2connectionUpdateFailure_t *e2ConnectionUpdateFailure=NULLP; - asn_enc_rval_t encRetVal; /* Encoder return value */ + uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionModificationResponse_t *ricSubsModResponse = NULLP; + RICsubscriptionModificationResponse_IEs_t *ricSubsModResponseIe = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ - DU_LOG("\nINFO --> E2AP : Building E2 Connection Update Failure Message\n"); - do + while(true) { + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Modification Response Message\n"); + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); if(e2apMsg == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } - e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; - DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); - if(e2apMsg->choice.unsuccessfulOutcome == NULLP) + e2apMsg->present = E2AP_PDU_PR_successfulOutcome; + DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(e2apMsg->choice.successfulOutcome == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } + e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscriptionModification; + e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationResponse; - e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2connectionUpdate; - e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; - e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2connectionUpdateFailure; - e2ConnectionUpdateFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2connectionUpdateFailure; + + ricSubsModResponse = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationResponse; elementCnt = 2; - e2ConnectionUpdateFailure->protocolIEs.list.count = elementCnt; - e2ConnectionUpdateFailure->protocolIEs.list.size = elementCnt * sizeof(E2connectionUpdateFailure_IEs_t *); - DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array, e2ConnectionUpdateFailure->protocolIEs.list.size); - if(!e2ConnectionUpdateFailure->protocolIEs.list.array) + if(pendingSubsModRsp->removeActionStatus.numOfAcceptedActions) + elementCnt++; + if(pendingSubsModRsp->addActionStatus.numOfAcceptedActions) + elementCnt++; + if(pendingSubsModRsp->modActionStatus.numOfAcceptedActions) + elementCnt++; + if(pendingSubsModRsp->removeActionStatus.numOfRejectedActions) + elementCnt++; + if(pendingSubsModRsp->addActionStatus.numOfRejectedActions) + elementCnt++; + if(pendingSubsModRsp->modActionStatus.numOfRejectedActions) + elementCnt++; + + ricSubsModResponse->protocolIEs.list.count = elementCnt; + ricSubsModResponse->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationResponse_IEs_t *); + + DU_ALLOC(ricSubsModResponse->protocolIEs.list.array, ricSubsModResponse->protocolIEs.list.size); + if(ricSubsModResponse->protocolIEs.list.array == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); break; } - for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) { - DU_ALLOC(e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx], sizeof(E2connectionUpdateFailure_IEs_t)); - if(!e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]) + DU_ALLOC(ricSubsModResponse->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationResponse_IEs_t)); + if(ricSubsModResponse->protocolIEs.list.array[ieIdx] == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); break; } } @@ -8356,172 +10872,144 @@ uint8_t BuildAndSendE2ConnectionUpdateFailure(uint16_t transId, E2FailureCause f break; ieIdx = 0; - e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; - e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; - e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_TransactionID; - e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsModResponseIe->criticality = CriticalityE2_reject; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICrequestID; + ricSubsModResponseIe->value.choice.RICrequestID.ricRequestorID= pendingSubsModRsp->requestId.requestorId; + ricSubsModResponseIe->value.choice.RICrequestID.ricInstanceID = pendingSubsModRsp->requestId.instanceId; - /* Cause */ ieIdx++; - e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2; - e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore; - e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.present = E2connectionUpdateFailure_IEs__value_PR_CauseE2; - fillE2Cause(&e2ConnectionUpdateFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause); - - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsModResponseIe->criticality = CriticalityE2_reject; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RANfunctionID; + ricSubsModResponseIe->value.choice.RANfunctionID = pendingSubsModRsp->ranFuncId; + + if(pendingSubsModRsp->removeActionStatus.numOfAcceptedActions) + { + ieIdx++; + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsRemovedForModification_List; + ricSubsModResponseIe->criticality = CriticalityE2_ignore; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_RemovedForModification_List; + if(BuildActionRemovedList(&ricSubsModResponseIe->value.choice.RICactions_RemovedForModification_List,\ + pendingSubsModRsp->removeActionStatus.numOfAcceptedActions, pendingSubsModRsp->removeActionStatus.acceptedActionList) != ROK) + { + DU_LOG("\nERROR --> E2AP : failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + + if(pendingSubsModRsp->removeActionStatus.numOfRejectedActions) + { + ieIdx++; + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsFailedToBeRemovedForModification_List; + ricSubsModResponseIe->criticality = CriticalityE2_ignore; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_FailedToBeRemovedForModification_List; + if(BuildActionFailedToBeRemovedList(&ricSubsModResponseIe->value.choice.RICactions_FailedToBeRemovedForModification_List,\ + pendingSubsModRsp->removeActionStatus.numOfRejectedActions, pendingSubsModRsp->removeActionStatus.rejectedActionList) != ROK) + { + DU_LOG("\nERROR --> E2AP : failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + + if(pendingSubsModRsp->modActionStatus.numOfAcceptedActions) + { + ieIdx++; + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsModifiedForModification_List; + ricSubsModResponseIe->criticality = CriticalityE2_ignore; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_ModifiedForModification_List; + if(BuildActionModifiedList(&ricSubsModResponseIe->value.choice.RICactions_ModifiedForModification_List,\ + pendingSubsModRsp->modActionStatus.numOfAcceptedActions, pendingSubsModRsp->modActionStatus.acceptedActionList) != ROK) + { + DU_LOG("\nERROR --> E2AP : failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + + if(pendingSubsModRsp->modActionStatus.numOfRejectedActions) + { + ieIdx++; + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsFailedToBeModifiedForModification_List; + ricSubsModResponseIe->criticality = CriticalityE2_ignore; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_FailedToBeModifiedForModification_List; + if(BuildActionFailedToBeModifiedList(&ricSubsModResponseIe->value.choice.RICactions_FailedToBeModifiedForModification_List,\ + pendingSubsModRsp->modActionStatus.numOfRejectedActions, pendingSubsModRsp->modActionStatus.rejectedActionList) != ROK) + { + DU_LOG("\nERROR --> E2AP : failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + if(pendingSubsModRsp->addActionStatus.numOfAcceptedActions) + { + ieIdx++; + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsAddedForModification_List; + ricSubsModResponseIe->criticality = CriticalityE2_ignore; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_AddedForModification_List; + if(BuildActionAddedList(&ricSubsModResponseIe->value.choice.RICactions_AddedForModification_List,\ + pendingSubsModRsp->addActionStatus.numOfAcceptedActions, pendingSubsModRsp->addActionStatus.acceptedActionList) != ROK) + { + DU_LOG("\nERROR --> E2AP : failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + + if(pendingSubsModRsp->addActionStatus.numOfRejectedActions) + { + ieIdx++; + ricSubsModResponseIe = ricSubsModResponse->protocolIEs.list.array[ieIdx]; + ricSubsModResponseIe->id = ProtocolIE_IDE2_id_RICactionsFailedToBeAddedForModification_List; + ricSubsModResponseIe->criticality = CriticalityE2_ignore; + ricSubsModResponseIe->value.present = RICsubscriptionModificationResponse_IEs__value_PR_RICactions_FailedToBeAddedForModification_List; + if(BuildActionFailedToBeAddedList(&ricSubsModResponseIe->value.choice.RICactions_FailedToBeAddedForModification_List,\ + pendingSubsModRsp->addActionStatus.numOfRejectedActions, pendingSubsModRsp->addActionStatus.rejectedActionList) != ROK) + { + DU_LOG("\nERROR --> E2AP : failed at [%s] : line [%d]", __func__, __LINE__); + break; + } + } + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); memset(encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode E2 connection update failure structure (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Modification Response Message (at %s)\n",\ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); break; } else { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Connection Update Failure \n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Modification Response Message \n"); +#ifdef DEBUG_ASN_PRINT for(int i=0; i< encBufSize; i++) { - DU_LOG("%x",encBuf[i]); + printf("%x",encBuf[i]); } +#endif } - /* Sending msg */ if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { - DU_LOG("\nERROR --> E2AP : Failed to send E2 Connection Update Failure"); + DU_LOG("\nERROR --> E2AP : Failed to send RIC Susbcription Modification Response Message"); break; } ret = ROK; break; - }while(true); - - FreeE2ConnectionUpdateFailure(e2apMsg); - return ret; -} - -/****************************************************************** - * - * @brief Deallocation of memory allocated by aper decoder for - * E2 Connection Update - * - * @details - * - * Function :freeAperDecodingOfE2ConnectionUpdate - * - * Functionality: Deallocation of memory allocated by aper decoder for - * E2 Connection Update - * - * @params[in] Pointer to connectionUpdate - * @return void - * - * ****************************************************************/ - -void freeAperDecodingOfE2ConnectionUpdate(E2connectionUpdate_t *connectionUpdate) -{ - uint8_t ieIdx =0, arrIdx=0; - E2connectionUpdate_List_t *connectionToBeModifyList = NULLP; - - if(connectionUpdate->protocolIEs.list.array) - { - for(ieIdx = 0; ieIdx < connectionUpdate->protocolIEs.list.count; ieIdx++) - { - if(connectionUpdate->protocolIEs.list.array[ieIdx]) - { - switch(connectionUpdate->protocolIEs.list.array[ieIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: - break; - - case ProtocolIE_IDE2_id_E2connectionUpdateModify: - { - connectionToBeModifyList = &connectionUpdate->protocolIEs.list.array[ieIdx]->value.choice.E2connectionUpdate_List; - if(connectionToBeModifyList->list.array) - { - for(arrIdx= 0; arrIdx< connectionToBeModifyList->list.count; arrIdx++) - { - free(connectionToBeModifyList->list.array[arrIdx]); - } - free(connectionToBeModifyList->list.array); - } - break; - } - } - free(connectionUpdate->protocolIEs.list.array[ieIdx]); - } - } - free(connectionUpdate->protocolIEs.list.array); - } -} - -/******************************************************************* - * - * @brief Process e2 connection update received from RIC - * - * @details - * - * Function : procE2ConnectionUpdate - * - * Functionality: Process e2 connection update received from RIC - * - * @param E2AP_PDU_t *e2apMsg - * @return void - * - ******************************************************************/ - -void procE2ConnectionUpdate(E2AP_PDU_t *e2apMsg) -{ - bool invalidTransId = false; - uint8_t arrIdx =0, transId =0, count=0; - E2FailureCause failureCause; - E2connectionUpdate_t *connectionUpdate=NULLP; - - DU_LOG("\nINFO --> E2AP : E2 connection update received"); - connectionUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2connectionUpdate; - - count = connectionUpdate->protocolIEs.list.count; - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - switch(connectionUpdate->protocolIEs.list.array[arrIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: - { - transId = connectionUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; - if(transId>255) - { - invalidTransId = true; - } - break; - } - case ProtocolIE_IDE2_id_E2connectionUpdateModify: - { - /*TODO*/ - break; - } - } - - if(invalidTransId == true) - break; - } - - if(invalidTransId == true) - { - failureCause.causeType = E2_PROTOCOL; - failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE; - if(BuildAndSendE2ConnectionUpdateFailure(transId, failureCause) != ROK) - { - DU_LOG("\nERROR --> E2AP : Failed to build and send E2 connection update failure"); - } - } - else - { - /*TODO*/ } - freeAperDecodingOfE2ConnectionUpdate(connectionUpdate); + FreeRicSubscriptionModificationResponse(e2apMsg); + return ret; } /******************************************************************* @@ -8724,6 +11212,12 @@ void E2APMsgHdlr(Buffer *mBuf) procE2ConnectionUpdate(e2apMsg); break; } + case InitiatingMessageE2__value_PR_RICsubscriptionModificationRequest: + { + DU_LOG("\nINFO --> E2AP : RIC Subscription Modification Request received"); + procRicSubscriptionModificationRequest(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\