X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fdu_app%2Fdu_e2ap_msg_hdl.c;h=0a5cec50b95e21c977c3963f3211c56cd60adad5;hb=refs%2Fchanges%2F60%2F11860%2F5;hp=bef81af0e85d5259627748ae3da564f0a9bf1d54;hpb=a3796bdbd76c38cd78ed1c9ef5cbf4cee1c355de;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 bef81af0e..0a5cec50b 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -2560,13 +2560,7 @@ uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoLis * Break out of for loop to search in next report style */ if(!measInfoSubscribedDb) { - while(measInfoSubscribedList->count) - { - measToDelNode = cmLListDelFrm(measInfoSubscribedList, measInfoSubscribedList->first); - measInfoToDel = (MeasurementInfo*)measToDelNode->node; - DU_FREE(measInfoToDel, sizeof(MeasurementInfo)); - DU_FREE(measToDelNode, sizeof(CmLList)); - } + deleteMeasurementInfoList(measInfoSubscribedList); break; } @@ -2752,8 +2746,7 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu /* In case of any failure, action is rejected * Added to rejected-action-list in subscription response */ - memset(&ricSubscriptionInfo->actionSequence[ricActionId], 0, sizeof(ActionInfo)); - ricSubscriptionInfo->actionSequence[ricActionId].actionId = -1; + deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]); subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId; if(failureCause->causeType == E2_NOTHING) @@ -3374,16 +3367,11 @@ uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInf measRecord->list.array[measRecIdx]->choice.real = measVal; } measRecIdx++; - + measValNode= measValNode->next; /* Once the measurement record is added to the message, delete it from DB */ - cmLListDelFrm(&measInfoDb->measuredValue, measValNode); - DU_FREE(measValNode->node, sizeof(double)); - DU_FREE(measValNode, sizeof(CmLList)); - - CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode); measVal = 0; } - + deleteMeasuredValueList(&measInfoDb->measuredValue); return ROK; } @@ -5553,161 +5541,1167 @@ uint8_t duSendE2NodeConfigurationUpdate() } return ROK; } + /******************************************************************* * - * @brief Handles received E2AP message and sends back response + * @brief Free RIC Subscription Modification Required * * @details * - * Function : E2APMsgHdlr + * Function : FreeRicSubsModRequired * - * Functionality: - * - Decodes received E2AP control message - * - Prepares response message, encodes and sends to SCTP + * Functionality: Freqq RIC Subscription Modification required * - * @params[in] + * @param E2AP Message PDU to be freed + * @return void + * + ******************************************************************/ +void FreeRicSubsModRequired(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0, arrIdx = 0; + RICsubscriptionModificationRequired_t *ricSubsModReqd = NULLP; + RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP; + RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP; + RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList = NULLP; + + if(e2apMsg) + { + if(e2apMsg->choice.initiatingMessage) + { + ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired; + if(ricSubsModReqd->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < ricSubsModReqd->protocolIEs.list.count; ieIdx++) + { + if(ricSubsModReqd->protocolIEs.list.array[ieIdx]) + { + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + switch(ricSubsModReqdIe->id) + { + case ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List: + { + actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List; + if(actionToBeModList->list.array) + { + for(arrIdx = 0; arrIdx < actionToBeModList->list.count; arrIdx++) + { + DU_FREE(actionToBeModList->list.array[arrIdx], \ + sizeof(RICaction_RequiredToBeModified_ItemIEs_t)); + } + DU_FREE(actionToBeModList->list.array, actionToBeModList->list.size); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List: + { + actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List; + if(actionToBeRmvList->list.array) + { + for(arrIdx = 0; arrIdx < actionToBeRmvList->list.count; arrIdx++) + { + DU_FREE(actionToBeRmvList->list.array[arrIdx], \ + sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t)); + } + DU_FREE(actionToBeRmvList->list.array, actionToBeRmvList->list.size); + } + break; + } + + default: + break; + } + DU_FREE(ricSubsModReqd->protocolIEs.list.array[ieIdx], \ + sizeof(RICsubscriptionModificationRequired_IEs_t)); + } + } + DU_FREE(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/* A RIC Subscription includes RIC subsequent action only for RIC Insert service. + * However, E2SM-KPM supports only RIC Report service. + * Hence there is no subsequent action in RIC subscription that may require modification. + * So commenting the action-modification IEs for the time being + */ +#if 0 +/******************************************************************* + * + * @brief Fill Action required to be modified list + * + * @details + * + * Function : FillActionReqdToBeModList + * + * Functionality: Fill Action required to be modified list + * + * @param RIC Actions Required To Be Modified List to be filled + * Number of actions to be modified + * RIC Subscription DB * @return ROK - success * RFAILED - failure * - * ****************************************************************/ -void E2APMsgHdlr(Buffer *mBuf) + ******************************************************************/ +uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \ + RicSubscription *ricSubscription) { - int i =0; - char *recvBuf = NULLP; - MsgLen copyCnt =0; - MsgLen recvBufLen =0; - E2AP_PDU_t *e2apMsg = NULLP; - asn_dec_rval_t rval ={0}; /* Decoder return value */ - E2AP_PDU_t e2apasnmsg={0} ; + uint8_t arrIdx = 0, actionIdx = 0; + RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL; - DU_LOG("\nDEBUG --> E2AP : Received E2AP message buffer"); - ODU_PRINT_MSG(mBuf, 0,0); + actionToBeModList->list.count = numActionsMod; + actionToBeModList->list.size = numActionsMod * sizeof(RICaction_RequiredToBeModified_ItemIEs_t *); + DU_ALLOC(actionToBeModList->list.array, actionToBeModList->list.size); + if(!actionToBeModList->list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + return RFAILED; + } - /* Copy mBuf into char array to decode it */ - ODU_GET_MSG_LEN(mBuf, &recvBufLen); - DU_ALLOC(recvBuf, (Size)recvBufLen); + arrIdx = 0; + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + { + if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD) + { + DU_ALLOC(actionToBeModList->list.array[arrIdx], sizeof(RICaction_RequiredToBeModified_ItemIEs_t)); + if(!actionToBeModList->list.array[arrIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + return RFAILED; + } + actionToBeMod = (RICaction_RequiredToBeModified_ItemIEs_t *)actionToBeModList->list.array[arrIdx]; - if(recvBuf == NULLP) + actionToBeMod->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeModified_Item; + actionToBeMod->criticality = CriticalityE2_reject; + actionToBeMod->value.present = \ + RICaction_RequiredToBeModified_ItemIEs__value_PR_RICaction_RequiredToBeModified_Item; + actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricActionID = \ + ricSubscription->actionSequence[actionIdx].actionId; + actionToBeMod->value.choice.RICaction_RequiredToBeModified_Item.ricTimeToWait = RICtimeToWait_w5ms; + + arrIdx++; + } + } + + return ROK; +} +#endif + +/******************************************************************* + * + * @brief Fill Action required to be removed list + * + * @details + * + * Function : FillActionReqdToBeRmvList + * + * Functionality: Fill Action required to be removed list + * + * @param RIC Actions Required To Be Removed List to be filled + * Number of actions to be removed + * RIC Subscription DB + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList, uint8_t numActionsRmv, \ + RicSubscription *ricSubscription) +{ + uint8_t arrIdx = 0, actionIdx = 0; + RICaction_RequiredToBeRemoved_ItemIEs_t *actionToBeRmv = NULL; + + actionToBeRmvList->list.count = numActionsRmv; + actionToBeRmvList->list.size = numActionsRmv * sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t *); + DU_ALLOC(actionToBeRmvList->list.array, actionToBeRmvList->list.size); + if(!actionToBeRmvList->list.array) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed"); - return; + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; } - if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK) + + arrIdx = 0; + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) { - DU_LOG("\nERROR --> E2AP : Failed while copying %d", copyCnt); - return; + if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL) + { + DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t)); + if(!actionToBeRmvList->list.array[arrIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; + } + actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx]; + + actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item; + 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); + + arrIdx++; + } } -#ifdef DEBUG_ASN_PRINT - printf("\nDEBUG --> E2AP : Received flat buffer to be decoded : "); - for(i=0; i< recvBufLen; i++) + return ROK; +} + +/******************************************************************* + * + * @brief Fill RIC Subscription Modification Required IEs + * + * @details + * + * Function : FillRicSubsModRequired + * + * Functionality: Fill RIC Subscription Modification Required IEs + * + * @param RIC Subscription Modification Required IEs to be filled + * RIC Subscription DB + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription) +{ + uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0; + uint8_t numActionsMod = 0, numActionsRmv = 0; + RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP; + RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP; + RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList = NULLP; + + /* Count number of Actions to be modified or deleted */ + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) { - printf("%x",recvBuf[i]); + if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD) + numActionsMod++; + else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL) + numActionsRmv++; } -#endif - /* Decoding flat buffer into E2AP messsage */ - e2apMsg = &e2apasnmsg; - memset(e2apMsg, 0, sizeof(E2AP_PDU_t)); + /* Count number of IEs to be added to messages */ + elementCnt = 2; + if(numActionsMod) + elementCnt++; + if(numActionsRmv) + elementCnt++; - rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0); - DU_FREE(recvBuf, (Size)recvBufLen); + ricSubsModReqd->protocolIEs.list.count = elementCnt; + ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *); + DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size); + if(!ricSubsModReqd->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; + } - if(rval.code == RC_FAIL || rval.code == RC_WMORE) + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) { - DU_LOG("\nERROR --> E2AP : ASN decode failed"); - return; + DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t)); + if(!ricSubsModReqd->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; + } } - printf("\n"); - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); - switch(e2apMsg->present) + /* RIC Request ID */ + ieIdx = 0; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID; + ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId; + ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId; + + /* RAN Function ID */ + ieIdx++; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID; + ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId; + +/* A RIC Subscription includes RIC subsequent action only for RIC Insert service. + * However, E2SM-KPM supports only RIC Report service. + * Hence there is no subsequent action in RIC subscription that may require modification. + * So commenting the action-modification IEs for the time being + */ +#if 0 + /* RIC Actions Required to be Modified */ + if(numActionsMod) { - case E2AP_PDU_PR_unsuccessfulOutcome: - { - switch(e2apMsg->choice.unsuccessfulOutcome->value.present) - { - case UnsuccessfulOutcomeE2__value_PR_E2setupFailure: - { - procE2SetupFailure(e2apMsg); - break; - } - case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure: - { - procE2NodeConfigUpdateFailure(e2apMsg); - break; - } - case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure: - { - procRicServiceUpdateFailure(e2apMsg); - break; - } - default: - { - DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome [%d]",\ - e2apMsg->choice.unsuccessfulOutcome->value.present); - return; - } - } - break; - } - case E2AP_PDU_PR_successfulOutcome: - { - switch(e2apMsg->choice.successfulOutcome->value.present) - { - case SuccessfulOutcomeE2__value_PR_E2setupResponse: - { - if(!duCb.e2Status) - { - procE2SetupRsp(e2apMsg); - } - break; - } - case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge: - { - DU_LOG("\nDEBUG --> E2AP : E2 node Config update ack message recevied"); - break; - } - case SuccessfulOutcomeE2__value_PR_ResetResponseE2: - { - procResetResponse(e2apMsg); - break; - } - case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge: - { - procRicServiceUpdateAck(e2apMsg); - break; - } + ieIdx++; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = \ + RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List; + actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List; + if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill actions required to be modified list", __func__); + return RFAILED; + } + } +#endif - default: - { - DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome [%d]",\ - e2apMsg->choice.successfulOutcome->value.present); - return; - } - }/* End of switch(successfulOutcome) */ - free(e2apMsg->choice.successfulOutcome); - break; - } + /* RIC Actions Required to be removed */ + if(numActionsRmv) + { + ieIdx++; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = \ + RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List; + actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List; - case E2AP_PDU_PR_initiatingMessage: - { - switch(e2apMsg->choice.initiatingMessage->value.present) - { - case InitiatingMessageE2__value_PR_RICsubscriptionRequest: - { - procRicSubscriptionRequest(e2apMsg); - break; - } - case InitiatingMessageE2__value_PR_RICserviceQuery: - { - procRicServiceQuery(e2apMsg); - break; - } - case InitiatingMessageE2__value_PR_ErrorIndicationE2: + if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill actions required to be removed list", __func__); + return RFAILED; + } + } + + return ROK; +} + +/******************************************************************* + * + * @brief Builds and Send RIC Subscription Modification Required + * message + * + * @details + * + * Function : BuildAndSendRicSubsModRequired + * + * Functionality: Builds and Send RIC Subscription Modification + * Required message + * + * @param RIC Subscription DB + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription) +{ + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionModificationRequired_t *ricSubsModReqd = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Modification Required \n"); + while(true) + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation 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) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + break; + } + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired; + + ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired; + + if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__); + break; + } + + /* Encode */ + 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 Modifiction Required structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Modification Required \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 RIC Subscription Modification Required failed"); + } + + ret = ROK; + break; + } + + /* Free RIC Subscription modification required */ + FreeRicSubsModRequired(e2apMsg); + return ret; +} + +/******************************************************************* + * + * @brief Free APER decoding of RIC Subscription Modification Confirm + * + * @details + * + * Function : freeAperDecodingOfRicSubsModConfirm + * + * Functionality: Free APER decoding of RIC Subscription + * Modification Confirm + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0, arrIdx=0; + RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP; + RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP; + RICactions_ConfirmedForModification_List_t *modCfmList = NULLP; + RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP; + RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP; + RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP; + + if(e2apMsg && e2apMsg->choice.successfulOutcome) + { + ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm; + if(ricSubsModCfm->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++) + { + if(ricSubsModCfm->protocolIEs.list.array[ieIdx]) + { + ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx]; + switch(ricSubsModCfmIe->id) + { + case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List: + { + modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List; + if(modCfmList->list.array) + { + for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++) + { + if(modCfmList->list.array[arrIdx]) + free(modCfmList->list.array[arrIdx]); + } + free(modCfmList->list.array); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List: + { + modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List; + if(modRefusedList->list.array) + { + for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++) + { + if(modRefusedList->list.array[arrIdx]) + free(modRefusedList->list.array[arrIdx]); + } + free(modRefusedList->list.array); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List: + { + rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List; + if(rmvCfmList->list.array) + { + for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++) + { + if(rmvCfmList->list.array[arrIdx]) + free(rmvCfmList->list.array[arrIdx]); + } + free(rmvCfmList->list.array); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List: + { + rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List; + if(rmvFailList->list.array) + { + for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++) + { + if(rmvFailList->list.array[arrIdx]) + free(rmvFailList->list.array[arrIdx]); + } + free(rmvFailList->list.array); + } + break; + } + + default: + break; + + } + free(ricSubsModCfmIe); + } + } + free(ricSubsModCfm->protocolIEs.list.array); + } + } +} + +/******************************************************************* + * + * @brief Process RIC Subscription Modification Confirm Message + * + * @details + * + * Function : procRicSubscriptionModificationConfirm + * + * Functionality: Process RIC Subscription Modification Confirm + * Message received from RIC. + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) +{ + uint8_t actionId = 0, ieIdx = 0, arrIdx = 0; + uint16_t ranFuncId = 0; + bool procFailure = false; + RicRequestId ricReqId; + RanFunction *ranFuncDb = NULLP; + CmLList *ricSubsNode = NULLP; + RicSubscription *ricSubsDb = NULLP; + ActionInfo *actionDb = NULLP; + + RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP; + RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP; + + RICactions_ConfirmedForModification_List_t *modCfmList = NULLP; + RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP; + + RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP; + RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP; + + RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP; + RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP; + + RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP; + RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP; + + DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Modification Confirm", __func__); + + do{ + if(!e2apMsg) + { + DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + break; + } + + if(!e2apMsg->choice.successfulOutcome) + { + DU_LOG("\nERROR --> E2AP : %s: Successful Outcome in E2AP message is NULL", __func__); + break; + } + + ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm; + if(!ricSubsModCfm->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); + break; + } + + for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++) + { + if(!ricSubsModCfm->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + break; + } + + ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx]; + switch(ricSubsModCfmIe->id) + { + case ProtocolIE_IDE2_id_RICrequestID: + { + memset(&ricReqId, 0, sizeof(RicRequestId)); + ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID; + break; + } + + case ProtocolIE_IDE2_id_RANfunctionID: + { + ranFuncId = ricSubsModCfmIe->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; + } + + break; + } + +/* A RIC Subscription includes RIC subsequent action only for RIC Insert service. + * However, E2SM-KPM supports only RIC Report service. + * Hence there is no subsequent action in RIC subscription that may require modification. + * So commenting the action-modification IEs for the time being + */ +#if 0 + case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List: + { + modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List; + for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++) + { + modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx]; + actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID; + + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + actionDb->action = CONFIG_UNKNOWN; + /* Further handling can be added here in future once the + * use case of this procedure is identified */ + } + actionDb = NULLP; + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List: + { + modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List; + for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++) + { + modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx]; + actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + /* Spec doesnt mention if in case of failure, DU should retry for modify action + * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN + */ + actionDb->action = CONFIG_UNKNOWN; + } + actionDb = NULLP; + } + break; + } +#endif + + case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List: + { + rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List; + for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++) + { + rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx]; + actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + deleteActionSequence(actionDb); + actionDb =NULLP; + ricSubsDb->numOfActions--; + /* Further handling can include : + * Deletion of this action from all DU layers + */ + } + actionDb = NULLP; + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List: + { + rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List; + for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++) + { + rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx]; + actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + actionDb->action = CONFIG_UNKNOWN; + } + actionDb = NULLP; + } + break; + } + + default: + break; + } /* End of switch for Protocol IE Id */ + + if(procFailure) + break; + } /* End of for loop for Protocol IE list */ + + break; + }while(true); + + freeAperDecodingOfRicSubsModConfirm(e2apMsg); + return; +} + +/****************************************************************** +* @brief Deallocate the memory allocated for E2 Reset Response +* +* @details +* +* Function : FreeE2ResetResponse +* +* Functionality: +* - freeing the memory allocated for E2ResetResponse +* +* @params[in] E2AP_PDU_t *e2apMsg +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0; + ResetResponseE2_t *resetResponse; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.successfulOutcome != NULLP) + { + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; + if(resetResponse->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + { + if(resetResponse->protocolIEs.list.array[ieIdx]) + { + DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); + } + } + DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); + } + + DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Buld and send the E2 Reset Response msg + * + * @details + * + * Function : BuildAndSendE2ResetResponse + * + * Functionality: + * - Buld and send the E2 Reset Response Message + * + * @params[in] Trans Id + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendResetResponse(uint8_t transId) +{ + uint8_t ieIdx = 0, elementCnt = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + ResetResponseE2_t *resetResponse; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building E2 Reset Response Message\n"); + do + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed"); + break; + } + e2apMsg->present = E2AP_PDU_PR_successfulOutcome; + + DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(e2apMsg->choice.successfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome"); + break; + } + + e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset; + e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2; + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; + + elementCnt = 1; + resetResponse->protocolIEs.list.count = elementCnt; + resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *); + DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); + if(!resetResponse->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array"); + break; + } + + for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); + if(!resetResponse->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element"); + break; + } + } + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + resetResponse->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID; + resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + 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 reset response structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Reset Response \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 Reset Response"); + break; + } + + ret = ROK; + break; + }while(true); + + FreeE2ResetResponse(e2apMsg); + return ret; +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for reset req + * + * @details + * + * Function : freeAperDecodingOfE2ResetReq + * + * Functionality: Deallocation of memory allocated by aper decoder for + * reset req + * + * @params[in] Pointer to resetReq + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq) +{ + uint8_t arrIdx=0; + + if(resetReq) + { + if(resetReq->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(resetReq->protocolIEs.list.array[arrIdx]) + { + free(resetReq->protocolIEs.list.array[arrIdx]); + } + } + free(resetReq->protocolIEs.list.array); + } + } +} + +/******************************************************************* + * + * @brief Process reset req received from RIC + * + * @details + * + * Function : procE2ResetRequest + * + * Functionality: Process reset req received from RIC + * + * @param E2AP_PDU_t *e2apMsg + * @return void + * + ******************************************************************/ + +void procE2ResetRequest(E2AP_PDU_t *e2apMsg) +{ + uint16_t ranFuncIdx=0; + uint8_t arrIdx =0, transId =0; + ResetRequestE2_t *resetReq; + + DU_LOG("\nINFO --> E2AP : E2 Reset request received"); + resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(resetReq->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; + break; + } + + case ProtocolIE_IDE2_id_CauseE2: + { + for(ranFuncIdx=0; ranFuncIdx0) + { + deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList)); + memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo)); + } + } + break; + } + } + } + if(BuildAndSendResetResponse(transId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send reset response"); + } + freeAperDecodingOfE2ResetReq(resetReq); +} + +/******************************************************************* + * + * @brief Handles received E2AP message and sends back response + * + * @details + * + * Function : E2APMsgHdlr + * + * Functionality: + * - Decodes received E2AP control message + * - Prepares response message, encodes and sends to SCTP + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void E2APMsgHdlr(Buffer *mBuf) +{ + int i =0; + char *recvBuf = NULLP; + MsgLen copyCnt =0; + MsgLen recvBufLen =0; + E2AP_PDU_t *e2apMsg = NULLP; + asn_dec_rval_t rval ={0}; /* Decoder return value */ + E2AP_PDU_t e2apasnmsg={0} ; + + DU_LOG("\nDEBUG --> E2AP : Received E2AP message buffer"); + ODU_PRINT_MSG(mBuf, 0,0); + + /* Copy mBuf into char array to decode it */ + ODU_GET_MSG_LEN(mBuf, &recvBufLen); + DU_ALLOC(recvBuf, (Size)recvBufLen); + + if(recvBuf == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed"); + return; + } + if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed while copying %d", copyCnt); + return; + } + +#ifdef DEBUG_ASN_PRINT + printf("\nDEBUG --> E2AP : Received flat buffer to be decoded : "); + for(i=0; i< recvBufLen; i++) + { + printf("%x",recvBuf[i]); + } +#endif + + /* Decoding flat buffer into E2AP messsage */ + e2apMsg = &e2apasnmsg; + memset(e2apMsg, 0, sizeof(E2AP_PDU_t)); + + rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0); + DU_FREE(recvBuf, (Size)recvBufLen); + + if(rval.code == RC_FAIL || rval.code == RC_WMORE) + { + DU_LOG("\nERROR --> E2AP : ASN decode failed"); + return; + } + printf("\n"); + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + + switch(e2apMsg->present) + { + case E2AP_PDU_PR_unsuccessfulOutcome: + { + switch(e2apMsg->choice.unsuccessfulOutcome->value.present) + { + case UnsuccessfulOutcomeE2__value_PR_E2setupFailure: + { + procE2SetupFailure(e2apMsg); + break; + } + case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure: + { + procE2NodeConfigUpdateFailure(e2apMsg); + break; + } + case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure: + { + procRicServiceUpdateFailure(e2apMsg); + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome [%d]",\ + e2apMsg->choice.unsuccessfulOutcome->value.present); + return; + } + } + free(e2apMsg->choice.unsuccessfulOutcome); + break; + } + case E2AP_PDU_PR_successfulOutcome: + { + switch(e2apMsg->choice.successfulOutcome->value.present) + { + case SuccessfulOutcomeE2__value_PR_E2setupResponse: + { + if(!duCb.e2Status) + { + procE2SetupRsp(e2apMsg); + } + break; + } + case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge: + { + DU_LOG("\nDEBUG --> E2AP : E2 node Config update ack message recevied"); + break; + } + case SuccessfulOutcomeE2__value_PR_ResetResponseE2: + { + procResetResponse(e2apMsg); + break; + } + case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge: + { + procRicServiceUpdateAck(e2apMsg); + break; + } + case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm: + { + procRicSubscriptionModificationConfirm(e2apMsg); + break; + } + + default: + { + DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome [%d]",\ + e2apMsg->choice.successfulOutcome->value.present); + return; + } + }/* End of switch(successfulOutcome) */ + free(e2apMsg->choice.successfulOutcome); + break; + } + + case E2AP_PDU_PR_initiatingMessage: + { + switch(e2apMsg->choice.initiatingMessage->value.present) + { + case InitiatingMessageE2__value_PR_RICsubscriptionRequest: + { + procRicSubscriptionRequest(e2apMsg); + break; + } + case InitiatingMessageE2__value_PR_RICserviceQuery: + { + procRicServiceQuery(e2apMsg); + break; + } + case InitiatingMessageE2__value_PR_ErrorIndicationE2: + { + DU_LOG("\nINFO --> E2AP : Error indication received"); + break; + } + case InitiatingMessageE2__value_PR_ResetRequestE2: { DU_LOG("\nINFO --> E2AP : Error indication received"); + procE2ResetRequest(e2apMsg); break; } default: