X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fdu_app%2Fdu_e2ap_msg_hdl.c;h=876c83bed73e682721f2af749addea9a1949a5f3;hb=203a75d30fe226a5496af4a0bc50ea0671e32df3;hp=5a42e637433e0b5fade8d35e306ff604ceab8d3e;hpb=959944c4b572d2027bceb7bb474a8fc40f85ec1c;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 5a42e6374..876c83bed 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -566,6 +566,7 @@ uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId) uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType) { + E2NodeConfig *e2NodeConfig=NULLP; E2nodeComponentInterfaceType_t *interfaceType=NULLP; E2nodeComponentID_t *componentID =NULLP; E2nodeComponentConfiguration_t *configuration=NULLP; @@ -581,6 +582,7 @@ uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, Co interfaceType = &e2NodeAddItem->e2nodeComponentInterfaceType; componentID = &e2NodeAddItem->e2nodeComponentID; configuration = &e2NodeAddItem->e2nodeComponentConfiguration; + e2NodeConfig = e2NodeComponentInfo->addConfiguration; break; } case CONFIG_MOD: @@ -589,6 +591,7 @@ uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, Co interfaceType = &e2NodeUpdateItem->e2nodeComponentInterfaceType; componentID = &e2NodeUpdateItem->e2nodeComponentID; configuration = &e2NodeUpdateItem->e2nodeComponentConfiguration; + e2NodeConfig = e2NodeComponentInfo->updateConfiguration; break; } case CONFIG_DEL: @@ -641,9 +644,9 @@ uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, Co } /* E2 Node Component Request Part */ - if(e2NodeComponentInfo->componentRequestPart) + if(e2NodeConfig->componentRequestPart) { - configuration->e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ; + configuration->e2nodeComponentRequestPart.size = e2NodeConfig->reqBufSize ; DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\ configuration->e2nodeComponentRequestPart.size); if(configuration->e2nodeComponentRequestPart.buf == NULLP) @@ -653,7 +656,7 @@ uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, Co } memcpy(configuration->e2nodeComponentRequestPart.buf,\ - e2NodeComponentInfo->componentRequestPart, configuration->\ + e2NodeConfig->componentRequestPart, configuration->\ e2nodeComponentRequestPart.size); } else @@ -663,16 +666,16 @@ uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, Co } /* E2 Node Component Response Part */ - if(e2NodeComponentInfo->componentResponsePart) + if(e2NodeConfig->componentResponsePart) { - configuration->e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; + configuration->e2nodeComponentResponsePart.size = e2NodeConfig->rspBufSize; DU_ALLOC(configuration->e2nodeComponentResponsePart.buf, configuration->e2nodeComponentResponsePart.size); if(configuration->e2nodeComponentResponsePart.buf == NULLP) { DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); return RFAILED; } - memcpy(configuration->e2nodeComponentResponsePart.buf, e2NodeComponentInfo->componentResponsePart, configuration->\ + memcpy(configuration->e2nodeComponentResponsePart.buf, e2NodeConfig->componentResponsePart, configuration->\ e2nodeComponentResponsePart.size); } else @@ -763,7 +766,7 @@ uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAdd { /* Getting only those E2 node configuration from DuCb whose interface * and action type is present in the received array */ - e2NodeComponentInfo = fetchE2NodeComponentInfo(e2NodeList[arrIdx].interface, e2NodeList[arrIdx].actionType, &node); + e2NodeComponentInfo = fetchE2NodeComponentInfo(e2NodeList[arrIdx].interface, e2NodeList[arrIdx].componentId, &node); } if(!e2NodeComponentInfo) @@ -832,7 +835,7 @@ uint8_t BuildE2NodeConfigUpdateList(E2nodeComponentConfigUpdate_List_t *e2NodeUp return RFAILED; } - e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node); + e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].componentId, &node); if(!e2NodeComponentInfo) { DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); @@ -902,7 +905,7 @@ uint8_t BuildE2NodeConfigRemoveList(E2nodeComponentConfigRemoval_List_t *e2NodeR return RFAILED; } - e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node); + e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface,updateE2Node[arrIdx].componentId, &node); if(!e2NodeComponentInfo) { DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); @@ -1580,8 +1583,8 @@ void FreeE2SetupReq(E2AP_PDU_t *e2apMsg) uint8_t BuildAndSendE2SetupReq() { uint8_t arrIdx = 0, elementCnt=0; - uint8_t transId = 0, ret = ROK; - bool memAllocFailed; + uint8_t transId = 0, ret = RFAILED; + bool memAllocFailed = false; E2AP_PDU_t *e2apMsg = NULLP; E2setupRequest_t *e2SetupReq = NULLP; asn_enc_rval_t encRetVal; /* Encoder return value */ @@ -2171,6 +2174,107 @@ void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg) } } } + +/****************************************************************** + * + * @brief handling of e2 noe config update ack ies + * + * @details + * + * Function :handleE2NodeConfigUpdateAckIes + * + * Functionality: handling of e2 noe config update ack ies + * + * @params[in] + * Pointer to the E2 Node cfg + * Procedure code + * @return void +******************************************************************/ + +void handleE2NodeConfigUpdateAckIes(PTR e2NodeCfg, uint8_t procedureCode) +{ + CmLList *node=NULLP; + E2NodeComponent *e2NodeComponentInfo=NULLP; + E2nodeComponentID_t *e2nodeComponentID=NULLP; + E2nodeComponentConfigRemovalAck_Item_t *removalAckItem=NULLP; + E2nodeComponentConfigUpdateAck_Item_t *updateAckItem=NULLP; + E2nodeComponentConfigAdditionAck_Item_t *additionAckItem=NULLP; + + switch(procedureCode) + { + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + additionAckItem = (E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg; + e2nodeComponentID = &additionAckItem->e2nodeComponentID; + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + updateAckItem = (E2nodeComponentConfigUpdateAck_Item_t*) e2NodeCfg; + e2nodeComponentID = &updateAckItem->e2nodeComponentID; + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + removalAckItem= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg; + e2nodeComponentID = &removalAckItem->e2nodeComponentID; + break; + } + } + + switch(e2nodeComponentID->present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0], &node); + if(!e2NodeComponentInfo) + { + DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); + return; + } + break; + } + default: + break; + } + + switch(procedureCode) + { + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig)); + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig)); + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node); + if(e2NodeComponentInfo->addConfiguration) + { + DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig)); + } + if(e2NodeComponentInfo->updateConfiguration) + { + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig)); + } + DU_FREE(node, sizeof(CmLList)); + break; + } + } +} + /****************************************************************** * * @brief Processes E2 Setup Response sent by RIC @@ -2182,18 +2286,16 @@ 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; - CmLList *node=NULL; - E2NodeComponent *e2NodeComponentInfo=NULL; E2nodeComponentConfigAdditionAck_List_t *e2NodeCfgAckList=NULL; E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem=NULL; @@ -2216,7 +2318,7 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) else { DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - return RFAILED; + invalidTransId = true; } break; } @@ -2226,60 +2328,47 @@ 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 - { - 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; + e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck); } + 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; } /******************************************************************* @@ -2533,8 +2622,8 @@ uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoLis { uint8_t elementIdx = 0; MeasurementInfoForAction *measInfoSupportedDb = NULLP; - MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP; - CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;; + MeasurementInfo *measInfoSubscribedDb = NULLP; + CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP; MeasurementInfoItem_t *measItem = NULLP; /* Validate Measurement list is supported by E2 node. @@ -2968,6 +3057,7 @@ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) if(ret == ROK) { cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1); + ricSubscriptionInfo->action = CONFIG_ADD; /* Add RAN subcription detail to RAN function */ DU_ALLOC(ricSubscriptionNode, sizeof(CmLList)); @@ -4488,6 +4578,7 @@ void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg) * - Buld and send the E2 reset request msg to RIC * * @params[in] + * Reset cause * @return ROK - success * RFAILED - failure * @@ -4573,13 +4664,13 @@ uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause) 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 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 E2SetupRequest\n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for reset request\n"); #ifdef DEBUG_ASN_PRINT for(int i=0; i< encBufSize; i++) { @@ -4661,14 +4752,15 @@ void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse) * Functionality: Processes E2 Reset Response sent by RIC * * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure + * @return void * * ****************************************************************/ -uint8_t procResetResponse(E2AP_PDU_t *e2apMsg) +void procResetResponse(E2AP_PDU_t *e2apMsg) { - uint8_t ieIdx =0, transId; - ResetResponseE2_t *resetResponse; + 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;; @@ -4678,36 +4770,47 @@ uint8_t procResetResponse(E2AP_PDU_t *e2apMsg) 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)); + 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; } - else + case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: { - DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - return RFAILED; + for(ranFuncIdx=0; ranFuncIdx0) + { + deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList)); + memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo)); + } + } + break; } - 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. - - 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; + { + 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); - return ROK; } /****************************************************************** @@ -5559,33 +5662,26 @@ uint8_t duSendE2NodeConfigurationUpdate() { e2NodeComponentInfo = (E2NodeComponent*)node->node; - if(e2NodeComponentInfo->componentRequestPart && e2NodeComponentInfo->componentResponsePart) + if(e2NodeComponentInfo->addConfiguration) { - 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; - } - } + e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.addE2Node[e2NodeList.addE2NodeCount].componentId= e2NodeComponentInfo->componentId; + e2NodeList.addE2NodeCount++; + break; + } + if(e2NodeComponentInfo->updateConfiguration) + { + e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].componentId= e2NodeComponentInfo->componentId; + e2NodeList.updateE2NodeCount++; + break; + } + if(e2NodeComponentInfo->deleteConfiguration == true) + { + e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].componentId = e2NodeComponentInfo->componentId; + e2NodeList.removeE2NodeCount++; + break; } node = node->next; } @@ -6729,75 +6825,723 @@ void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg) /******************************************************************* * - * @brief Handles received E2AP message and sends back response + * @brief Free RIC Subscription Delete Required Message * * @details * - * Function : E2APMsgHdlr + * Function : FreeRicSubscriptionDeleteRequired * - * Functionality: - * - Decodes received E2AP control message - * - Prepares response message, encodes and sends to SCTP + * Functionality: Free RIC Subscription Delete Required * - * @params[in] - * @return ROK - success - * RFAILED - failure + * @param E2AP Message PDU + * @return void * - * ****************************************************************/ -void E2APMsgHdlr(Buffer *mBuf) + ******************************************************************/ +void FreeRicSubscriptionDeleteRequired(E2AP_PDU_t *e2apMsg, CmLListCp *ricSubsToBeDelList) { - int i =0; - char *recvBuf = NULLP; - MsgLen copyCnt =0; - MsgLen recvBufLen =0; - E2AP_PDU_t *e2apMsg = NULLP; - asn_dec_rval_t rval ={0}; /* Decoder return value */ - E2AP_PDU_t e2apasnmsg={0} ; - - DU_LOG("\nDEBUG --> E2AP : Received E2AP message buffer"); - ODU_PRINT_MSG(mBuf, 0,0); - - /* Copy mBuf into char array to decode it */ - ODU_GET_MSG_LEN(mBuf, &recvBufLen); - DU_ALLOC(recvBuf, (Size)recvBufLen); + uint8_t ieIdx = 0, arrIdx = 0; + RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP; + RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP; + RICsubscription_List_withCause_t *ricSubsList = NULLP; + CmLList *subsNode = NULLP; - if(recvBuf == NULLP) + if(e2apMsg) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed"); - return; + if(e2apMsg->choice.initiatingMessage) + { + ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired; + if(ricSubsDelRqd->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++) + { + if(ricSubsDelRqd->protocolIEs.list.array[ieIdx]) + { + ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx]; + switch(ricSubsDelRqdIe->id) + { + case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved: + { + ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause; + if(ricSubsList->list.array) + { + for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++) + { + DU_FREE(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t)); + } + DU_FREE(ricSubsList->list.array, ricSubsList->list.size); + } + break; + } + } + DU_FREE(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t)); + } + } + DU_FREE(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size); + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));; } - if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK) + + if(ricSubsToBeDelList) { - DU_LOG("\nERROR --> E2AP : Failed while copying %d", copyCnt); - return; + CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode); + while(subsNode) + { + cmLListDelFrm(ricSubsToBeDelList, subsNode); + DU_FREE(subsNode, sizeof(CmLList)); + CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode); + } } +} -#ifdef DEBUG_ASN_PRINT - printf("\nDEBUG --> E2AP : Received flat buffer to be decoded : "); - for(i=0; i< recvBufLen; i++) +/******************************************************************* + * + * @brief Fill list of RIC subscriptions required to be deleted + * with the cause of deletion + * + * @details + * + * Function : fillRicSubsListWithCause + * + * Functionality: Fill list of RIC subscriptions required to be + * deleted with the cause of deletion + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +uint8_t fillRicSubsListWithCause(RICsubscription_List_withCause_t *ricSubsList, CmLListCp ricSubsToBeDelList) +{ + uint16_t ieIdx = 0; + CmLList *subsNode = NULLP; + RicSubscription *subsInfo = NULLP; + RICsubscription_withCause_ItemIEs_t *subsItemIe = NULLP; + RICsubscription_withCause_Item_t *subsItem = NULLP; + + ricSubsList->list.count = ricSubsToBeDelList.count; + ricSubsList->list.size = ricSubsList->list.count * sizeof(RICsubscription_withCause_ItemIEs_t *); + DU_ALLOC(ricSubsList->list.array, ricSubsList->list.size); + if(!ricSubsList->list.array) { - printf("%x",recvBuf[i]); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + return RFAILED; } -#endif - /* Decoding flat buffer into E2AP messsage */ - e2apMsg = &e2apasnmsg; - memset(e2apMsg, 0, sizeof(E2AP_PDU_t)); + CM_LLIST_FIRST_NODE(&ricSubsToBeDelList, subsNode); + while(subsNode && (ieIdx < ricSubsList->list.count)) + { + subsInfo = (RicSubscription *)subsNode->node; + DU_ALLOC(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t)); + if(!ricSubsList->list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + return RFAILED; + } - rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0); - DU_FREE(recvBuf, (Size)recvBufLen); + subsItemIe = (RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[ieIdx]; + subsItemIe->id = ProtocolIE_IDE2_id_RICsubscription_withCause_Item; + subsItemIe->criticality = CriticalityE2_ignore; + subsItemIe->value.present = RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item; - if(rval.code == RC_FAIL || rval.code == RC_WMORE) - { - DU_LOG("\nERROR --> E2AP : ASN decode failed"); - return; + subsItem = & subsItemIe->value.choice.RICsubscription_withCause_Item; + subsItem->ricRequestID.ricRequestorID = subsInfo->requestId.requestorId; + subsItem->ricRequestID.ricInstanceID = subsInfo->requestId.instanceId; + subsItem->ranFunctionID = subsInfo->ranFuncId; + fillE2Cause(&subsItem->cause, subsInfo->failureCause); + + ieIdx++; + subsNode = subsNode->next; } - printf("\n"); - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); - switch(e2apMsg->present) + return ROK; +} + +/******************************************************************* + * + * @brief Builds and Send RIC Subscription delete required + * + * @details + * + * Function : BuildAndSendRicSubscriptionDeleteRequired + * + * Functionality: Build and send RIC subscription delete required. + * There can be 2 approaches to trigger following. One of these + * approaches may/may not be implemented in future: + * 1. It can be triggerred immediately when a RIC subscription's + * End Time has expired. In this case, only this subscription's + * info will be sent in this message. + * Since we have not yet added support to execute RIC + * Subscription based on Start Time and End Timer, this message is + * not triggered anywhere from DU APP yet. + * 2. Another approach is to have a periodic timer to check subscription + * status running in background. + * When RIC Subscription End Time expires, this subscription is + * marked to be deleted. Later when this background timer expires, + * a RIC Subscription delete required is sent with all the + * subscription's info which is marked to be deleted. + * The following function is implemented keeping in mind the second + * approach. + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t BuildAndSendRicSubscriptionDeleteRequired() +{ + uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP; + RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + CmLListCp ricSubsToBeDelList; + + while(true) { - case E2AP_PDU_PR_unsuccessfulOutcome: + /* Check if there are any RIC subscriptions to be deleted */ + cmLListInit(&ricSubsToBeDelList); + fetchRicSubsToBeDeleted(&ricSubsToBeDelList); + if(ricSubsToBeDelList.count == 0) + { + DU_LOG("\nDEBUG --> E2AP : %s: No RIC subscriptions are required to be deleted", __func__); + return ROK; + } + + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Delete Required Message\n"); + + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + break; + } + + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + break; + } + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDeleteRequired; + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired; + + ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired; + + elementCnt = 1; + ricSubsDelRqd->protocolIEs.list.count = elementCnt; + ricSubsDelRqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequired_IEs_t *); + + DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size); + if(ricSubsDelRqd->protocolIEs.list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__); + break; + } + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t)); + if(ricSubsDelRqd->protocolIEs.list.array[ieIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for index [%d] at line %d", \ + __func__, ieIdx, __LINE__); + break; + } + } + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx]; + ricSubsDelRqdIe->id = ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved; + ricSubsDelRqdIe->criticality = CriticalityE2_ignore; + ricSubsDelRqdIe->value.present = RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause; + if(fillRicSubsListWithCause(&ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause, ricSubsToBeDelList)\ + != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill RIC Subscription list with cause", __func__); + break; + } + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Delete Required Message (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Delete Required Message \n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); + } +#endif + } + + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send RIC Susbcription Delete Required Message"); + + } + ret = ROK; + break; + } + + FreeRicSubscriptionDeleteRequired(e2apMsg, &ricSubsToBeDelList); + return ret; +} + +/******************************************************************* + * + * @brief Free RIC Subscription Delete Request Message + * + * @details + * + * Function : freeAperDecodingOfRicSubsDeleteReq + * + * Functionality: Free RIC Subscription Delete Request + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0; + RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP; + + if(e2apMsg) + { + if(e2apMsg->choice.initiatingMessage) + { + ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest; + if(ricSubsDelReq->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++) + { + if(ricSubsDelReq->protocolIEs.list.array[ieIdx]) + { + free(ricSubsDelReq->protocolIEs.list.array[ieIdx]); + } + } + free(ricSubsDelReq->protocolIEs.list.array); + } + } + } +} + +/******************************************************************* + * + * @brief Process RIC Subscription delete request + * + * @details + * + * Function : procRicSubscriptionDeleteRequest + * + * Functionality: Process RIC subscription delete request. + * Fetch RAN Function and RIC subscription to be deleted. + * Send statistics delete request to MAC for all action sequence + * within this RIC subscription. + * + * @params[in] E2AP PDU + * @return void + * + ******************************************************************/ +void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0; + uint16_t ranFuncId = 0; + bool procFailure = false; + RicRequestId ricReqId; + RanFunction *ranFuncDb = NULLP; + CmLList *ricSubsNode = NULLP; + RicSubscription *ricSubsDb = NULLP; + RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP; + RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP; + + DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Delete Request", __func__); + + do{ + if(!e2apMsg) + { + DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + break; + } + + if(!e2apMsg->choice.initiatingMessage) + { + DU_LOG("\nERROR --> E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__); + break; + } + + ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest; + if(!ricSubsDelReq->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); + break; + } + + for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++) + { + if(!ricSubsDelReq->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + break; + } + + ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx]; + switch(ricSubsDelReqIe->id) + { + case ProtocolIE_IDE2_id_RICrequestID: + { + memset(&ricReqId, 0, sizeof(RicRequestId)); + ricReqId.requestorId = ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID; + break; + } + + case ProtocolIE_IDE2_id_RANfunctionID: + { + ranFuncId = ricSubsDelReqIe->value.choice.RANfunctionID; + ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId); + if(!ranFuncDb) + { + DU_LOG("\nERROR --> E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId); + procFailure = true; + break; + } + + ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); + if(!ricSubsDb) + { + DU_LOG("\nERROR --> E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\ + __func__, ricReqId.requestorId, ricReqId.instanceId); + procFailure = true; + break; + } + + //TODO : Send statistics delete request to MAC + break; + } + + default: + break; + } /* End of switch for Protocol IE Id */ + + if(procFailure) + break; + } /* End of for loop for Protocol IE list */ + + break; + }while(true); + + freeAperDecodingOfRicSubsDeleteReq(e2apMsg); + return; +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for E2 node configuration + * update ack msg by aper decoder + * + * @details + * + * Function : freeAperDecodingOfE2NodeConfigUpdateAck + * + * Functionality: + * - Deallocate the memory allocated for E2 node configuration + * update ack msg by aper decoder + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg) +{ + uint8_t arrIdx =0, e2NodeConfigIdx=0; + E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL; + E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL; + E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL; + E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL; + E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL; + E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL; + + E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP; + if(updateAckMsg->protocolIEs.list.array != NULLP) + { + for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++) + { + if(updateAckMsg->protocolIEs.list.array[arrIdx]) + { + switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; + if(additionAckList->list.array) + { + for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) + { + additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx]; + if(additionAckItemIte) + { + switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + f1InterfaceInfo = additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; + free(f1InterfaceInfo->gNB_DU_ID.buf); + free(f1InterfaceInfo); + break; + } + default: + break; + } + free(additionAckItemIte); + } + free(additionAckList->list.array); + } + break; + } + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List; + if(updateAckList->list.array) + { + for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) + { + updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx]; + if(updateAckItemIe) + { + switch(updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + f1InterfaceInfo = updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; + free(f1InterfaceInfo->gNB_DU_ID.buf); + free(f1InterfaceInfo); + break; + } + default: + break; + } + free(updateAckItemIe); + } + } + free(updateAckList->list.array); + } + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List; + if(removalAckList->list.array) + { + for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) + { + removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx]; + if(removalAckItemIe) + { + switch(removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + f1InterfaceInfo = removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; + free(f1InterfaceInfo->gNB_DU_ID.buf); + free(f1InterfaceInfo); + break; + } + default: + break; + } + free(removalAckItemIe); + } + } + free(removalAckList->list.array); + } + break; + } + } + free(updateAckMsg->protocolIEs.list.array[arrIdx]); + } + } + free(updateAckMsg->protocolIEs.list.array); + } +} + +/****************************************************************** + * + * @brief Processes the E2 node config update ack msg + * + * @details + * + * Function :procE2NodeConfigUpdateAck + * + * Functionality: Processes the E2 node config update ack msg + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx =0; + uint16_t e2CfgIdx =0; + E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck =NULLP; + E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList=NULLP; + E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULLP; + E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList=NULLP; + E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULLP; + E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULLP; + E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAdditionAckItem=NULLP; + + e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge; + + if(e2NodeConfigUpdateAck->protocolIEs.list.array) + { + for(arrIdx =0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; + if(e2NodeConfigAdditionAckList->list.array) + { + for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigAdditionAckList->list.count; e2CfgIdx++) + { + e2NodeAdditionAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2CfgIdx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAdditionAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck); + } + } + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List; + if(e2NodeConfigUpdateAckList->list.array) + { + for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigUpdateAckList->list.count; e2CfgIdx++) + { + e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[e2CfgIdx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck); + } + } + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List; + if(e2NodeConfigRemovalAckList->list.array) + { + for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigRemovalAckList->list.count; e2CfgIdx++) + { + e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[e2CfgIdx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck); + } + } + break; + } + } + } + } + + freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck); +} + +/******************************************************************* + * + * @brief Handles received E2AP message and sends back response + * + * @details + * + * Function : E2APMsgHdlr + * + * Functionality: + * - Decodes received E2AP control message + * - Prepares response message, encodes and sends to SCTP + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void E2APMsgHdlr(Buffer *mBuf) +{ + int i =0; + char *recvBuf = NULLP; + MsgLen copyCnt =0; + MsgLen recvBufLen =0; + E2AP_PDU_t *e2apMsg = NULLP; + asn_dec_rval_t rval ={0}; /* Decoder return value */ + E2AP_PDU_t e2apasnmsg={0} ; + + DU_LOG("\nDEBUG --> E2AP : Received E2AP message buffer"); + ODU_PRINT_MSG(mBuf, 0,0); + + /* Copy mBuf into char array to decode it */ + ODU_GET_MSG_LEN(mBuf, &recvBufLen); + DU_ALLOC(recvBuf, (Size)recvBufLen); + + if(recvBuf == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed"); + return; + } + if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed while copying %d", copyCnt); + return; + } + +#ifdef DEBUG_ASN_PRINT + printf("\nDEBUG --> E2AP : Received flat buffer to be decoded : "); + for(i=0; i< recvBufLen; i++) + { + printf("%x",recvBuf[i]); + } +#endif + + /* Decoding flat buffer into E2AP messsage */ + e2apMsg = &e2apasnmsg; + memset(e2apMsg, 0, sizeof(E2AP_PDU_t)); + + rval = aper_decode(0, &asn_DEF_E2AP_PDU, (void **)&e2apMsg, recvBuf, recvBufLen, 0, 0); + DU_FREE(recvBuf, (Size)recvBufLen); + + if(rval.code == RC_FAIL || rval.code == RC_WMORE) + { + DU_LOG("\nERROR --> E2AP : ASN decode failed"); + return; + } + printf("\n"); + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + + switch(e2apMsg->present) + { + case E2AP_PDU_PR_unsuccessfulOutcome: { switch(e2apMsg->choice.unsuccessfulOutcome->value.present) { @@ -6843,11 +7587,6 @@ void E2APMsgHdlr(Buffer *mBuf) } break; } - case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge: - { - DU_LOG("\nDEBUG --> E2AP : E2 node Config update ack message recevied"); - break; - } case SuccessfulOutcomeE2__value_PR_ResetResponseE2: { procResetResponse(e2apMsg); @@ -6863,7 +7602,11 @@ void E2APMsgHdlr(Buffer *mBuf) procRicSubscriptionModificationConfirm(e2apMsg); break; } - + case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge: + { + procE2NodeConfigUpdateAck(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome [%d]",\ @@ -6900,6 +7643,12 @@ void E2APMsgHdlr(Buffer *mBuf) procE2ResetRequest(e2apMsg); break; } + case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest: + { + DU_LOG("\nINFO --> E2AP : RIC Subscription Delete Request received"); + procRicSubscriptionDeleteRequest(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\