X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fdu_app%2Fdu_e2ap_msg_hdl.c;h=6f366b6c915d646bc472336191ee62e8f3e86ee4;hb=345f36a57881a9b78819a8e0f37a45bc146c2e7a;hp=1c8843aa1781665a75948a4ebbee30115d7d1e14;hpb=76d2662c441ac10d75d004698ae6ca6a61814d72;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 1c8843aa1..6f366b6c9 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -51,6 +51,15 @@ #include "E2SM-KPM-ActionDefinition-Format1.h" #include "MeasurementInfoItem.h" #include "RANfunctionsIDcause-List.h" +#include "MeasurementRecord.h" +#include "MeasurementData.h" +#include "MeasurementRecordItem.h" +#include "MeasurementDataItem.h" +#include "E2SM-KPM-IndicationMessage-Format1.h" +#include "E2SM-KPM-IndicationMessage.h" +#include "E2SM-KPM-IndicationHeader.h" +#include "E2SM-KPM-IndicationHeader-Format1.h" +#include "LabelInfoItem.h" /******************************************************************* * @@ -108,6 +117,62 @@ void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause) } } +/******************************************************************* + * + * @brief Printing Type and Cause of failure + * + * @details + * + * Function : printE2ErrorCause + * + * Functionality: Printing Type and Cause of failure + * + * @params[in] E2 Cause + * @return void + * + ******************************************************************/ +void printE2ErrorCause(CauseE2_t *cause) +{ + switch(cause->present) + { + case CauseE2_PR_ricRequest: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Request", cause->choice.ricRequest); + break; + } + case CauseE2_PR_ricService: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Service", cause->choice.ricService); + break; + } + case CauseE2_PR_e2Node: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "E2_Node", cause->choice.e2Node); + break; + } + case CauseE2_PR_transport: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "Transport", cause->choice.transport); + break; + } + case CauseE2_PR_protocol: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "Protocol", cause->choice.protocol); + break; + } + case CauseE2_PR_misc: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "Miscellaneous", cause->choice.misc); + break; + } + default: + { + DU_LOG("Failure_Type and Cause unknown"); + break; + } + } +} + /******************************************************************* * * @brief Free the ErrorIndication Message @@ -2117,13 +2182,13 @@ void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg) * Functionality: Processes E2 Setup Response sent by RIC * * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure + * @return void * * ****************************************************************/ -uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) +void procE2SetupRsp(E2AP_PDU_t *e2apMsg) { + bool invalidTransId = false; uint8_t arrIdx =0, transId=0, idx=0; uint32_t recvBufLen; E2setupResponse_t *e2SetRspMsg=NULL; @@ -2151,7 +2216,7 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) else { DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - return RFAILED; + invalidTransId = true; } break; } @@ -2161,60 +2226,67 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) /* To store the Ric Id Params */ recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\ .choice.GlobalRIC_ID.pLMN_Identity.size); - memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\ - ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen); + memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\ + ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen); bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId); /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */ break; } case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: - { - e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; - for(idx =0; idx list.count; idx++) { - e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx]; - switch(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present) + e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; + for(idx =0; idx list.count; idx++) { - case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: - { - e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD, &node); - if(!e2NodeComponentInfo) - { - DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); - return RFAILED; - } - else + e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx]; + switch(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: { - cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node); - DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize); - DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize); - DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent)); - DU_FREE(node, sizeof(CmLList)); + e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD, &node); + if(!e2NodeComponentInfo) + { + DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); + } + else + { + cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node); + DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize); + DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize); + DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent)); + DU_FREE(node, sizeof(CmLList)); + } + break; } + default: break; - } - default: - break; + } } + break; } - break; - } default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in E2SetupRsp:%ld", - e2SetRspMsg->protocolIEs.list.array[arrIdx]->id); - break; + { + DU_LOG("\nERROR --> E2AP : Invalid IE received in E2SetupRsp:%ld", + e2SetRspMsg->protocolIEs.list.array[arrIdx]->id); + break; + } + } + + if(invalidTransId == true) + { + break; } } freeAperDecodingOfE2SetupRsp(e2SetRspMsg); - if(duSendE2NodeConfigurationUpdate() != ROK) + if(invalidTransId == false) { - DU_LOG("\nERROR --> E2AP : Failed to send E2 node config update"); - return RFAILED; + if(duSendE2NodeConfigurationUpdate() != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 node config update"); + } } - return ROK; } /******************************************************************* @@ -2551,13 +2623,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; } @@ -2729,13 +2795,13 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report) { - ricSubscriptionInfo->actionSequence[ricActionId-1].id = ricActionId; - ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT; + ricSubscriptionInfo->actionSequence[ricActionId].actionId = ricActionId; + ricSubscriptionInfo->actionSequence[ricActionId].type = REPORT; - if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \ + if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId].definition, \ actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK) { - ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD; + ricSubscriptionInfo->actionSequence[ricActionId].action = CONFIG_ADD; ricSubscriptionInfo->numOfActions++; break; } @@ -2743,7 +2809,8 @@ 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-1], 0, sizeof(ActionInfo)); + deleteActionSequence(&ricSubscriptionInfo->actionSequence[ricActionId]); + subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId; if(failureCause->causeType == E2_NOTHING) { @@ -2791,7 +2858,7 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu * ****************************************************************/ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) { - uint8_t idx = 0; + uint8_t idx = 0, actionIdx = 0; uint8_t ret = ROK; uint16_t ranFuncId = 0; RicRequestId ricReqId; @@ -2856,6 +2923,12 @@ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) } ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId; 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, @@ -2901,6 +2974,8 @@ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) if(ret == ROK) { + cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1); + /* Add RAN subcription detail to RAN function */ DU_ALLOC(ricSubscriptionNode, sizeof(CmLList)); if(ricSubscriptionNode) @@ -2913,13 +2988,8 @@ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) #ifdef KPI_CALCULATION /* Send statistics request to other DU entities */ - BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo); + BuildAndSendStatsReq(ricSubscriptionInfo); #endif - - /* TODO : Trigger RIC Indication once statistics indication is - * received from MAC . - * TBD in future gerrit */ - //BuildAndSendRicIndication(ricSubscriptionInfo); } else { @@ -3141,14 +3211,8 @@ void FreeRicIndication(E2AP_PDU_t *e2apMsg) switch(ricIndicationMsg->protocolIEs.list.array[idx]->id) { case ProtocolIE_IDE2_id_RICrequestID: - break; - case ProtocolIE_IDE2_id_RANfunctionID: - break; - case ProtocolIE_IDE2_id_RICactionID: - break; - case ProtocolIE_IDE2_id_RICindicationType: break; @@ -3181,1107 +3245,1028 @@ void FreeRicIndication(E2AP_PDU_t *e2apMsg) /******************************************************************* * - * brief Fill the RicIndication Message + * @brief Free measurement record * * @details * - * Function : FillRicIndication + * Function : freeMeasRecord * - * Functionality:Fills the RicIndication Message + * Functionality: Free all measurement recorded for a measurement + * within an action in a RIC subscription * - * @return ROK - success - * RFAILED - failure + * @param Measurement data to be freed + * @return void * ******************************************************************/ -uint8_t FillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo) +void freeMeasData(MeasurementData_t *measData) { - uint8_t elementCnt=0; - uint8_t idx=0; - uint8_t ret = ROK; - elementCnt = 6; + uint8_t measIdx = 0, measRecIdx = 0; + MeasurementRecord_t *measRecord = NULLP; - ricIndicationMsg->protocolIEs.list.count = elementCnt; - ricIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(RICindication_t); - /* Initialize the Ric Indication members */ - DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, \ - ricIndicationMsg->protocolIEs.list.size); - if(ricIndicationMsg->protocolIEs.list.array == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed"); - ret = RFAILED; - } - else + if(measData->list.array) { - for(idx=0; idxlist.count; measIdx++) { - DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx],\ - sizeof(RICindication_IEs_t)); - if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed"); - ret = RFAILED; - } - } - if(ret != RFAILED) - { - idx = 0; - - ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID; - ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ - RICindication_IEs__value_PR_RICrequestID; - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID =ricSubscriptionInfo->requestId.requestorId; - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = ricSubscriptionInfo->requestId.instanceId; - - idx++; - ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID; - ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ - RICindication_IEs__value_PR_RANfunctionID; - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = duCb.e2apDb.ranFunction[0].id; - - idx++; - ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID; - ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ - RICindication_IEs__value_PR_RICactionID; - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = ricSubscriptionInfo->actionSequence[0].id; - - idx++; - ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType; - ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ - RICindication_IEs__value_PR_RICindicationType; - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = ricSubscriptionInfo->actionSequence[0].type; - - idx++; - ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader; - ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ - RICindication_IEs__value_PR_RICindicationHeader; - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size = 3 * - sizeof(uint8_t); - DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf ,\ - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size); - if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed"); - ret = RFAILED; - } - else - { - buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \ - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf); - idx++; - /* TO BE CHANGED: RIC INDICATION DATA */ - /* For now filling a dummy octect data, need to tested with PRBs*/ - ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage; - ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricIndicationMsg->protocolIEs.list.array[idx]->value.present = \ - RICindication_IEs__value_PR_RICindicationMessage; - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size = 3 * - sizeof(uint8_t); - DU_ALLOC(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf ,\ - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size); - if(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for RICindicationIEs failed"); - ret = RFAILED; - } - else - { - buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \ - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf); - } - } + if(measData->list.array[measIdx]) + { + measRecord = &measData->list.array[measIdx]->measRecord; + if(measRecord->list.array) + { + for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++) + { + DU_FREE(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t)); + } + DU_FREE(measRecord->list.array, measRecord->list.size); + } + DU_FREE(measData->list.array[measIdx], sizeof(MeasurementDataItem_t)); + } } + DU_FREE(measData->list.array, measData->list.size); } - return ret; } /******************************************************************* * - * @brief Builds and Send the RicIndication Message + * @brief Fill measurement info list * * @details * - * Function : BuildAndSendRicIndication + * Function : freeMeasInfoList * - * Functionality:Fills the RicIndication Message + * Functionality: Fills all measurement info within an action + * in a RIC subscription * - * @return ROK - success - * RFAILED - failure + * @param Measurement Info list to be freed + * @return void * ******************************************************************/ - -uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo) +void freeMeasInfoList(MeasurementInfoList_t *measInfoList) { - E2AP_PDU_t *e2apMsg = NULLP; - RICindication_t *ricIndicationMsg=NULLP; - asn_enc_rval_t encRetVal; /* Encoder return value */ - uint8_t ret = RFAILED; - uint8_t FillRicIndicationret = ROK; + uint8_t measInfoIdx = 0; - while(true) + if(measInfoList->list.array) { - DU_LOG("\nINFO --> E2AP : Building RIC Indication Message\n"); - - DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); - if(e2apMsg == NULLP) + for(measInfoIdx = 0; measInfoIdx < measInfoList->list.count; measInfoIdx++) { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); - break; - } + if(measInfoList->list.array[measInfoIdx]) + { + DU_FREE(measInfoList->list.array[measInfoIdx]->measType.choice.measName.buf, \ + measInfoList->list.array[measInfoIdx]->measType.choice.measName.size); - 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 for E2AP-PDU failed"); - break; + DU_FREE(measInfoList->list.array[measInfoIdx], measInfoList->list.size); + } } - e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication; - e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; - e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication; + DU_FREE(measInfoList->list.array, measInfoList->list.size); + } +} - ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication; +/******************************************************************* + * + * @brief Free E2SM-KPM Indication Message + * + * @details + * + * Function : FreeE2smKpmIndicationMessage + * + * Functionality: Free E2SM-KPM Indication Message + * + * @param E2SM-KPM Indication message to be freed + * @return void + * + ******************************************************************/ +void FreeE2smKpmIndicationMessage(E2SM_KPM_IndicationMessage_t *e2smKpmIndMsg) +{ + E2SM_KPM_IndicationMessage_Format1_t *format1Msg = NULLP; - FillRicIndicationret = FillRicIndication(ricIndicationMsg, ricSubscriptionInfo); - if(FillRicIndicationret != ROK) - { - 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 Indication Message (at %s)\n",\ - encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); - break; - } - else - { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Indication Message \n"); -#ifdef DEBUG_ASN_PRINT - for(int i=0; i< encBufSize; i++) - { - printf("%x",encBuf[i]); - } -#endif - } + switch(e2smKpmIndMsg->indicationMessage_formats.present) + { + case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1: + { + if(e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1) + { + format1Msg = e2smKpmIndMsg->indicationMessage_formats.choice.indicationMessage_Format1; + + /* Measurement Data */ + freeMeasData(&format1Msg->measData); - if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) - { - DU_LOG("\nINFO --> E2AP : Sending RIC Indication Message"); + /* Measurement Info List */ + if(format1Msg->measInfoList) + { + freeMeasInfoList(format1Msg->measInfoList); + DU_FREE(format1Msg->measInfoList, sizeof(MeasurementInfoList_t)); + } - } - ret = ROK; - break; + /* Granularity Period */ + DU_FREE(format1Msg->granulPeriod, sizeof(GranularityPeriod_t)); + + DU_FREE(format1Msg, sizeof(E2SM_KPM_IndicationMessage_Format1_t)); + } + break; + } + + case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING: + case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2: + default: + break; } - FreeRicIndication(e2apMsg); - return ret; } /******************************************************************* * - * @brief free e2 node component configuration req and rsp + * @brief Fill measurement record * * @details * - * Function : freeE2NodeComponentConfiguration + * Function : fillMeasRecord * - * Functionality: - * - free e2 node component configuration req and rsp + * Functionality: Fills all measurement value for a measurement + * within an action in a RIC subscription * - * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration + * @param Measurement record to be filled + * Measurement database with measurement records * @return ROK - success * RFAILED - failure * - * ****************************************************************/ - -void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration) + ******************************************************************/ +uint8_t fillMeasRecord(MeasurementRecord_t *measRecord, MeasurementInfo *measInfoDb) { - /* Free E2 Node Component Request Part */ - DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size); + uint8_t measRecIdx = 0; + CmLList *measValNode = NULLP; + double measVal = 0; - /* Free E2 Node Component Response Part */ - DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size); - + measRecord->list.count = measInfoDb->measuredValue.count; + measRecord->list.size = measRecord->list.count * sizeof(MeasurementRecordItem_t *); + + DU_ALLOC(measRecord->list.array, measRecord->list.size); + if(!measRecord->list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } + + for(measRecIdx = 0; measRecIdx < measRecord->list.count; measRecIdx++) + { + DU_ALLOC(measRecord->list.array[measRecIdx], sizeof(MeasurementRecordItem_t)); + if(!measRecord->list.array[measRecIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } + } + + measRecIdx = 0; + CM_LLIST_FIRST_NODE(&measInfoDb->measuredValue, measValNode); + while(measValNode) + { + measVal = *(double *)measValNode->node; + if(measVal == (int)measVal) + { + measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_integer; + measRecord->list.array[measRecIdx]->choice.integer = (int)measVal; + } + else + { + measRecord->list.array[measRecIdx]->present = MeasurementRecordItem_PR_real; + measRecord->list.array[measRecIdx]->choice.real = measVal; + } + measRecIdx++; + measValNode= measValNode->next; + /* Once the measurement record is added to the message, delete it from DB */ + measVal = 0; + } + deleteMeasuredValueList(&measInfoDb->measuredValue); + return ROK; } /******************************************************************* * - * @brief free e2 node component component identifier + * @brief Fills measuerement data * * @details * - * Function : freeE2NodeComponentIdentifier + * Function : fillMeasData * - * Functionality: - * - free e2 node component component identifier + * Functionality: Fill all measurement recorded for all measurements + * in an action in a RIC subscription * - * @params[in] E2nodeComponentID_t *componentID + * @param Measurement data to be filled + * Measurement info list from an action DB * @return ROK - success * RFAILED - failure * - * ****************************************************************/ - -void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID) + ******************************************************************/ +uint8_t fillMeasData(MeasurementData_t *measData, CmLListCp *measInfoListDb) { - if(componentID->choice.e2nodeComponentInterfaceTypeF1) - { - DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size); - DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t)); - } - + uint8_t measIdx = 0; + CmLList *measInfoNode = NULLP; + MeasurementInfo *measInfoDb = NULLP; + MeasurementRecord_t *measRecord = NULLP; + + measData->list.count = measInfoListDb->count; + measData->list.size = measData->list.count * sizeof(MeasurementDataItem_t *); + + DU_ALLOC(measData->list.array, measData->list.size); + if(!measData->list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } + + measIdx = 0; + CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode); + while(measInfoNode) + { + measInfoDb = (MeasurementInfo *)measInfoNode->node; + if(measInfoDb) + { + DU_ALLOC(measData->list.array[measIdx], sizeof(MeasurementDataItem_t)); + if(!measData->list.array[measIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } + + measRecord = &measData->list.array[measIdx]->measRecord; + if(fillMeasRecord(measRecord, measInfoDb) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill measurement record"); + return RFAILED; + } + measIdx++; + } + measInfoNode = measInfoNode->next; + } + + return ROK; } /******************************************************************* * - * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg + * @brief Fill all measurement info * * @details * - * Function : FreeE2NodeConfigUpdate + * Function : fillMeasInfoList * - * Functionality: - * - freeing the memory allocated for E2nodeConfigurationUpdate + * Functionality: Fills all measurement info belonging to an action + * in a RIC subscription * - * @params[in] E2AP_PDU_t *e2apMsg + * @param Measurement Info list to be filled + * Measurement Info list from E2AP DB * @return ROK - success * RFAILED - failure * - * ****************************************************************/ - -void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg) + ******************************************************************/ +uint8_t fillMeasInfoList(MeasurementInfoList_t *measInfoList, CmLListCp *measInfoListDb) { - uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0; - E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL; - E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList =NULL; - E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL; - E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL; - E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL; - E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL; - E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL; + uint8_t measInfoIdx = 0; + CmLList *measInfoNode = NULLP; + MeasurementInfo *measInfoDb = NULLP; + MeasurementInfoItem_t *measInfoItem = NULLP; - if(e2apMsg != NULLP) + measInfoList->list.count = measInfoListDb->count; + measInfoList->list.size = measInfoList->list.count * sizeof(MeasurementInfoItem_t *); + + DU_ALLOC(measInfoList->list.array, measInfoList->list.size); + if(!measInfoList->list.array) { - if(e2apMsg->choice.initiatingMessage != NULLP) + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } + + measInfoIdx = 0; + CM_LLIST_FIRST_NODE(measInfoListDb, measInfoNode); + while(measInfoNode) + { + DU_ALLOC(measInfoList->list.array[measInfoIdx], sizeof(MeasurementInfoItem_t)); + if(!measInfoList->list.array[measInfoIdx]) { - e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate; - if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP) - { - for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++) - { - if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]) - { - - switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: - break; + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } - case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition: - { - e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List; - if(e2NodeAddList->list.array) - { - for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++) - { - e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx]; - - freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration); - freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID); - DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t)); - } - DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size); - } - break; - } - case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate: - { - e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List; - if(e2NodeUpdateList->list.array) - { - for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++) - { - e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx]; - - freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration); - freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID); - DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t)); - } - DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size); - } - break; - } - case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval: - { - e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List; - if(e2NodeRemovalList->list.array) - { - for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++) - { - e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx]; + measInfoItem = measInfoList->list.array[measInfoIdx]; + measInfoDb = (MeasurementInfo *)measInfoNode->node; + if(measInfoDb) + { + /* Measurement Type */ + measInfoItem->measType.present = MeasurementType_PR_measName; + measInfoItem->measType.choice.measName.size = strlen(measInfoDb->measurementTypeName); - freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID); - DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t)); - } - DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size); - } - break; - } - - default: - break; - } - DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t)); - } - } - DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size); + DU_ALLOC(measInfoItem->measType.choice.measName.buf, measInfoItem->measType.choice.measName.size); + if(!measInfoItem->measType.choice.measName.buf) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; } - DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + + memcpy(measInfoItem->measType.choice.measName.buf, measInfoDb->measurementTypeName,\ + measInfoItem->measType.choice.measName.size); + + measInfoIdx++; } - DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + measInfoNode = measInfoNode->next; + measInfoDb = NULLP; } + + return ROK; } -/******************************************************************* + /******************************************************************* * - * @brief Buld and send the E2 node config update msg + * @brief Fill E2SM-KPM Indication Message Format 1 * * @details * - * Function : BuildAndSendE2NodeConfigUpdate + * Function : fillE2smKpmIndMsgFormat1 * - * Functionality: - * - Buld and send the E2 node config update msg + * Functionality: Fill E2SM-KPM Indication Message Format 1 * - * @params[in] + * @param Format 1 Message to be filled + * Action Definition format 1 from E2AP DB * @return ROK - success * RFAILED - failure * - * ****************************************************************/ + ******************************************************************/ +uint8_t fillE2smKpmIndMsgFormat1(E2SM_KPM_IndicationMessage_Format1_t *format1Msg, ActionDefFormat1 *format1) +{ + /* Measurement Data */ + if(fillMeasData(&format1Msg->measData, &format1->measurementInfoList) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill measurement data"); + return RFAILED; + } + + /* Measurement Information */ + DU_ALLOC(format1Msg->measInfoList, sizeof(MeasurementInfoList_t)); + if(!format1Msg->measInfoList) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } + + if(fillMeasInfoList(format1Msg->measInfoList, &format1->measurementInfoList) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill measurement information list"); + return RFAILED; + } + + /* Granularity Period */ + DU_ALLOC(format1Msg->granulPeriod, sizeof(GranularityPeriod_t)); + if(!format1Msg->granulPeriod) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } + *(format1Msg->granulPeriod) = format1->granularityPeriod; + + return ROK; +} -uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList) +/******************************************************************* + * + * @brief Fill RIC Indication Message buffer + * + * @details + * + * Function : fillRicIndMsgBuf + * + * Functionality: Fill E2SM-KPM Indication Message + * Encode this message and copy to RIC Indication Message buffer + * + * @param RIC Indication Message buffer to be filled + * Source action info from E2AP DB + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t fillRicIndMsgBuf(RICindicationMessage_t *ricIndMsgBuf, ActionInfo *actionInfo) { uint8_t ret = RFAILED; - uint8_t arrIdx = 0,elementCnt = 0, transId=0; - E2AP_PDU_t *e2apMsg = NULLP; - asn_enc_rval_t encRetVal; /* Encoder return value */ - E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP; - - DU_LOG("\nINFO --> E2AP : Building E2 Node config update\n"); - do - { - DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); - if(e2apMsg == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); - 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 for E2AP-PDU failed"); - break; - } - e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; - e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate; - e2apMsg->choice.initiatingMessage->value.present = \ - InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate; - e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate; - - elementCnt =1; - if(e2NodeList->addE2NodeCount) - elementCnt++; - if(e2NodeList->updateE2NodeCount) - elementCnt++; - if(e2NodeList->removeE2NodeCount) - elementCnt++; - - e2NodeConfigUpdate->protocolIEs.list.count = elementCnt; - e2NodeConfigUpdate->protocolIEs.list.size = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*); - DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size); - if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for e2NodeConfigUpdate failed"); - break; - } - - for(arrIdx =0; arrIdxprotocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t)); - if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP) - { - - DU_LOG("\nERROR --> E2AP : Memory allocation for e2NodeConfigUpdate failed"); - break; - } - } - - if(arrIdxprotocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID; - transId = assignTransactionId(); - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId; + memset(&e2smKpmIndMsg, 0, sizeof(E2SM_KPM_IndicationMessage_t)); - if(e2NodeList->addE2NodeCount) - { - arrIdx++; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List; - if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\ - ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK) - { - DU_LOG("\nERROR --> E2AP : Failed to create E2 Node config list"); - break; - } - } - - if(e2NodeList->updateE2NodeCount) + while(true) + { + /* E2SM-KPM Indication message format type */ + e2smKpmIndMsg.indicationMessage_formats.present = actionInfo->definition.formatType; + switch(e2smKpmIndMsg.indicationMessage_formats.present) { - arrIdx++; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List; - if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\ - e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK) - { + case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format1: + { + /* E2SM-KPM Indication message format 1 */ + DU_ALLOC(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \ + sizeof(E2SM_KPM_IndicationMessage_Format1_t)); + if(!e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + failedInFormat = true; + break; + } - DU_LOG("\nERROR --> E2AP : Failed to update the E2 node configuration"); - break; - } - } - - if(e2NodeList->removeE2NodeCount) - { - arrIdx++; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List; - if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\ - e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK) - { + if(fillE2smKpmIndMsgFormat1(e2smKpmIndMsg.indicationMessage_formats.choice.indicationMessage_Format1, \ + &actionInfo->definition.choice.format1) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill E2SM-KPM Indication message format 1"); + failedInFormat = true; + break; + } + break; + } - DU_LOG("\nERROR --> E2AP : Failed to remove the E2 node configuration"); - break; - } + case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_NOTHING: + case E2SM_KPM_IndicationMessage__indicationMessage_formats_PR_indicationMessage_Format2: + default: + { + DU_LOG("\nERROR --> E2AP : fillRicIndMsgBuf: Only Format 1 supported"); + failedInFormat = true; + break; + } } - /* Prints the Msg formed */ - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + if(failedInFormat) + break; + /* Encode E2SM-KPM Indication Message */ + xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationMessage, &e2smKpmIndMsg); 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_E2SM_KPM_IndicationMessage, 0, &e2smKpmIndMsg, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode E2SM-KPM Indication Message (at %s)\n",\ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); break; } else { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SM-KPM Indication 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)) + + /* Copy encoded string to RIC Indication Message buffer */ + ricIndMsgBuf->size = encBufSize; + DU_ALLOC(ricIndMsgBuf->buf, ricIndMsgBuf->size); + if(!ricIndMsgBuf->buf) { - DU_LOG("\nERROR --> E2AP : Sending E2 node config update failed"); + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); break; } + memset(ricIndMsgBuf->buf, 0, ricIndMsgBuf->size); + memcpy(ricIndMsgBuf->buf, encBuf, encBufSize); - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; - memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList)); ret = ROK; break; - }while(true); - - FreeE2NodeConfigUpdate(e2apMsg); + } + + /* Free E2SM-KPM Indication Message */ + FreeE2smKpmIndicationMessage(&e2smKpmIndMsg); + return ret; } /******************************************************************* * - * @brief Deallocate the memory allocated for E2ResetRequest msg + * @brief Free E2SM-KPM Indication Header * * @details * - * Function : FreeE2ResetRequest - * - * Functionality: - * - freeing the memory allocated for E2ResetRequest + * Function : FreeE2smKpmIndicationHeader * - * @params[in] E2AP_PDU_t *e2apMsg - * @return ROK - success - * RFAILED - failure + * Functionality: Free E2SM-KPM Indication Header + * + * @param E2SM-KPM Indication Header to be free + * @return void * - * ****************************************************************/ -void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg) + ******************************************************************/ +void FreeE2smKpmIndicationHeader(E2SM_KPM_IndicationHeader_t *e2smKpmIndHdr) { - uint8_t ieIdx =0; - ResetRequestE2_t *resetReq = NULLP; + E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP; - if(e2apMsg != NULLP) + if(e2smKpmIndHdr) { - if(e2apMsg->choice.initiatingMessage != NULLP) + switch(e2smKpmIndHdr->indicationHeader_formats.present) { - resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; - if(resetReq->protocolIEs.list.array) - { - for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++) + case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1: { - DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t)); + if(e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1) + { + format1 = e2smKpmIndHdr->indicationHeader_formats.choice.indicationHeader_Format1; + + DU_FREE(format1->colletStartTime.buf, format1->colletStartTime.size); + DU_FREE(format1, sizeof(E2SM_KPM_IndicationHeader_Format1_t)); + } + break; } - DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size); - } - DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING: + default: + break; } - DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); } } /******************************************************************* * - * @brief Build and send the E2 reset request msg + * @brief Fill RIC Indication Header buffer * * @details * - * Function : BuildAndSendE2ResetRequest - * - * Functionality: - * - Buld and send the E2 reset request msg to RIC + * Function : fillRicIndHeader * - * @params[in] + * Functionality: Fill E2SM-KPM Indication Header + * Encode this message and copy to RIC Indication Header buffer + * + * @param RIC Indication Header buffer to be filled + * Source RIC subscription info from E2AP DB * @return ROK - success * RFAILED - failure * - * ****************************************************************/ -uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause) + ******************************************************************/ +uint8_t fillRicIndHeader(RICindicationHeader_t *ricIndHdr, RicSubscription *ricSubsInfo) { - uint8_t ieIdx = 0, elementCnt = 0, transId = 0; uint8_t ret = RFAILED; - E2AP_PDU_t *e2apMsg = NULLP; - ResetRequestE2_t *resetReq = NULLP; - asn_enc_rval_t encRetVal; /* Encoder return value */ - - DU_LOG("\nINFO --> E2AP : Building E2 Reset Request\n"); + uint8_t secBufIdx = 0, milliSecBufIdx = 0; + int8_t byteIdx = 0; + bool formatFailure = false; + RanFunction *ranFunc = NULLP; + ReportStartTime *startTime = NULLP; + E2SM_KPM_IndicationHeader_t e2smKpmIndHdr; + E2SM_KPM_IndicationHeader_Format1_t *format1 = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ - do + while(true) { - DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); - if(e2apMsg == NULLP) + ranFunc = fetchRanFuncFromRanFuncId(ricSubsInfo->ranFuncId); + if(ranFunc == NULLP) { - DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed"); + DU_LOG("\nERROR --> E2AP : RAN Function ID [%d] not found", ricSubsInfo->ranFuncId); break; } - e2apMsg->present = E2AP_PDU_PR_initiatingMessage; - DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); - if(e2apMsg->choice.initiatingMessage == NULLP) + memset(&e2smKpmIndHdr, 0, sizeof(E2SM_KPM_IndicationHeader_t)); + + e2smKpmIndHdr.indicationHeader_formats.present = ranFunc->ricIndicationHeaderFormat; + switch(e2smKpmIndHdr.indicationHeader_formats.present) { - DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage"); - break; - } + case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_indicationHeader_Format1: + { + DU_ALLOC(e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1, \ + sizeof(E2SM_KPM_IndicationHeader_Format1_t)); + if(!e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + formatFailure = true; + break; + } + format1 = e2smKpmIndHdr.indicationHeader_formats.choice.indicationHeader_Format1; - e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset; - e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; - e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2; - resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + /* Fetch reporting period start time from DB */ + switch(ricSubsInfo->eventTriggerDefinition.formatType) + { + case 1: + { + startTime = &ricSubsInfo->eventTriggerDefinition.choice.format1.startTime; + } + } - elementCnt = 2; - resetReq->protocolIEs.list.count = elementCnt; - resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *); + format1->colletStartTime.size = 8 * sizeof(uint8_t); + DU_ALLOC(format1->colletStartTime.buf, format1->colletStartTime.size); + if(!format1->colletStartTime.buf) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + formatFailure = true; + break; + } - DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size); - if(!resetReq->protocolIEs.list.array) - { - DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \ - Reset Request IE array"); - break; - } + /* As per O-RAN.WG3.E2SM-KPM-R003-v03.00, section 8.3.12 and + * RFC 5905, section 6 : + * Time stamp has a 64-bit format where first 32-bit is seconds + * and next 32-bit is fraction in picosecond-level. + * This fraction has been rounded in microseconds. + * + * Hence, + * Storing 32-bit seconds at MSB 0-3 and + * 32-bit milliseconds at next 4 bytes i.e. bytes 4-7 + */ + secBufIdx = 0; + milliSecBufIdx = 4; + for(byteIdx = 3; byteIdx >= 0; byteIdx--) + { + format1->colletStartTime.buf[secBufIdx++] = startTime->timeInSec >> (8*byteIdx); + format1->colletStartTime.buf[milliSecBufIdx++] = startTime->timeInMilliSec >> (8*byteIdx); + } + break; + } - for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) - { - DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t)); - if(!resetReq->protocolIEs.list.array[ieIdx]) + case E2SM_KPM_IndicationHeader__indicationHeader_formats_PR_NOTHING: + default: { - DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \ - Reset Request IE array element"); - break; + DU_LOG("\nERROR --> E2AP : Only E2SM-KPM Indication Header Format 1 supported"); + formatFailure = true; + break; } } - /* In case of failure */ - if(ieIdx < elementCnt) + if(formatFailure) break; - ieIdx = 0; - resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; - resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; - resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID; - transId = assignTransactionId(); - resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; - - ieIdx++; - resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2; - resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore; - resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2; - fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause); - - /* Prints the Msg formed */ - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); - + /* Encode E2SM-KPM Indication Header */ + xer_fprint(stdout, &asn_DEF_E2SM_KPM_IndicationHeader, &e2smKpmIndHdr); 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_E2SM_KPM_IndicationHeader, 0, &e2smKpmIndHdr, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode E2SetupRequest structure (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode E2SM-KPM Indication Header (at %s)\n",\ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); break; } else { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SetupRequest\n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SM-KPM Indication Header \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) + + /* Copy encoded string to RIC Indication Header buffer */ + ricIndHdr->size = encBufSize; + DU_ALLOC(ricIndHdr->buf, ricIndHdr->size); + if(!ricIndHdr->buf) { - DU_LOG("\nERROR --> E2AP : Sending E2 Setup request failed"); + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); break; } - - /* In case the message is sent successfully, store the transaction info to - * be used when response is received */ - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; - + memset(ricIndHdr->buf, 0, ricIndHdr->size); + memcpy(ricIndHdr->buf, encBuf, encBufSize); ret = ROK; break; - }while(true); + } + + /* Free E2SM-KPM Indication Header */ + FreeE2smKpmIndicationHeader(&e2smKpmIndHdr); - /* Free all memory */ - FreeE2ResetRequest(e2apMsg); return ret; } /******************************************************************* * - * @brief Deallocate the memory allocated for Reset Response msg + * brief Fill the RIC Indication Message * * @details * - * Function : freeAperDecodingOfE2ResetRsp + * Function : fillRicIndication * - * Functionality: - * - freeing the memory allocated for Reset response + * Functionality: Fills the RIC Indication Message * - * @params[in] ResetResponseE2_t *resetResponse - * @return void + * @param RIC Indication Message to be filled + * RIC Subscription DB + * Action DB + * @return ROK - success + * RFAILED - failure * - * ****************************************************************/ -void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse) + ******************************************************************/ +uint8_t fillRicIndication(RICindication_t *ricIndicationMsg, RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo) { - uint8_t ieIdx; + uint8_t elementCnt = 0, idx = 0; + uint8_t ret = ROK; - if(resetResponse) + elementCnt = 6; + + ricIndicationMsg->protocolIEs.list.count = elementCnt; + ricIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(RICindication_IEs_t *); + + /* Initialize the Ric Indication members */ + DU_ALLOC(ricIndicationMsg->protocolIEs.list.array, ricIndicationMsg->protocolIEs.list.size); + if(ricIndicationMsg->protocolIEs.list.array == NULLP) { - if(resetResponse->protocolIEs.list.array) - { - for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) - { - if(resetResponse->protocolIEs.list.array[ieIdx]) - { - switch(resetResponse->protocolIEs.list.array[ieIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: - break; + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; + } - case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: - break; - } - free(resetResponse->protocolIEs.list.array[ieIdx]); - } - } - free(resetResponse->protocolIEs.list.array); + for(idx=0; idxprotocolIEs.list.array[idx], sizeof(RICindication_IEs_t)); + if(ricIndicationMsg->protocolIEs.list.array[idx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation in [%s] at line [%d]", __func__, __LINE__); + return RFAILED; } } -} - -/****************************************************************** - * - * @brief Processes E2 Reset Response sent by RIC - * - * @details - * - * Function : procResetResponse - * - * Functionality: Processes E2 Reset Response sent by RIC - * - * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure - * - * ****************************************************************/ -uint8_t procResetResponse(E2AP_PDU_t *e2apMsg) -{ - uint8_t ieIdx =0, transId; - ResetResponseE2_t *resetResponse; - DU_LOG("\nINFO --> E2AP : E2 Reset Response received"); - resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;; + /* RIC Request ID */ + idx = 0; + ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID; + ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICrequestID; + ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID = \ + ricSubscriptionInfo->requestId.requestorId; + ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID = \ + ricSubscriptionInfo->requestId.instanceId; - for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + /* RAN Function ID */ + idx++; + ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID; + ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RANfunctionID; + ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RANfunctionID = ricSubscriptionInfo->ranFuncId; + + /* RIC Action ID */ + idx++; + ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactionID; + ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICactionID; + ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICactionID = actionInfo->actionId; + + /* RIC Indication Type */ + idx++; + ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationType; + ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationType; + ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationType = actionInfo->type; + + /* RIC Indication Header */ + idx++; + ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationHeader; + ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationHeader; + if(fillRicIndHeader(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader, \ + ricSubscriptionInfo) != ROK) { - switch(resetResponse->protocolIEs.list.array[ieIdx]->id) - { - case ProtocolIE_IDE2_id_TransactionID: - transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; - if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \ - (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode)) - { - memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); - } - else - { - DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - return RFAILED; - } - break; - case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: - /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2 - Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. - Reset Request in this case, have not been comprehended or were missing, or if the message - contained logical errors. + DU_LOG("\nERROR --> E2AP : Failed to fill RIC Indication header"); + return RFAILED; + } - Processing of this ID should be implemented when negative call flows are to be supported. - */ - break; - default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in E2 Reset Response : %ld", - resetResponse->protocolIEs.list.array[ieIdx]->id); - break; - } + /* RIC Indication Message */ + idx++; + ricIndicationMsg->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICindicationMessage; + ricIndicationMsg->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; + ricIndicationMsg->protocolIEs.list.array[idx]->value.present = RICindication_IEs__value_PR_RICindicationMessage; + if(fillRicIndMsgBuf(&ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage, \ + actionInfo) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill RIC Indication Message"); + return RFAILED; } - freeAperDecodingOfE2ResetRsp(resetResponse); - return ROK; + return ret; } -/****************************************************************** +/******************************************************************* * - * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure + * @brief Builds and Send the RicIndication Message * * @details * - * Function : freeAperDecodingOfE2SetupFailure + * Function : BuildAndSendRicIndication * - * Functionality: Deallocation of memory allocated by aper decoder for e2 - * setup Failure + * Functionality:Fills the RicIndication Message * - * @params[in] E2setupFailure_t *e2SetupFailure; - * @return void + * @return ROK - success + * RFAILED - failure * - * ****************************************************************/ -void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure) + ******************************************************************/ + +uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo, ActionInfo *actionInfo) { - uint8_t arrIdx; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICindication_t *ricIndicationMsg = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ - if(e2SetupFailure) + while(true) { - if(e2SetupFailure->protocolIEs.list.array) + DU_LOG("\nINFO --> E2AP : Building RIC Indication Message\n"); + + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - if(e2SetupFailure->protocolIEs.list.array[arrIdx]) - { - free(e2SetupFailure->protocolIEs.list.array[arrIdx]); - } - } - free(e2SetupFailure->protocolIEs.list.array); + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); + break; } - } -} -/****************************************************************** - * - * @brief Processes E2 Setup Failure sent by RIC - * - * @details - * - * Function : procE2SetupFailure - * - * Functionality: Processes E2 Setup failure sent by RIC - * - * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure - * - * ****************************************************************/ -void procE2SetupFailure(E2AP_PDU_t *e2apMsg) -{ - uint8_t arrIdx =0, transId =0, timerValue=0; - E2setupFailure_t *e2SetupFailure; - DU_LOG("\nINFO --> E2AP : E2 Setup failure received"); - e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure; + 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 for E2AP-PDU failed"); + break; + } + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICindication; + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICindication; - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id) + ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication; + + if(fillRicIndication(ricIndicationMsg, ricSubscriptionInfo, actionInfo) != ROK) { - case ProtocolIE_IDE2_id_TransactionID: + DU_LOG("\nERROR --> E2AP : Failed to fill RIC Indication message"); + 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 Indication Message (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Indication Message \n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) { - transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->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); - return ; - } - break; - } - case ProtocolIE_IDE2_id_TimeToWaitE2: - { - timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2); - if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE) - { - duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue); - } - else - { - DU_LOG("\nERROR --> E2AP : EVENT_E2_SETUP_TMR timer is already running"); - return; - } - break; - } + printf("%x",encBuf[i]); + } +#endif } - } - freeAperDecodingOfE2SetupFailure(e2SetupFailure); + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nINFO --> E2AP : Sending RIC Indication Message"); + + } + ret = ROK; + break; + } + FreeRicIndication(e2apMsg); + return ret; } -/****************************************************************** + +/******************************************************************* * - * @brief Deallocation of memory allocated by aper decoder for RIC service Query + * @brief free e2 node component configuration req and rsp * * @details * - * Function : freeAperDecodingOfRicServiceQuery + * Function : freeE2NodeComponentConfiguration * - * Functionality: Deallocation of memory allocated by aper decoder for RIC - * service Query + * Functionality: + * - free e2 node component configuration req and rsp * - * @params[in] RICserviceQuery_t *ricServiceQuery; - * @return void + * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration + * @return ROK - success + * RFAILED - failure * * ****************************************************************/ -void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery) +void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration) { - uint8_t arrIdx,ranFuncIdx; - RANfunctionsID_List_t *ranFuncAddedList; + /* Free E2 Node Component Request Part */ + DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size); - if(ricServiceQuery) - { - if(ricServiceQuery->protocolIEs.list.array) - { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - if(ricServiceQuery->protocolIEs.list.array[arrIdx]) - { - switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id) - { - case ProtocolIE_IDE2_id_RANfunctionsAccepted: - { - ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; - if(ranFuncAddedList->list.array) - { - for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) - { - free(ranFuncAddedList->list.array[ranFuncIdx]); - } - free(ranFuncAddedList->list.array);; - } - break; - } - default: - break; - } - free(ricServiceQuery->protocolIEs.list.array[arrIdx]); - } - } - free(ricServiceQuery->protocolIEs.list.array); - } - } + /* Free E2 Node Component Response Part */ + DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size); + } + /******************************************************************* * - * @brief Build RanFunction Delete List + * @brief free e2 node component component identifier * * @details * - * Function : BuildRanFunctionDeleteList - * - * Functionality: Build RanFunction Delete List + * Function : freeE2NodeComponentIdentifier * - * @params[in] - * RANfunctionsID List - * Count of the RAN function - * Received RAN function list + * Functionality: + * - free e2 node component component identifier * + * @params[in] E2nodeComponentID_t *componentID * @return ROK - success * RFAILED - failure * - ******************************************************************/ + * ****************************************************************/ -uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc) +void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID) { - uint8_t ranFuncIdx=0; - RANfunctionID_ItemIEs_t *delRanFuncItem; - - if(count) + if(componentID->choice.e2nodeComponentInterfaceTypeF1) { - deleteList->list.count = count; - deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*); - DU_ALLOC(deleteList->list.array, deleteList->list.size); - if(deleteList->list.array == NULLP) - { - DU_LOG("\nERROR --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__); - return RFAILED; - } - for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++) - { - DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t)); - if(deleteList->list.array[ranFuncIdx] == NULLP) - { - DU_LOG("\nERROR --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__); - return RFAILED; - } - delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx]; - delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item; - delRanFuncItem->criticality = CriticalityE2_ignore; - delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id; - delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter; - - } + DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size); + DU_FREE(componentID->choice.e2nodeComponentInterfaceTypeF1, sizeof(E2nodeComponentInterfaceF1_t)); } - return ROK; + } + /******************************************************************* * - * @brief De Allocate Ric Service Update message + * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg * * @details * - * Function : FreeRicServiceUpdate + * Function : FreeE2NodeConfigUpdate * - * Functionality: De-Allocating Ric Service Update message + * Functionality: + * - freeing the memory allocated for E2nodeConfigurationUpdate * - * @params[in] E2AP_PDU_t *e2apMsg - - * @return void + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure * * ****************************************************************/ -void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg) +void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx = 0; - uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0; - RICserviceUpdate_t *ricServiceUpdate; - RANfunctions_List_t *ranFunctionsList; - RANfunction_ItemIEs_t *ranFuncItemIe; - RANfunction_Item_t *ranFunItem; - RANfunctionsID_List_t *deleteList; + uint8_t arrIdx =0, e2NodeUpdateListIdx=0, e2NodeRemovalListIdx=0, e2NodeAddListIdx=0; + E2nodeConfigurationUpdate_t *e2NodeConfigUpdate =NULL; + E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList =NULL; + E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItem =NULL; + E2nodeComponentConfigRemoval_List_t *e2NodeRemovalList =NULL; + E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItem =NULL; + E2nodeComponentConfigAddition_List_t *e2NodeAddList =NULL; + E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItem =NULL; - /* De-allocating Memory */ if(e2apMsg != NULLP) { if(e2apMsg->choice.initiatingMessage != NULLP) { - ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate; - if(ricServiceUpdate->protocolIEs.list.array != NULLP) + e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate; + if(e2NodeConfigUpdate->protocolIEs.list.array != NULLP) { - for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++) + for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++) { - if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP) + if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]) { - switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id) + + switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id) { case ProtocolIE_IDE2_id_TransactionID: break; - case ProtocolIE_IDE2_id_RANfunctionsAdded: - case ProtocolIE_IDE2_id_RANfunctionsModified: - { - ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List); - if(ranFunctionsList->list.array) - { - for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++) - { - if(ranFunctionsList->list.array[ranFuncAddListIdx]) - { - ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx]; - ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item; - DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size); - DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size); - DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t)); - } - } - DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size); + case ProtocolIE_IDE2_id_E2nodeComponentConfigAddition: + { + e2NodeAddList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List; + if(e2NodeAddList->list.array) + { + for(e2NodeAddListIdx = 0; e2NodeAddListIdx< e2NodeAddList->list.count; e2NodeAddListIdx++) + { + e2NodeAddItem = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[e2NodeAddListIdx]; + + freeE2NodeComponentConfiguration(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentConfiguration); + freeE2NodeComponentIdentifier(&e2NodeAddItem->value.choice.E2nodeComponentConfigAddition_Item.e2nodeComponentID); + DU_FREE(e2NodeAddItem, sizeof(E2nodeComponentConfigAddition_ItemIEs_t)); + } + DU_FREE(e2NodeAddList->list.array, e2NodeAddList->list.size); + } + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate: + { + e2NodeUpdateList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List; + if(e2NodeUpdateList->list.array) + { + for(e2NodeUpdateListIdx = 0; e2NodeUpdateListIdx< e2NodeUpdateList->list.count; e2NodeUpdateListIdx++) + { + e2NodeUpdateItem = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[e2NodeUpdateListIdx]; + + freeE2NodeComponentConfiguration(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentConfiguration); + freeE2NodeComponentIdentifier(&e2NodeUpdateItem->value.choice.E2nodeComponentConfigUpdate_Item.e2nodeComponentID); + DU_FREE(e2NodeUpdateItem, sizeof(E2nodeComponentConfigUpdate_ItemIEs_t)); + } + DU_FREE(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size); } break; } - case ProtocolIE_IDE2_id_RANfunctionsDeleted: + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval: { - deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; - if(deleteList->list.array) + e2NodeRemovalList = &e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List; + if(e2NodeRemovalList->list.array) { - for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++) + for(e2NodeRemovalListIdx = 0; e2NodeRemovalListIdx< e2NodeRemovalList->list.count; e2NodeRemovalListIdx++) { - DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t)); + e2NodeRemovalItem = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemovalList->list.array[e2NodeRemovalListIdx]; + + freeE2NodeComponentIdentifier(&e2NodeRemovalItem->value.choice.E2nodeComponentConfigRemoval_Item.e2nodeComponentID); + DU_FREE(e2NodeRemovalItem, sizeof(E2nodeComponentConfigRemoval_ItemIEs_t)); } - DU_FREE(deleteList->list.array, deleteList->list.size); - + DU_FREE(e2NodeRemovalList->list.array, e2NodeRemovalList->list.size); } break; } + default: - DU_LOG("\nERROR --> E2AP: Invalid event at ricServiceUpdate %ld ",\ - (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)); break; } - DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t)); + DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t)); } } - DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size); + DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size); } DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); } @@ -4291,29 +4276,30 @@ void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg) /******************************************************************* * - * @brief Builds and Send the RicServiceUpdateuest + * @brief Buld and send the E2 node config update msg * * @details * - * Function : BuildAndSendRicServiceUpdate + * Function : BuildAndSendE2NodeConfigUpdate * - * Functionality:Fills the RicServiceUpdateuest + * Functionality: + * - Buld and send the E2 node config update msg * + * @params[in] * @return ROK - success * RFAILED - failure * - ******************************************************************/ + * ****************************************************************/ -uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate) +uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList) { - uint8_t arrIdx = 0, elementCnt=0; - uint8_t transId = 0, ret = RFAILED; - bool memAllocFailed =false; - E2AP_PDU_t *e2apMsg = NULLP; - RICserviceUpdate_t *ricServiceUpdate = NULLP; + uint8_t ret = RFAILED; + uint8_t arrIdx = 0,elementCnt = 0, transId=0; + E2AP_PDU_t *e2apMsg = NULLP; asn_enc_rval_t encRetVal; /* Encoder return value */ + E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = NULLP; - DU_LOG("\nINFO --> E2AP : Building Ric Service Update\n"); + DU_LOG("\nINFO --> E2AP : Building E2 Node config update\n"); do { DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); @@ -4322,6 +4308,7 @@ uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate) DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); break; } + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); if(e2apMsg->choice.initiatingMessage == NULLP) @@ -4330,95 +4317,93 @@ uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate) break; } e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; - e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate; - e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate; - ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate; + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate; + e2apMsg->choice.initiatingMessage->value.present = \ + InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate; + e2NodeConfigUpdate = &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate; - /* For TransId IE, set elementCnt to 1. - If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/ - elementCnt =1; - if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded) - elementCnt++; - if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified) + if(e2NodeList->addE2NodeCount) elementCnt++; - if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted) + if(e2NodeList->updateE2NodeCount) + elementCnt++; + if(e2NodeList->removeE2NodeCount) elementCnt++; - - ricServiceUpdate->protocolIEs.list.count = elementCnt; - ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*); - /* Initialize the E2Setup members */ - DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size); - if(ricServiceUpdate->protocolIEs.list.array == NULLP) + e2NodeConfigUpdate->protocolIEs.list.count = elementCnt; + e2NodeConfigUpdate->protocolIEs.list.size = elementCnt * sizeof(E2nodeConfigurationUpdate_IEs_t*); + DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, e2NodeConfigUpdate->protocolIEs.list.size); + if(e2NodeConfigUpdate->protocolIEs.list.array == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed for array elements"); + DU_LOG("\nERROR --> E2AP : Memory allocation for e2NodeConfigUpdate failed"); break; } - for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++) + for(arrIdx =0; arrIdxprotocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t)); - if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP) + DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t)); + if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx] == NULLP) { - memAllocFailed = true; - DU_LOG("\nERROR --> E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx); + + DU_LOG("\nERROR --> E2AP : Memory allocation for e2NodeConfigUpdate failed"); break; } } - if(memAllocFailed == true) + + if(arrIdxprotocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_TransactionID; + transId = assignTransactionId(); + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId; - /* TransactionID */ - ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID; - if(serviceUpdate.dir == E2_NODE_INITIATED) - transId = assignTransactionId(); - else - transId = serviceUpdate.transId; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId; - - if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded) + if(e2NodeList->addE2NodeCount) { arrIdx++; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List; - if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\ - e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK) + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigAddition_List; + if(BuildE2NodeConfigAddList(&(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List),\ + ProcedureCodeE2_id_E2nodeConfigurationUpdate, e2NodeList->addE2NodeCount, e2NodeList->addE2Node)!=ROK) { + DU_LOG("\nERROR --> E2AP : Failed to create E2 Node config list"); break; } } - - if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified) + + if(e2NodeList->updateE2NodeCount) { arrIdx++; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List; - if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List, - e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK) + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigUpdate_List; + if(BuildE2NodeConfigUpdateList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdate_List,\ + e2NodeList->updateE2NodeCount, e2NodeList->updateE2Node) != ROK) { + + DU_LOG("\nERROR --> E2AP : Failed to update the E2 node configuration"); break; } } - - if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted) + + if(e2NodeList->removeE2NodeCount) { arrIdx++; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List; - if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\ - serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK) + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdate_IEs__value_PR_E2nodeComponentConfigRemoval_List; + if(BuildE2NodeConfigRemoveList(&e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemoval_List,\ + e2NodeList->removeE2NodeCount, e2NodeList->removeE2Node) != ROK) { + + DU_LOG("\nERROR --> E2AP : Failed to remove the E2 node configuration"); break; } } + /* Prints the Msg formed */ xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); @@ -4427,13 +4412,13 @@ uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate) encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode RicServiceUpdateuest structure (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); break; } else { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RicServiceUpdateuest\n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2nodeConfigurationUpdate\n"); #ifdef DEBUG_ASN_PRINT for(int i=0; i< encBufSize; i++) { @@ -4441,445 +4426,2327 @@ uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate) } #endif } - if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize)) { - DU_LOG("\nERROR --> E2AP : Sending E2 Setup request failed"); + DU_LOG("\nERROR --> E2AP : Sending E2 node config update failed"); break; } + + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; + memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.configList, e2NodeList, sizeof(E2NodeConfigList)); ret = ROK; break; }while(true); - if(ret == ROK) - { - if(serviceUpdate.dir == E2_NODE_INITIATED) - { - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; - duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; - } - else - { - duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId; - duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; - } - duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir; - duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId; - memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList)); - } - FreeRicServiceUpdate(e2apMsg); + FreeE2NodeConfigUpdate(e2apMsg); return ret; } -/****************************************************************** + +/******************************************************************* * - * @brief Processes RIC service Query sent by RIC + * @brief Deallocate the memory allocated for E2ResetRequest msg * * @details * - * Function : procRicServiceQuery + * Function : FreeE2ResetRequest * - * Functionality: Processes RIC service Query sent by RIC + * Functionality: + * - freeing the memory allocated for E2ResetRequest * - * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @params[in] E2AP_PDU_t *e2apMsg * @return ROK - success * RFAILED - failure * * ****************************************************************/ - -void procRicServiceQuery(E2AP_PDU_t *e2apMsg) +void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg) { - ConfigType action; - uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0; - uint16_t id,revisionCcounter; - bool tmpArray[MAX_RAN_FUNCTION] = {false}; - RICserviceQuery_t *ricServiceQuery=NULL; - RicServiceUpdate ricUpdate; - RANfunctionID_ItemIEs_t *ranFuncAddedItemIe; - RANfunctionsID_List_t *ranFuncAddedList; - - DU_LOG("\nINFO --> E2AP : RIC Service Query received"); - memset(&ricUpdate, 0, sizeof(RicServiceUpdate)); - ricUpdate.dir = RIC_INITIATED; - ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery; + uint8_t ieIdx =0; + ResetRequestE2_t *resetReq = NULLP; - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + if(e2apMsg != NULLP) { - switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id) + if(e2apMsg->choice.initiatingMessage != NULLP) { - /* TODO completing in next patch/gerrit */ - case ProtocolIE_IDE2_id_TransactionID: - { - ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; - break; - } - - case ProtocolIE_IDE2_id_RANfunctionsAccepted: + resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + if(resetReq->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < resetReq->protocolIEs.list.count; ieIdx++) + { + DU_FREE(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t)); + } + DU_FREE(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Build and send the E2 reset request msg + * + * @details + * + * Function : BuildAndSendE2ResetRequest + * + * Functionality: + * - Buld and send the E2 reset request msg to RIC + * + * @params[in] + * Reset cause + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause) +{ + uint8_t ieIdx = 0, elementCnt = 0, transId = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + ResetRequestE2_t *resetReq = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building E2 Reset Request\n"); + + do + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation for E2AP-PDU failed"); + break; + } + + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation for initiatingMessage"); + break; + } + + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_Reset; + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ResetRequestE2; + resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + + elementCnt = 2; + resetReq->protocolIEs.list.count = elementCnt; + resetReq->protocolIEs.list.size = elementCnt * sizeof(ResetRequestIEs_t *); + + DU_ALLOC(resetReq->protocolIEs.list.array, resetReq->protocolIEs.list.size); + if(!resetReq->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \ + Reset Request IE array"); + break; + } + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(resetReq->protocolIEs.list.array[ieIdx], sizeof(ResetRequestIEs_t)); + if(!resetReq->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest(): Memory allocation failed for \ + Reset Request IE array element"); + break; + } + } + + /* In case of failure */ + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_TransactionID; + transId = assignTransactionId(); + resetReq->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + ieIdx++; + resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2; + resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore; + resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2; + fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause); + + /* 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 reset request structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for reset 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 E2 Setup request failed"); + break; + } + + /* In case the message is sent successfully, store the transaction info to + * be used when response is received */ + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; + + ret = ROK; + break; + }while(true); + + /* Free all memory */ + FreeE2ResetRequest(e2apMsg); + return ret; +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for Reset Response msg + * + * @details + * + * Function : freeAperDecodingOfE2ResetRsp + * + * Functionality: + * - freeing the memory allocated for Reset response + * + * @params[in] ResetResponseE2_t *resetResponse + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse) +{ + uint8_t ieIdx; + + if(resetResponse) + { + if(resetResponse->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + { + if(resetResponse->protocolIEs.list.array[ieIdx]) + { + switch(resetResponse->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + break; + + case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: + break; + } + free(resetResponse->protocolIEs.list.array[ieIdx]); + } + } + free(resetResponse->protocolIEs.list.array); + } + } +} + +/****************************************************************** + * + * @brief Processes E2 Reset Response sent by RIC + * + * @details + * + * Function : procResetResponse + * + * Functionality: Processes E2 Reset Response sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return void + * + * ****************************************************************/ +void procResetResponse(E2AP_PDU_t *e2apMsg) +{ + bool invalidTransId=false; + uint8_t ieIdx =0, transId =0; + uint16_t ranFuncIdx=0; + ResetResponseE2_t *resetResponse =NULLP; + + DU_LOG("\nINFO --> E2AP : E2 Reset Response received"); + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;; + + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + { + switch(resetResponse->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; + if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \ + (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode)) + { + memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); + } + else + { + DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); + invalidTransId = true; + } + break; + } + case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: + { + for(ranFuncIdx=0; ranFuncIdx0) + { + deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList)); + memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo)); + } + } + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid IE received in E2 Reset Response : %ld", + resetResponse->protocolIEs.list.array[ieIdx]->id); + break; + } + } + + if(invalidTransId == true) + { + break; + } + } + + freeAperDecodingOfE2ResetRsp(resetResponse); +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure + * + * @details + * + * Function : freeAperDecodingOfE2SetupFailure + * + * Functionality: Deallocation of memory allocated by aper decoder for e2 + * setup Failure + * + * @params[in] E2setupFailure_t *e2SetupFailure; + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfE2SetupFailure(E2setupFailure_t *e2SetupFailure) +{ + uint8_t arrIdx; + + if(e2SetupFailure) + { + if(e2SetupFailure->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(e2SetupFailure->protocolIEs.list.array[arrIdx]) + { + free(e2SetupFailure->protocolIEs.list.array[arrIdx]); + } + } + free(e2SetupFailure->protocolIEs.list.array); + } + } +} +/****************************************************************** + * + * @brief Processes E2 Setup Failure sent by RIC + * + * @details + * + * Function : procE2SetupFailure + * + * Functionality: Processes E2 Setup failure sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void procE2SetupFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx =0, transId =0, timerValue=0; + E2setupFailure_t *e2SetupFailure; + + DU_LOG("\nINFO --> E2AP : E2 Setup failure received"); + e2SetupFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2setupFailure; + + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(e2SetupFailure->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = e2SetupFailure->protocolIEs.list.array[arrIdx]->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); + return ; + } + break; + } + case ProtocolIE_IDE2_id_TimeToWaitE2: + { + timerValue = convertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2); + if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR)) == FALSE) + { + duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), EVENT_E2_SETUP_TMR, timerValue); + } + else + { + DU_LOG("\nERROR --> E2AP : EVENT_E2_SETUP_TMR timer is already running"); + return; + } + break; + } + } + } + + freeAperDecodingOfE2SetupFailure(e2SetupFailure); +} +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for RIC service Query + * + * @details + * + * Function : freeAperDecodingOfRicServiceQuery + * + * Functionality: Deallocation of memory allocated by aper decoder for RIC + * service Query + * + * @params[in] RICserviceQuery_t *ricServiceQuery; + * @return void + * + * ****************************************************************/ + +void freeAperDecodingOfRicServiceQuery(RICserviceQuery_t *ricServiceQuery) +{ + uint8_t arrIdx,ranFuncIdx; + RANfunctionsID_List_t *ranFuncAddedList; + + if(ricServiceQuery) + { + if(ricServiceQuery->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(ricServiceQuery->protocolIEs.list.array[arrIdx]) + { + switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_RANfunctionsAccepted: + { + ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; + if(ranFuncAddedList->list.array) + { + for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) + { + free(ranFuncAddedList->list.array[ranFuncIdx]); + } + free(ranFuncAddedList->list.array);; + } + break; + } + default: + break; + } + free(ricServiceQuery->protocolIEs.list.array[arrIdx]); + } + } + free(ricServiceQuery->protocolIEs.list.array); + } + } +} +/******************************************************************* + * + * @brief Build RanFunction Delete List + * + * @details + * + * Function : BuildRanFunctionDeleteList + * + * Functionality: Build RanFunction Delete List + * + * @params[in] + * RANfunctionsID List + * Count of the RAN function + * Received RAN function list + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t BuildRanFunctionDeleteList(RANfunctionsID_List_t *deleteList, uint8_t count, RanFuncInfo *recvdRanFunc) +{ + uint8_t ranFuncIdx=0; + RANfunctionID_ItemIEs_t *delRanFuncItem; + + if(count) + { + deleteList->list.count = count; + deleteList->list.size = deleteList->list.count * sizeof(RANfunctionID_ItemIEs_t*); + DU_ALLOC(deleteList->list.array, deleteList->list.size); + if(deleteList->list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__); + return RFAILED; + } + for(ranFuncIdx = 0; ranFuncIdx< deleteList->list.count; ranFuncIdx++) + { + DU_ALLOC(deleteList->list.array[ranFuncIdx], sizeof(RANfunctionID_ItemIEs_t)); + if(deleteList->list.array[ranFuncIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed in %s at %d",__func__, __LINE__); + return RFAILED; + } + delRanFuncItem= (RANfunctionID_ItemIEs_t *) deleteList->list.array[ranFuncIdx]; + delRanFuncItem->id = ProtocolIE_IDE2_id_RANfunctionID_Item; + delRanFuncItem->criticality = CriticalityE2_ignore; + delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionID = recvdRanFunc[ranFuncIdx].id; + delRanFuncItem->value.choice.RANfunctionID_Item.ranFunctionRevision = recvdRanFunc[ranFuncIdx].revisionCounter; + + } + } + return ROK; +} +/******************************************************************* + * + * @brief De Allocate Ric Service Update message + * + * @details + * + * Function : FreeRicServiceUpdate + * + * Functionality: De-Allocating Ric Service Update message + * + * @params[in] E2AP_PDU_t *e2apMsg + + * @return void + * + * ****************************************************************/ + +void FreeRicServiceUpdate(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx = 0; + uint8_t ranFuncAddListIdx=0, ranFuncDelIdx=0; + RICserviceUpdate_t *ricServiceUpdate; + RANfunctions_List_t *ranFunctionsList; + RANfunction_ItemIEs_t *ranFuncItemIe; + RANfunction_Item_t *ranFunItem; + RANfunctionsID_List_t *deleteList; + + /* De-allocating Memory */ + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.initiatingMessage != NULLP) + { + ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate; + if(ricServiceUpdate->protocolIEs.list.array != NULLP) + { + for(arrIdx = 0; arrIdx < ricServiceUpdate->protocolIEs.list.count; arrIdx++) + { + if(ricServiceUpdate->protocolIEs.list.array[arrIdx] != NULLP) + { + switch(ricServiceUpdate->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + break; + + case ProtocolIE_IDE2_id_RANfunctionsAdded: + case ProtocolIE_IDE2_id_RANfunctionsModified: + { + ranFunctionsList = &(ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List); + if(ranFunctionsList->list.array) + { + for(ranFuncAddListIdx= 0; ranFuncAddListIdx< ranFunctionsList->list.count; ranFuncAddListIdx++) + { + if(ranFunctionsList->list.array[ranFuncAddListIdx]) + { + ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncAddListIdx]; + ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item; + DU_FREE(ranFunItem->ranFunctionOID.buf, ranFunItem->ranFunctionOID.size); + DU_FREE(ranFunItem->ranFunctionDefinition.buf, ranFunItem->ranFunctionDefinition.size); + DU_FREE(ranFunctionsList->list.array[ranFuncAddListIdx], sizeof(RANfunction_ItemIEs_t)); + } + } + DU_FREE(ranFunctionsList->list.array, ranFunctionsList->list.size); + } + break; + } + case ProtocolIE_IDE2_id_RANfunctionsDeleted: + { + deleteList= &ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; + if(deleteList->list.array) + { + for(ranFuncDelIdx = 0; ranFuncDelIdx< deleteList->list.count; ranFuncDelIdx++) + { + DU_FREE(deleteList->list.array[ranFuncDelIdx], sizeof(RANfunctionID_ItemIEs_t)); + } + DU_FREE(deleteList->list.array, deleteList->list.size); + + } + break; + } + default: + DU_LOG("\nERROR --> E2AP: Invalid event at ricServiceUpdate %ld ",\ + (ricServiceUpdate->protocolIEs.list.array[arrIdx]->id)); + break; + } + DU_FREE(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t)); + } + } + DU_FREE(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Builds and Send the RicServiceUpdateuest + * + * @details + * + * Function : BuildAndSendRicServiceUpdate + * + * Functionality:Fills the RicServiceUpdateuest + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate) +{ + uint8_t arrIdx = 0, elementCnt=0; + uint8_t transId = 0, ret = RFAILED; + bool memAllocFailed =false; + E2AP_PDU_t *e2apMsg = NULLP; + RICserviceUpdate_t *ricServiceUpdate = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building Ric Service Update\n"); + do + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); + 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 for E2AP-PDU failed"); + break; + } + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICserviceUpdate; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICserviceUpdate; + ricServiceUpdate = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceUpdate; + + /* For TransId IE, set elementCnt to 1. + If there is any item in the RAN function add list, RAN function modification list, or RAN function delete list, increment the elementCnt.*/ + + elementCnt =1; + if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded) + elementCnt++; + if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified) + elementCnt++; + if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted) + elementCnt++; + + ricServiceUpdate->protocolIEs.list.count = elementCnt; + ricServiceUpdate->protocolIEs.list.size = elementCnt * sizeof(RICserviceUpdate_IEs_t*); + + /* Initialize the E2Setup members */ + DU_ALLOC(ricServiceUpdate->protocolIEs.list.array, ricServiceUpdate->protocolIEs.list.size); + if(ricServiceUpdate->protocolIEs.list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for array elements"); + break; + } + + for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++) + { + DU_ALLOC(ricServiceUpdate->protocolIEs.list.array[arrIdx], sizeof(RICserviceUpdate_IEs_t)); + if(ricServiceUpdate->protocolIEs.list.array[arrIdx] == NULLP) + { + memAllocFailed = true; + DU_LOG("\nERROR --> E2AP : Memory allocation failed for arrayIdx [%d]", arrIdx); + break; + } + } + if(memAllocFailed == true) + break; + + arrIdx = 0; + + /* TransactionID */ + ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_TransactionID; + if(serviceUpdate.dir == E2_NODE_INITIATED) + transId = assignTransactionId(); + else + transId = serviceUpdate.transId; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId; + + if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded) + { + arrIdx++; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsAdded; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List; + if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List,\ + e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded, serviceUpdate.recvRanFuncList.ranFunToBeAdded) !=ROK) + { + break; + } + } + + if(serviceUpdate.recvRanFuncList.numOfRanFunToBeModified) + { + arrIdx++; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsModified; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctions_List; + if(BuildRanFunctionAddList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctions_List, + e2apMsg->choice.initiatingMessage->procedureCode, serviceUpdate.recvRanFuncList.numOfRanFunToBeModified, serviceUpdate.recvRanFuncList.ranFunToBeModified) !=ROK) + { + break; + } + } + + if(serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted) + { + arrIdx++; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionsDeleted; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.present = RICserviceUpdate_IEs__value_PR_RANfunctionsID_List; + if(BuildRanFunctionDeleteList(&ricServiceUpdate->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List,\ + serviceUpdate.recvRanFuncList.numOfRanFunToBeDeleted, serviceUpdate.recvRanFuncList.ranFunToBeDeleted) != ROK) + { + 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 RicServiceUpdateuest structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RicServiceUpdateuest\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 E2 Setup request failed"); + break; + } + ret = ROK; + break; + }while(true); + + if(ret == ROK) + { + if(serviceUpdate.dir == E2_NODE_INITIATED) + { + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId = transId; + duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; + } + else + { + duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId = transId; + duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode = e2apMsg->choice.initiatingMessage->procedureCode; + } + duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.dir = serviceUpdate.dir; + duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.transId =transId; + memcpy(&duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.ricService.recvRanFuncList, &serviceUpdate.recvRanFuncList, sizeof(E2TmpRanFunList)); + } + FreeRicServiceUpdate(e2apMsg); + return ret; +} +/****************************************************************** + * + * @brief Processes RIC service Query sent by RIC + * + * @details + * + * Function : procRicServiceQuery + * + * Functionality: Processes RIC service Query sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void procRicServiceQuery(E2AP_PDU_t *e2apMsg) +{ + ConfigType action; + uint16_t arrIdx =0, ranFuncIdx=0,tmpIdx=0; + uint16_t id,revisionCcounter; + bool tmpArray[MAX_RAN_FUNCTION] = {false}; + RICserviceQuery_t *ricServiceQuery=NULL; + RicServiceUpdate ricUpdate; + RANfunctionID_ItemIEs_t *ranFuncAddedItemIe; + RANfunctionsID_List_t *ranFuncAddedList; + + DU_LOG("\nINFO --> E2AP : RIC Service Query received"); + memset(&ricUpdate, 0, sizeof(RicServiceUpdate)); + ricUpdate.dir = RIC_INITIATED; + ricServiceQuery = &e2apMsg->choice.initiatingMessage->value.choice.RICserviceQuery; + + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(ricServiceQuery->protocolIEs.list.array[arrIdx]->id) + { + /* TODO completing in next patch/gerrit */ + case ProtocolIE_IDE2_id_TransactionID: + { + ricUpdate.transId = ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; + break; + } + + case ProtocolIE_IDE2_id_RANfunctionsAccepted: { ranFuncAddedList= &ricServiceQuery->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; if(ranFuncAddedList->list.array) { - for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) + for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) + { + if(ranFuncAddedList->list.array[ranFuncIdx]) + { + /* Using the RAN function Id, identify the RAN function to be modified or deleted. */ + + ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx]; + id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID; + revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision; + + if((id != duCb.e2apDb.ranFunction[id-1].id)) + { + action = CONFIG_DEL; + } + else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter)) + { + action = CONFIG_MOD; + } + + if(action == CONFIG_DEL) + { + ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id; + ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter; + ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++; + } + else if(action == CONFIG_MOD) + { + ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id; + ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter; + ricUpdate.recvRanFuncList.numOfRanFunToBeModified++; + } + + /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. + * Else we will add the IDs into the added list */ + tmpArray[id-1] = true; + } + } + } + break; + } + } + } + + /* Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */ + for(arrIdx =0; arrIdx0)&&(!tmpArray[arrIdx])) + { + ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id; + ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter; + ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++; + } + } + + if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send ric service update message"); + } + + freeAperDecodingOfRicServiceQuery(ricServiceQuery); +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for + * RIC service update ack + * + * @details + * + * Function : freeAperDecodingOfRicServiceUpdateAck + * + * Functionality: Deallocation of memory allocated by aper decoder + * for RIC service update ack + * + * @params[in] RICserviceUpdateAck_t *ricServiceAck; + * @return void + * + * ****************************************************************/ + +void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck) +{ + uint8_t arrIdx=0,ranFuncIdx=0; + RANfunctionsID_List_t *ranFuncAddedList=NULL; + + if(ricServiceAck) + { + if(ricServiceAck->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(ricServiceAck->protocolIEs.list.array[arrIdx]) + { + switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_RANfunctionsAccepted: + { + ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; + if(ranFuncAddedList->list.array) + { + for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) + { + free(ranFuncAddedList->list.array[ranFuncIdx]); + } + free(ranFuncAddedList->list.array); + } + break; + } + default: + break; + } + free(ricServiceAck->protocolIEs.list.array[arrIdx]); + } + } + free(ricServiceAck->protocolIEs.list.array); + } + } +} + +/****************************************************************** + * + * @brief Processes RIC service update ack sent by RIC + * + * @details + * + * Function : procRicServiceUpdateAck + * + * Functionality: Processes RIC service update ack sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx =0, transId =0; + uint16_t id =0, tmpIdx=0, ranFuncIdx=0; + RicServiceUpdate serviceUpdate; + RANfunctionsIDcause_List_t *rejectedList=NULL; + RICserviceUpdateAcknowledge_t *ricServiceAck=NULL; + RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL; + + DU_LOG("\nINFO --> E2AP : RIC service update ack received"); + memset(&serviceUpdate, 0, sizeof(RicServiceUpdate)); + ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge; + + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = ricServiceAck->protocolIEs.list.array[arrIdx]->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 if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\ + (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode)) + { + memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo)); + } + else + { + DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); + return ; + } + break; + } + + case ProtocolIE_IDE2_id_RANfunctionsAccepted: + break; + + case ProtocolIE_IDE2_id_RANfunctionsRejected: + { + rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List; + if(rejectedList->list.array) + { + for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) + { + ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx]; + id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID; + tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded; + serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id; + serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter; + serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++; + } + } + break; + } + + } + } + + if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded) + { + serviceUpdate.dir = E2_NODE_INITIATED; + BuildAndSendRicServiceUpdate(serviceUpdate); + } + freeAperDecodingOfRicServiceUpdateAck(ricServiceAck); +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for + * RIC service update failure + * + * @details + * + * Function : freeAperDecodingOfRicServiceUpdateFailure + * + * Functionality: Deallocation of memory allocated by aper decoder + * for RIC service update failure + * + * @params[in] RICserviceUpdateFailure_t *ricServiceFailure; + * @return void + * + * ****************************************************************/ + +void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure) +{ + uint8_t arrIdx=0; + + if(ricServiceFailure) + { + if(ricServiceFailure->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(ricServiceFailure->protocolIEs.list.array[arrIdx]) + { + free(ricServiceFailure->protocolIEs.list.array[arrIdx]); + } + } + free(ricServiceFailure->protocolIEs.list.array); + } + } +} + +/****************************************************************** + * + * @brief Processes RIC service update failure sent by RIC + * + * @details + * + * Function : procRicServiceUpdateFailure + * + * Functionality: Processes RIC service update failure sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx =0, timerValue=0; + RICserviceUpdateFailure_t *ricServiceFailure=NULL; + + DU_LOG("\nINFO --> E2AP : RIC service update failure received"); + ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure; + + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + break; + } + case ProtocolIE_IDE2_id_TimeToWaitE2: + { + timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2); + if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE) + { + duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue); + } + else + { + DU_LOG("\nERROR --> E2AP : EVENT_RIC_SERVICE_UPDATE_TMR timer is already running"); + return; + } + break; + } + case ProtocolIE_IDE2_id_CauseE2: + { + break; + } + } + } + + freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure); +} + +/****************************************************************** + * + * @brief DU Send E2 Node Configuration Update + * + * @details + * + * Function : duSendE2NodeConfigurationUpdate + * + * Functionality: DU Send E2 Node Configuration Update + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +uint8_t duSendE2NodeConfigurationUpdate() +{ + E2NodeConfigList e2NodeList; + CmLList *node =NULL; + E2NodeComponent *e2NodeComponentInfo=NULL; + + memset(&e2NodeList, 0, sizeof(E2NodeConfigList)); + CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); + while(node) + { + e2NodeComponentInfo = (E2NodeComponent*)node->node; + + if(e2NodeComponentInfo->componentRequestPart && e2NodeComponentInfo->componentResponsePart) + { + switch(e2NodeComponentInfo->componentActionType) + { + case E2_NODE_COMPONENT_ADD: + { + e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.addE2Node[e2NodeList.addE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; + e2NodeList.removeE2NodeCount++; + break; + } + case E2_NODE_COMPONENT_UPDATE: + { + e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; + e2NodeList.updateE2NodeCount++; + break; + + } + case E2_NODE_COMPONENT_DEL: + { + e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; + e2NodeList.removeE2NodeCount++; + break; + } + } + } + node = node->next; + } + + if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send e2 node config update message to RIC_stub"); + return RFAILED; + } + return ROK; +} + +/******************************************************************* + * + * @brief Free RIC Subscription Modification Required + * + * @details + * + * Function : FreeRicSubsModRequired + * + * Functionality: Freqq RIC Subscription Modification required + * + * @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]) { - if(ranFuncAddedList->list.array[ranFuncIdx]) + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + switch(ricSubsModReqdIe->id) { - /* Using the RAN function Id, identify the RAN function to be modified or deleted. */ - - ranFuncAddedItemIe = (RANfunctionID_ItemIEs_t*)ranFuncAddedList->list.array[ranFuncIdx]; - id = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionID; - revisionCcounter = ranFuncAddedItemIe->value.choice.RANfunctionID_Item.ranFunctionRevision; - - if((id != duCb.e2apDb.ranFunction[id-1].id)) - { - action = CONFIG_DEL; - } - else if((id == duCb.e2apDb.ranFunction[id-1].id)&&(revisionCcounter!=duCb.e2apDb.ranFunction[id-1].revisionCounter)) - { - action = CONFIG_MOD; - } + 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 + * + ******************************************************************/ +uint8_t FillActionReqdToBeModList(RICactions_RequiredToBeModified_List_t *actionToBeModList, uint8_t numActionsMod, \ + RicSubscription *ricSubscription) +{ + uint8_t arrIdx = 0, actionIdx = 0; + RICaction_RequiredToBeModified_ItemIEs_t *actionToBeMod = NULL; + + 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; + } + + 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]; + + 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 : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; + } + + arrIdx = 0; + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + { + 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++; + } + } + + 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_RequiredToBeRemoved_List_t *actionToBeRmvList = NULLP; + +/* Unused in case of E2SM-KPM */ +#if 0 + RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP; +#endif + + /* Count number of Actions to be modified or deleted */ + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + { + if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD) + numActionsMod++; + else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL) + numActionsRmv++; + } + + /* Count number of IEs to be added to messages */ + elementCnt = 2; + if(numActionsMod) + elementCnt++; + if(numActionsRmv) + elementCnt++; + + 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; + } + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) + { + 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; + } + } + + /* 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) + { + 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 + + /* 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; + + 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; - if(action == CONFIG_DEL) - { - ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].id = id; - ricUpdate.recvRanFuncList.ranFunToBeDeleted[ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted].revisionCounter = revisionCcounter; - ricUpdate.recvRanFuncList.numOfRanFunToBeDeleted++; - } - else if(action == CONFIG_MOD) - { - ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].id = id; - ricUpdate.recvRanFuncList.ranFunToBeModified[ricUpdate.recvRanFuncList.numOfRanFunToBeModified].revisionCounter = revisionCcounter; - ricUpdate.recvRanFuncList.numOfRanFunToBeModified++; - } + ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired; - /* If any ID is set to true, it means that the ID has been used in either modification or deletion list. - * Else we will add the IDs into the added list */ - tmpArray[id-1] = true; - } - } - } - break; - } + 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); - /* Traversing the whole RAN function list in ducb to check if any new Ran function ids have been added. */ - for(arrIdx =0; arrIdx0)&&(!tmpArray[arrIdx])) + 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) { - ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[arrIdx].id; - ricUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[arrIdx].revisionCounter; - ricUpdate.recvRanFuncList.numOfRanFunToBeAdded++; + 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"); } - } - if(BuildAndSendRicServiceUpdate(ricUpdate)!= ROK) - { - DU_LOG("\nERROR --> E2AP : Failed to build and send ric service update message"); + ret = ROK; + break; } - freeAperDecodingOfRicServiceQuery(ricServiceQuery); + /* Free RIC Subscription modification required */ + FreeRicSubsModRequired(e2apMsg); + return ret; } -/****************************************************************** +/******************************************************************* * - * @brief Deallocation of memory allocated by aper decoder for - * RIC service update ack + * @brief Free APER decoding of RIC Subscription Modification Confirm * * @details * - * Function : freeAperDecodingOfRicServiceUpdateAck + * Function : freeAperDecodingOfRicSubsModConfirm * - * Functionality: Deallocation of memory allocated by aper decoder - * for RIC service update ack + * Functionality: Free APER decoding of RIC Subscription + * Modification Confirm * - * @params[in] RICserviceUpdateAck_t *ricServiceAck; + * @param E2AP Message PDU * @return void * - * ****************************************************************/ - -void freeAperDecodingOfRicServiceUpdateAck(RICserviceUpdateAcknowledge_t *ricServiceAck) + ******************************************************************/ +void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx=0,ranFuncIdx=0; - RANfunctionsID_List_t *ranFuncAddedList=NULL; - - if(ricServiceAck) + 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) { - if(ricServiceAck->protocolIEs.list.array) + ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm; + if(ricSubsModCfm->protocolIEs.list.array) { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++) { - if(ricServiceAck->protocolIEs.list.array[arrIdx]) + if(ricSubsModCfm->protocolIEs.list.array[ieIdx]) { - switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id) + ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx]; + switch(ricSubsModCfmIe->id) { - case ProtocolIE_IDE2_id_RANfunctionsAccepted: - { - ranFuncAddedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsID_List; - if(ranFuncAddedList->list.array) + case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List: { - for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) + modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List; + if(modCfmList->list.array) { - free(ranFuncAddedList->list.array[ranFuncIdx]); + for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++) + { + if(modCfmList->list.array[arrIdx]) + free(modCfmList->list.array[arrIdx]); + } + free(modCfmList->list.array); } - free(ranFuncAddedList->list.array); + break; } - 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(ricServiceAck->protocolIEs.list.array[arrIdx]); + free(ricSubsModCfmIe); } } - free(ricServiceAck->protocolIEs.list.array); + free(ricSubsModCfm->protocolIEs.list.array); } } } -/****************************************************************** +/******************************************************************* * - * @brief Processes RIC service update ack sent by RIC + * @brief Process RIC Subscription Modification Confirm Message * * @details * - * Function : procRicServiceUpdateAck + * Function : procRicSubscriptionModificationConfirm * - * Functionality: Processes RIC service update ack sent by RIC + * Functionality: Process RIC Subscription Modification Confirm + * Message received from RIC. * - * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure + * @param E2AP Message PDU + * @return void * - * ****************************************************************/ - -void procRicServiceUpdateAck(E2AP_PDU_t *e2apMsg) + ******************************************************************/ +void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx =0, transId =0; - uint16_t id =0, tmpIdx=0, ranFuncIdx=0; - RicServiceUpdate serviceUpdate; - RANfunctionsIDcause_List_t *rejectedList=NULL; - RICserviceUpdateAcknowledge_t *ricServiceAck=NULL; - RANfunctionIDcause_ItemIEs_t *ranFuncRejectedItemIe=NULL; - - DU_LOG("\nINFO --> E2AP : RIC service update ack received"); - memset(&serviceUpdate, 0, sizeof(RicServiceUpdate)); - ricServiceAck = &e2apMsg->choice.successfulOutcome->value.choice.RICserviceUpdateAcknowledge; - - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - switch(ricServiceAck->protocolIEs.list.array[arrIdx]->id) + 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; + +/* Not used in case of E2SM-KPM */ +#if 0 + RICactions_ConfirmedForModification_List_t *modCfmList = NULLP; + RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP; + + RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP; + RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP; +#endif + + 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) { - case ProtocolIE_IDE2_id_TransactionID: + 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]) { - transId = ricServiceAck->protocolIEs.list.array[arrIdx]->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 if((duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].transactionId == transId) &&\ - (duCb.e2apDb.e2TransInfo.ricInitTransaction[transId].procedureCode == e2apMsg->choice.unsuccessfulOutcome->procedureCode)) - { - memset(&duCb.e2apDb.e2TransInfo.ricInitTransaction[transId], 0, sizeof(E2TransInfo)); - } - else - { - DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - return ; - } + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); break; } - - case ProtocolIE_IDE2_id_RANfunctionsAccepted: + + 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; +} - case ProtocolIE_IDE2_id_RANfunctionsRejected: +/****************************************************************** +* @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) { - rejectedList= &ricServiceAck->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionsIDcause_List; - if(rejectedList->list.array) + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) { - for(ranFuncIdx=0;ranFuncIdxlist.count; ranFuncIdx++) + if(resetResponse->protocolIEs.list.array[ieIdx]) { - ranFuncRejectedItemIe = (RANfunctionIDcause_ItemIEs_t*)rejectedList->list.array[ranFuncIdx]; - id = ranFuncRejectedItemIe->value.choice.RANfunctionIDcause_Item.ranFunctionID; - tmpIdx= serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded; - serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].id = duCb.e2apDb.ranFunction[id-1].id; - serviceUpdate.recvRanFuncList.ranFunToBeAdded[tmpIdx].revisionCounter = duCb.e2apDb.ranFunction[id-1].revisionCounter; - serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded++; + DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); } } - break; + 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)); } +} - if(serviceUpdate.recvRanFuncList.numOfRanFunToBeAdded) +/******************************************************************* + * + * @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 { - serviceUpdate.dir = E2_NODE_INITIATED; - BuildAndSendRicServiceUpdate(serviceUpdate); - } - freeAperDecodingOfRicServiceUpdateAck(ricServiceAck); + 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 - * RIC service update failure + * @brief Deallocation of memory allocated by aper decoder for reset req * * @details * - * Function : freeAperDecodingOfRicServiceUpdateFailure + * Function : freeAperDecodingOfE2ResetReq * - * Functionality: Deallocation of memory allocated by aper decoder - * for RIC service update failure + * Functionality: Deallocation of memory allocated by aper decoder for + * reset req * - * @params[in] RICserviceUpdateFailure_t *ricServiceFailure; + * @params[in] Pointer to resetReq * @return void * * ****************************************************************/ - -void freeAperDecodingOfRicServiceUpdateFailure(RICserviceUpdateFailure_t *ricServiceFailure) +void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq) { uint8_t arrIdx=0; - if(ricServiceFailure) + if(resetReq) { - if(ricServiceFailure->protocolIEs.list.array) + if(resetReq->protocolIEs.list.array) { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) { - if(ricServiceFailure->protocolIEs.list.array[arrIdx]) + if(resetReq->protocolIEs.list.array[arrIdx]) { - free(ricServiceFailure->protocolIEs.list.array[arrIdx]); + free(resetReq->protocolIEs.list.array[arrIdx]); } } - free(ricServiceFailure->protocolIEs.list.array); + free(resetReq->protocolIEs.list.array); } } } -/****************************************************************** +/******************************************************************* * - * @brief Processes RIC service update failure sent by RIC + * @brief Process reset req received from RIC * * @details * - * Function : procRicServiceUpdateFailure + * Function : procE2ResetRequest * - * Functionality: Processes RIC service update failure sent by RIC + * Functionality: Process reset req received from RIC * - * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure + * @param E2AP_PDU_t *e2apMsg + * @return void * - * ****************************************************************/ + ******************************************************************/ -void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg) +void procE2ResetRequest(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx =0, timerValue=0; - RICserviceUpdateFailure_t *ricServiceFailure=NULL; + uint16_t ranFuncIdx=0; + uint8_t arrIdx =0, transId =0; + ResetRequestE2_t *resetReq; - DU_LOG("\nINFO --> E2AP : RIC service update failure received"); - ricServiceFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICserviceUpdateFailure; + DU_LOG("\nINFO --> E2AP : E2 Reset request received"); + resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) { - switch(ricServiceFailure->protocolIEs.list.array[arrIdx]->id) + 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_TimeToWaitE2: + + case ProtocolIE_IDE2_id_CauseE2: { - timerValue = convertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2); - if((duChkTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR)) == FALSE) - { - duStartTmr((PTR)&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer), EVENT_RIC_SERVICE_UPDATE_TMR, timerValue); - } - else + for(ranFuncIdx=0; ranFuncIdx E2AP : EVENT_RIC_SERVICE_UPDATE_TMR timer is already running"); - return; + if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0) + { + deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList)); + memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo)); + } } - break; - } - case ProtocolIE_IDE2_id_CauseE2: - { break; } } } - - freeAperDecodingOfRicServiceUpdateFailure(ricServiceFailure); + if(BuildAndSendResetResponse(transId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send reset response"); + } + freeAperDecodingOfE2ResetReq(resetReq); } -/****************************************************************** +/******************************************************************* * - * @brief DU Send E2 Node Configuration Update + * @brief Free APER decoding of RIC Subscription Modification Refuse * * @details * - * Function : duSendE2NodeConfigurationUpdate + * Function : freeAperDecodingOfRicSubsModRefuse * - * Functionality: DU Send E2 Node Configuration Update + * Functionality: Free APER decoding of RIC Subscription + * Modification Refuse * - * @return ROK - success - * RFAILED - failure + * @param E2AP Message PDU + * @return void * - * ****************************************************************/ - -uint8_t duSendE2NodeConfigurationUpdate() + ******************************************************************/ +void freeAperDecodingOfRicSubsModRefuse(E2AP_PDU_t *e2apMsg) { - E2NodeConfigList e2NodeList; - CmLList *node =NULL; - E2NodeComponent *e2NodeComponentInfo=NULL; + uint8_t ieIdx =0; + RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP; - memset(&e2NodeList, 0, sizeof(E2NodeConfigList)); - CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); - while(node) + if(e2apMsg && e2apMsg->choice.unsuccessfulOutcome) { - e2NodeComponentInfo = (E2NodeComponent*)node->node; + ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse; + if(ricSubsModRefuse->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++) + { + if(ricSubsModRefuse->protocolIEs.list.array[ieIdx]) + free(ricSubsModRefuse->protocolIEs.list.array[ieIdx]); + } + free(ricSubsModRefuse->protocolIEs.list.array); + } + } +} - if(e2NodeComponentInfo->componentRequestPart && e2NodeComponentInfo->componentResponsePart) +/******************************************************************* + * + * @brief Process RIC Subscription Modification Refuse Message + * + * @details + * + * Function : procRicSubscriptionModificationRefuse + * + * Functionality: Process RIC Subscription Modification Refuse + * Message received from RIC. + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0; + uint16_t ranFuncId = 0; + RicRequestId ricReqId; + RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP; + RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP; + CauseE2_t *cause = NULLP; + + DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Modification Refuse", __func__); + + do{ + if(!e2apMsg) { - switch(e2NodeComponentInfo->componentActionType) + DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + break; + } + + if(!e2apMsg->choice.unsuccessfulOutcome) + { + DU_LOG("\nERROR --> E2AP : %s: Unsuccessful Outcome in E2AP message is NULL", __func__); + break; + } + + ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse; + if(!ricSubsModRefuse->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); + break; + } + + for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++) + { + if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx]) { - case E2_NODE_COMPONENT_ADD: + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + break; + } + + ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx]; + switch(ricSubsModRefuseIe->id) + { + case ProtocolIE_IDE2_id_RICrequestID: { - e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType; - e2NodeList.addE2Node[e2NodeList.addE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; - e2NodeList.removeE2NodeCount++; + memset(&ricReqId, 0, sizeof(RicRequestId)); + ricReqId.requestorId = ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID; break; } - case E2_NODE_COMPONENT_UPDATE: + + case ProtocolIE_IDE2_id_RANfunctionID: { - e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType; - e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; - e2NodeList.updateE2NodeCount++; + ranFuncId = ricSubsModRefuseIe->value.choice.RANfunctionID; break; - } - case E2_NODE_COMPONENT_DEL: + + case ProtocolIE_IDE2_id_CauseE2: { - e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType; - e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; - e2NodeList.removeE2NodeCount++; - break; + DU_LOG("\nDEBUG --> E2AP : %s: RIC subscriptiom modification refused for RIC_Requestor_ID [%d] \ + RIC_Instance_ID [%d] RAN_Function_ID [%d] ", __func__, ricReqId.requestorId, \ + ricReqId.instanceId, ranFuncId); + + cause = &ricSubsModRefuseIe->value.choice.CauseE2; + printE2ErrorCause(cause); } - } - } - node = node->next; - } - if(BuildAndSendE2NodeConfigUpdate(&e2NodeList) !=ROK) - { - DU_LOG("\nERROR --> E2AP : Failed to build and send e2 node config update message to RIC_stub"); - return RFAILED; - } - return ROK; + default: + break; + } /* End of switch for Protocol IE Id */ + } /* End of for loop for Protocol IE list */ + + break; + }while(true); + + freeAperDecodingOfRicSubsModRefuse(e2apMsg); + return; } + /******************************************************************* * * @brief Handles received E2AP message and sends back response @@ -4969,6 +6836,11 @@ void E2APMsgHdlr(Buffer *mBuf) procRicServiceUpdateFailure(e2apMsg); break; } + case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse: + { + procRicSubscriptionModificationRefuse(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome [%d]",\ @@ -4976,6 +6848,7 @@ void E2APMsgHdlr(Buffer *mBuf) return; } } + free(e2apMsg->choice.unsuccessfulOutcome); break; } case E2AP_PDU_PR_successfulOutcome: @@ -5005,7 +6878,11 @@ void E2APMsgHdlr(Buffer *mBuf) procRicServiceUpdateAck(e2apMsg); break; } - + case SuccessfulOutcomeE2__value_PR_RICsubscriptionModificationConfirm: + { + procRicSubscriptionModificationConfirm(e2apMsg); + break; + } default: { @@ -5037,6 +6914,12 @@ void E2APMsgHdlr(Buffer *mBuf) DU_LOG("\nINFO --> E2AP : Error indication received"); break; } + case InitiatingMessageE2__value_PR_ResetRequestE2: + { + DU_LOG("\nINFO --> E2AP : Error indication received"); + procE2ResetRequest(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\