X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fdu_app%2Fdu_e2ap_msg_hdl.c;h=1c8843aa1781665a75948a4ebbee30115d7d1e14;hb=76d2662c441ac10d75d004698ae6ca6a61814d72;hp=d7a98bd29d8fe4ec2d4a16fde367d6b1e03a8386;hpb=2ba58cd78e409ae234aac627914f954e6aa8b1ff;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 d7a98bd29..1c8843aa1 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -45,6 +45,362 @@ #include "RIC-EventTriggerStyle-Item.h" #include "RIC-ReportStyle-Item.h" #include "MeasurementInfo-Action-Item.h" +#include "E2SM-KPM-EventTriggerDefinition.h" +#include "E2SM-KPM-EventTriggerDefinition-Format1.h" +#include "E2SM-KPM-ActionDefinition.h" +#include "E2SM-KPM-ActionDefinition-Format1.h" +#include "MeasurementInfoItem.h" +#include "RANfunctionsIDcause-List.h" + +/******************************************************************* + * + * @brief Fill E2 Failure Cause + * + * @details + * + * Function : fillE2Cause + * + * Functionality: Fill E2 Failure Cause + * + * @params[in] E2 Cause pointer to be filled in + * E2 Cause to be filled from + * @return void + * + ******************************************************************/ +void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause) +{ + e2Cause->present = failureCause.causeType; + switch(e2Cause->present) + { + case CauseE2_PR_ricRequest: + { + e2Cause->choice.ricRequest = failureCause.cause; + break; + } + case CauseE2_PR_ricService: + { + e2Cause->choice.ricService = failureCause.cause; + break; + } + case CauseE2_PR_e2Node: + { + e2Cause->choice.e2Node = failureCause.cause; + break; + } + case CauseE2_PR_transport: + { + e2Cause->choice.transport = failureCause.cause; + break; + } + case CauseE2_PR_protocol: + { + e2Cause->choice.protocol = failureCause.cause; + break; + } + case CauseE2_PR_misc: + { + e2Cause->choice.misc = failureCause.cause; + break; + } + case CauseE2_PR_NOTHING: + default: + break; + } +} + +/******************************************************************* + * + * @brief Free the ErrorIndication Message + * + * @details + * + * Function : FreeRicIndication + * + * Functionality: Free the ErrorIndication Message + * + * @params[in] + * E2AP_PDU is to freed + * @return void + * + ******************************************************************/ +void FreeErrorIndication(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx = 0; + ErrorIndicationE2_t *errorIndicationMsg= NULLP; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.initiatingMessage != NULLP) + { + errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2; + if(errorIndicationMsg!= NULLP) + { + if(errorIndicationMsg->protocolIEs.list.array != NULLP) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + DU_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t)); + } + DU_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size); + } + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Builds and Send the ErrorIndication Message + * + * @details + * + * Function : BuildAndSendErrorIndication + * + * Functionality:Fills the ErrorIndication Message + * + * @params[in] + * Trans id + * Ric req id + * Ran function id + * Cause of failure + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t BuildAndSendErrorIndication(int8_t transId, RicRequestId requestId, uint16_t ranFuncId, E2FailureCause failureCause) +{ + uint8_t elementCnt =0, arrIdx=0, ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + ErrorIndicationE2_t *errorIndicationMsg=NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + while(true) + { + DU_LOG("\nINFO --> E2AP : Building Error Indication Message\n"); + + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__); + break; + } + + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__); + break; + } + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_ErrorIndicationE2; + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_ErrorIndicationE2; + + errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2; + + /* Element count is 2 for TransactionID/RICrequestID and Cause. + * If the RAN function id is present, the count will be increased.*/ + elementCnt = 2; + if(ranFuncId>0) + { + elementCnt++; + } + + errorIndicationMsg->protocolIEs.list.count = elementCnt; + errorIndicationMsg->protocolIEs.list.size = elementCnt * sizeof(ErrorIndicationE2_IEs_t*); + + /* Initialize the E2Setup members */ + DU_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size); + if(errorIndicationMsg->protocolIEs.list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__); + break; + } + + for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++) + { + DU_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t)); + if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for array [%d] elements in %s at line %d", arrIdx, __func__, __LINE__); + break; + } + } + if(arrIdx < elementCnt) + break; + + arrIdx = 0; + + if(transId >=0 && transId<=255) + { + /* TransactionID */ + errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_TransactionID; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId; + } + else + { + /* RICrequestID */ + errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RICrequestID; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RICrequestID; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricRequestorID = requestId.requestorId; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RICrequestID.ricInstanceID = requestId.instanceId; + } + + if(ranFuncId>0) + { + /* RAN Function ID */ + arrIdx++; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_RANfunctionID; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_RANfunctionID; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.RANfunctionID = ranFuncId; + } + + /* Cause */ + arrIdx++; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore; + errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2; + fillE2Cause(&errorIndicationMsg->protocolIEs.list.array[arrIdx]->value.choice.CauseE2, failureCause); + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\ + encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode Error Indication Message (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for Error 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) != ROK) + { + DU_LOG("\nINFO --> E2AP : Sending Error Indication Message"); + + } + ret = ROK; + break; + } + FreeErrorIndication(e2apMsg); + return ret; +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for e2 + * Config Update Failure + * + * @details + * + * Function : freeAperDecodingOfE2Node Config UpdateFailure + * + * Functionality: Deallocation of memory allocated by aper decoder + * for e2 Config Update Failure + * + * @params[in] E2nodeConfigurationUpdateFailure_t to be deallocated + * @return void + * + * ****************************************************************/ + +void freeAperDecodingOfE2NodeConfigUpdateFailure(E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail) +{ + uint8_t arrIdx =0; + + if(e2NodeCfgUpdFail) + { + if(e2NodeCfgUpdFail->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]) + { + free(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]); + } + } + free(e2NodeCfgUpdFail->protocolIEs.list.array); + } + } +} + +/****************************************************************** + * + * @brief Processes E2 Node Config Update Failure sent by RIC + * + * @details + * + * Function : procE2NodeConfigUpdateFailure + * + * Functionality: Processes E2 Node Config Update failure sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void procE2NodeConfigUpdateFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx =0, transId =0, timerValue=0; + E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL; + + DU_LOG("\nINFO --> E2AP : E2 Node Config Update failure received"); + e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure; + + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + transId = e2NodeCfgUpdFail->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); + } + break; + } + case ProtocolIE_IDE2_id_TimeToWaitE2: + { + timerValue = convertE2WaitTimerEnumToValue(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2); + if((duChkTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR)) == FALSE) + { + duStartTmr((PTR)&(duCb.e2apDb), EVENT_E2_NODE_CONFIG_UPDATE_TMR, timerValue); + } + else + { + DU_LOG("\nERROR --> E2AP : EVENT_E2_NODE_CONFIG_UPDATE_TMR timer is already running"); + } + break; + } + } + } + + freeAperDecodingOfE2NodeConfigUpdateFailure(e2NodeCfgUpdFail); +} /******************************************************************* * @@ -124,116 +480,115 @@ uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId) return ret; } -/****************************************************************** - * - * @brief Search E2 node component with the help of action type - * - * @details - * - * Function : searchE2NodeComponentInfo - * - * Functionality: Search E2 node component with the help of action type - * - * @params[in] uint8_t componentActionType - * @return CmLList - * - * ****************************************************************/ - -CmLList *searchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType) -{ - E2NodeComponent *e2NodeComponentInfo; - CmLList *node; - - if(duCb.e2apDb.e2NodeComponentList.count) - { - CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); - while(node) - { - e2NodeComponentInfo = (E2NodeComponent*)node->node; - if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentActionType == componentActionType)) - break; - else - node = node->next; - } - } - return node; -} - /******************************************************************* * - * @brief Builds E2 node config addition list + * @brief fill the E2 node config information * * @details * - * Function : BuildE2NodeConfigAddList + * Function : fillE2NodeConfig * - * Functionality: Building E2 node config addition list + * Functionality: fill E2 node config information * - * @params[in] E2nodeComponentConfigAddition_List_t *e2NodeAddList + * @params[in] + * Pointer to e2NodeCfg to be filled + * E2 Node Component information + * Type of configuration * @return ROK - success * RFAILED - failure * ******************************************************************/ -uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList) +uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType) { - uint8_t arrIdx = 0; - CmLList *node; - E2NodeComponent *e2NodeComponentInfo; - E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe; - E2nodeComponentConfigAddition_Item_t *e2NodeAddItem; - - e2NodeAddList->list.count = 1; - e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *); - DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size); - if(e2NodeAddList->list.array == NULLP) + E2nodeComponentInterfaceType_t *interfaceType=NULLP; + E2nodeComponentID_t *componentID =NULLP; + E2nodeComponentConfiguration_t *configuration=NULLP; + E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL; + E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL; + E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL; + + switch(configType) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); - return RFAILED; + case CONFIG_ADD: + { + e2NodeAddItem = (E2nodeComponentConfigAddition_Item_t*)e2NodeCfg; + interfaceType = &e2NodeAddItem->e2nodeComponentInterfaceType; + componentID = &e2NodeAddItem->e2nodeComponentID; + configuration = &e2NodeAddItem->e2nodeComponentConfiguration; + break; + } + case CONFIG_MOD: + { + e2NodeUpdateItem = (E2nodeComponentConfigUpdate_Item_t *) e2NodeCfg; + interfaceType = &e2NodeUpdateItem->e2nodeComponentInterfaceType; + componentID = &e2NodeUpdateItem->e2nodeComponentID; + configuration = &e2NodeUpdateItem->e2nodeComponentConfiguration; + break; + } + case CONFIG_DEL: + { + e2NodeRemovalItem = (E2nodeComponentConfigRemoval_Item_t*) e2NodeCfg; + interfaceType = &e2NodeRemovalItem->e2nodeComponentInterfaceType; + componentID = &e2NodeRemovalItem->e2nodeComponentID; + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Configuration type %d does not supported ", configType); + return RFAILED; + } } - - for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++) + /* E2nodeComponentInterfaceType */ + *interfaceType = convertInterfaceToE2ComponentInterfaceType(e2NodeComponentInfo->interfaceType); + + /* We now only support the F1 interface out of these interfaces + * (NG,XN,E1,F1,W1,S1,X2), therefore only the F1 component identifier was filled in. */ + + if(*interfaceType == F1) { - DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t)); - if(e2NodeAddList->list.array[arrIdx] == NULLP) + /* E2 Node Component ID */ + componentID->present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1; + DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1,sizeof(E2nodeComponentInterfaceF1_t)); + if(componentID->choice.e2nodeComponentInterfaceTypeF1 == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); + return RFAILED; + } + componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t); + DU_ALLOC(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\ + componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size); + + if(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); return RFAILED; } + memcpy(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf, &e2NodeComponentInfo->componentId,\ + componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size); } - - node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD); - if(!node) + + if(configType == CONFIG_DEL) { - DU_LOG("\nERROR --> E2AP : Received e2NodeComponentInfo is null"); - return RFAILED; + /* We don't need to fill out the E2 Node Component Request and Response + * information in the case of CONFIG_DEL, therefore returning ROK from here. */ + return ROK; } - e2NodeComponentInfo = (E2NodeComponent*)node->node; - - arrIdx = 0; - e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx]; - e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item; - e2NodeAddItemIe->criticality = CriticalityE2_reject; - e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item; - e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item; - - /* E2nodeComponentInterfaceType */ - e2NodeAddItem->e2nodeComponentInterfaceType = E2nodeComponentInterfaceType_f1; /* E2 Node Component Request Part */ if(e2NodeComponentInfo->componentRequestPart) { - e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ; - DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\ - e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size); - if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf == NULLP) + configuration->e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ; + DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\ + configuration->e2nodeComponentRequestPart.size); + if(configuration->e2nodeComponentRequestPart.buf == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); return RFAILED; } - memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\ - e2NodeComponentInfo->componentRequestPart, e2NodeAddItem->e2nodeComponentConfiguration.\ + memcpy(configuration->e2nodeComponentRequestPart.buf,\ + e2NodeComponentInfo->componentRequestPart, configuration->\ e2nodeComponentRequestPart.size); } else @@ -242,20 +597,17 @@ uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAdd return RFAILED; } - /* E2 Node Component Response Part */ if(e2NodeComponentInfo->componentResponsePart) { - e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; - DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \ - e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.size); - if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf == NULLP) + configuration->e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; + DU_ALLOC(configuration->e2nodeComponentResponsePart.buf, configuration->e2nodeComponentResponsePart.size); + if(configuration->e2nodeComponentResponsePart.buf == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); return RFAILED; } - memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \ - e2NodeComponentInfo->componentResponsePart, e2NodeAddItem->e2nodeComponentConfiguration.\ + memcpy(configuration->e2nodeComponentResponsePart.buf, e2NodeComponentInfo->componentResponsePart, configuration->\ e2nodeComponentResponsePart.size); } else @@ -264,29 +616,249 @@ uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAdd return RFAILED; } - /* E2 Node Component ID */ - e2NodeAddItem->e2nodeComponentID.present = E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1; - DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1,\ - sizeof(E2nodeComponentInterfaceF1_t)); - if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1 == NULLP) + return ROK; +} + +/******************************************************************* + * + * @brief Builds E2 node config addition list + * + * @details + * + * Function : BuildE2NodeConfigAddList + * + * Functionality: Building E2 node config addition list + * + * @params[in] + * E2nodeComponentConfigAddition_List_t to be filled + * Procedure Code + * Count of E2 node to be added in the list + * Received list of E2 node configuration + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList, uint8_t procedureCode, uint16_t count, E2NodeConfigItem *e2NodeList) +{ + uint8_t arrIdx = 0; + CmLList *node =NULL; + E2NodeComponent *e2NodeComponentInfo=NULL; + E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe=NULL; + E2nodeComponentConfigAddition_Item_t *e2NodeAddItem=NULL; + + + /* For ProcedureCodeE2_id_E2setup, the number of E2 node configuration list items is + * equal to the number of E2 node configuration entries stored in the database. + * For any other procedure, the E2 node configuration list count is equal + * to the count of E2 node configuration obtained from the function's caller */ + + if(procedureCode == ProcedureCodeE2_id_E2setup) + e2NodeAddList->list.count = duCb.e2apDb.e2NodeComponentList.count; + else + e2NodeAddList->list.count = count; + + e2NodeAddList->list.size = e2NodeAddList->list.count * sizeof(E2nodeComponentConfigAddition_ItemIEs_t *); + DU_ALLOC(e2NodeAddList->list.array, e2NodeAddList->list.size); + if(e2NodeAddList->list.array == NULLP) { DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); return RFAILED; } - e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size = sizeof(uint8_t); - DU_ALLOC(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf,\ - e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.size); - if(e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP) + for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++) + { + DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t)); + if(e2NodeAddList->list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + return RFAILED; + } + + if(procedureCode == ProcedureCodeE2_id_E2setup) + { + /* Getting all of the E2 node configuration's information from DuCb one by one*/ + if(arrIdx == 0) + { + CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); + } + else + { + node = node->next; + } + if(!node) + { + DU_LOG("\nERROR --> E2AP : E2 node component list node is null"); + return RFAILED; + } + e2NodeComponentInfo = (E2NodeComponent*)node->node; + } + else + { + /* 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); + } + + if(!e2NodeComponentInfo) + { + DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); + return RFAILED; + } + + e2NodeAddItemIe = (E2nodeComponentConfigAddition_ItemIEs_t *) e2NodeAddList->list.array[arrIdx]; + e2NodeAddItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition_Item; + e2NodeAddItemIe->criticality = CriticalityE2_reject; + e2NodeAddItemIe->value.present = E2nodeComponentConfigAddition_ItemIEs__value_PR_E2nodeComponentConfigAddition_Item; + e2NodeAddItem = &e2NodeAddItemIe->value.choice.E2nodeComponentConfigAddition_Item; + if(fillE2NodeConfig((PTR)e2NodeAddItem, e2NodeComponentInfo, CONFIG_ADD) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill the E2 node configuration"); + return RFAILED; + } + } + return ROK; +} + +/******************************************************************* + * + * @brief Builds E2 node config update list + * + * @details + * + * Function : BuildE2NodeConfigUpdateList + * + * Functionality: Building E2 node config update list + * + * @params[in] + * E2nodeComponentConfigUpdate_List_t to be filled + * Count of E2 node to be update in the list + * Received list of E2 node configuration + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t BuildE2NodeConfigUpdateList(E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList, uint16_t count, E2NodeConfigItem *updateE2Node) +{ + uint8_t arrIdx = 0; + CmLList *node =NULL; + E2NodeComponent *e2NodeComponentInfo =NULL; + E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe =NULL; + E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL; + + e2NodeUpdateList->list.count = count; + e2NodeUpdateList->list.size = e2NodeUpdateList->list.count * sizeof(E2nodeComponentConfigUpdate_ItemIEs_t *); + DU_ALLOC(e2NodeUpdateList->list.array, e2NodeUpdateList->list.size); + if(e2NodeUpdateList->list.array == NULLP) { - DU_LOG("\nERROR -->list. E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); return RFAILED; } - e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[arrIdx] = e2NodeComponentInfo->componentId; + + for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++) + { + DU_ALLOC(e2NodeUpdateList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdate_ItemIEs_t)); + if(e2NodeUpdateList->list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); + return RFAILED; + } + + e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node); + if(!e2NodeComponentInfo) + { + DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); + return RFAILED; + } + + e2NodeUpdateItemIe = (E2nodeComponentConfigUpdate_ItemIEs_t *) e2NodeUpdateList->list.array[arrIdx]; + e2NodeUpdateItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigUpdate_Item; + e2NodeUpdateItemIe->criticality = CriticalityE2_reject; + e2NodeUpdateItemIe->value.present = E2nodeComponentConfigUpdate_ItemIEs__value_PR_E2nodeComponentConfigUpdate_Item; + e2NodeUpdateItem = &e2NodeUpdateItemIe->value.choice.E2nodeComponentConfigUpdate_Item; + + if(fillE2NodeConfig((PTR)e2NodeUpdateItem, e2NodeComponentInfo, CONFIG_MOD) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill the E2 node configuration"); + return RFAILED; + } + + } return ROK; } + +/******************************************************************* + * + * @brief Builds E2 node config remove list + * + * @details + * + * Function :BuildE2NodeConfigRemoveList + * + * Functionality: Building E2 node config remove list + * + * @params[in] + * E2nodeComponentConfigRemoval_List_t to be filled + * Count of E2 node to be remove in the list + * Received list of E2 node configuration + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t BuildE2NodeConfigRemoveList(E2nodeComponentConfigRemoval_List_t *e2NodeRemoveList, uint16_t count, E2NodeConfigItem *updateE2Node) +{ + uint8_t arrIdx = 0; + CmLList *node=NULL; + E2NodeComponent *e2NodeComponentInfo=NULL; + E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItemIe=NULL; + E2nodeComponentConfigRemoval_Item_t *e2NodeRemovalItem=NULL; + + e2NodeRemoveList->list.count = count; + e2NodeRemoveList->list.size = e2NodeRemoveList->list.count * sizeof(E2nodeComponentConfigRemoval_ItemIEs_t *); + DU_ALLOC(e2NodeRemoveList->list.array, e2NodeRemoveList->list.size); + if(e2NodeRemoveList->list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__); + return RFAILED; + } + + for(arrIdx = 0; arrIdx< e2NodeRemoveList->list.count; arrIdx++) + { + DU_ALLOC(e2NodeRemoveList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemoval_ItemIEs_t)); + if(e2NodeRemoveList->list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__); + return RFAILED; + } + + e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node); + if(!e2NodeComponentInfo) + { + DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); + return RFAILED; + } + + e2NodeRemovalItemIe = (E2nodeComponentConfigRemoval_ItemIEs_t *) e2NodeRemoveList->list.array[arrIdx]; + e2NodeRemovalItemIe->id = ProtocolIE_IDE2_id_E2nodeComponentConfigRemoval_Item; + e2NodeRemovalItemIe->criticality = CriticalityE2_reject; + e2NodeRemovalItemIe->value.present = E2nodeComponentConfigRemoval_ItemIEs__value_PR_E2nodeComponentConfigRemoval_Item; + e2NodeRemovalItem = &e2NodeRemovalItemIe->value.choice.E2nodeComponentConfigRemoval_Item; + + if(fillE2NodeConfig((PTR)e2NodeRemovalItem, e2NodeComponentInfo, CONFIG_DEL) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill the E2 node configuration"); + return RFAILED; + } + + } + return ROK; +} /******************************************************************* * * @brief deallocation of E2SM_KPM_RANfunction_Description_t @@ -1047,7 +1619,7 @@ uint8_t BuildAndSendE2SetupReq() e2SetupReq->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_E2nodeComponentConfigAddition; e2SetupReq->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; e2SetupReq->protocolIEs.list.array[arrIdx]->value.present = E2setupRequestIEs__value_PR_E2nodeComponentConfigAddition_List; - if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List))!=ROK) + if(BuildE2NodeConfigAddList(&(e2SetupReq->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAddition_List), ProcedureCodeE2_id_E2setup, 0, NULL)!=ROK) { DU_LOG("\nERROR --> E2AP : Failed to create E2 Node config list"); break; @@ -1094,121 +1666,111 @@ uint8_t BuildAndSendE2SetupReq() /******************************************************************* * - * @brief Builds Ric Request Id + * @brief Builds RIC Action Admitted List * * @details * - * Function : BuildRicRequestId + * Function : BuildRicActionAdmitList * - * Functionality: Building the Ric Request Id + * Functionality: Builds RIC Action Admitted List * - * @params[in] RICrequestID_t *ricReqId + * @params[in] Pointer to RIC Action Admitted List to be filled + * Subscription Response information * @return ROK - success * RFAILED - failure * * ****************************************************************/ - -uint8_t BuildRicRequestId(RICrequestID_t *ricReqId) +uint8_t BuildRicActionAdmitList(RICaction_Admitted_List_t *admitList, PendingSubsRspInfo *subsRspInfo) { - if(ricReqId == NULLP) - { - return RFAILED; - } - - ricReqId->ricRequestorID = 1; - ricReqId->ricInstanceID = 1; - return ROK; -} + uint8_t idx = 0; + uint8_t elementCnt = 0; + RICaction_Admitted_ItemIEs_t *admitItem = NULLP; -/******************************************************************* - * - * @brief Fills the mandatory RicAdmitted List Items - * - * @details - * - * Function : fillRicAdmitList - * - * Functionality: Fills the mandatory Ric Admitted List Items - * - * @params[in] RICaction_Admitted_ItemIEs_t *ricAdmitItems - * @return ROK - success - * RFAILED - failure - * - * ****************************************************************/ + elementCnt = subsRspInfo->numOfAcceptedActions; -uint8_t fillRicAdmitList(RICaction_Admitted_ItemIEs_t *ricAdmitItems) -{ + admitList->list.count = elementCnt; + admitList->list.size = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t *); - if(ricAdmitItems != NULLP) + DU_ALLOC(admitList->list.array, admitList->list.size); + if(admitList->list.array == NULLP) { - ricAdmitItems->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item; - ricAdmitItems->criticality = CriticalityE2_reject; - ricAdmitItems->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item; - ricAdmitItems->value.choice.RICaction_Admitted_Item.ricActionID = 1; + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } - else + + for(idx=0; idxlist.array[idx], sizeof(RICaction_Admitted_ItemIEs_t)); + if(admitList->list.array[idx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; + } + + admitItem = (RICaction_Admitted_ItemIEs_t *)admitList->list.array[idx]; + admitItem->id = ProtocolIE_IDE2_id_RICaction_Admitted_Item; + admitItem->criticality = CriticalityE2_reject; + admitItem->value.present = RICaction_Admitted_ItemIEs__value_PR_RICaction_Admitted_Item; + admitItem->value.choice.RICaction_Admitted_Item.ricActionID = subsRspInfo->acceptedActionList[idx]; } return ROK; } + /******************************************************************* * - * @brief Builds the mandatory RicAdmitted List Params + * @brief Builds RIC Action Not Admitted List * * @details * - * Function : BuildRicAdmitList + * Function : BuildRicActionNotAdmitList * - * Functionality: Builds the mandatory Ric Admitted List Params + * Functionality: Builds RIC Action Not Admitted List * - * @params[in] RICaction_Admitted_List_t *admitListPtr + * @params[in] Pointer to RIC Action Not Admitted List to be filled + * Subscription Response information * @return ROK - success * RFAILED - failure * * ****************************************************************/ - -uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr) +uint8_t BuildRicActionNotAdmitList(RICaction_NotAdmitted_List_t *notAdmitList, PendingSubsRspInfo *subsRspInfo) { - uint8_t idx ; - uint8_t elementCnt; - uint8_t ret= ROK; - elementCnt = 1; + uint8_t idx = 0; + uint8_t elementCnt = 0; + RICaction_NotAdmitted_ItemIEs_t *notAdmitItem = NULLP; + + elementCnt = subsRspInfo->numOfRejectedActions; - if(admitListPtr == NULLP) + notAdmitList->list.count = elementCnt; + notAdmitList->list.size = elementCnt * sizeof(RICaction_NotAdmitted_ItemIEs_t *); + + DU_ALLOC(notAdmitList->list.array, notAdmitList->list.size); + if(notAdmitList->list.array == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation for RIC Admit List failed"); - ret = RFAILED; + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } - else + + for(idx=0; idxlist.count = elementCnt; - admitListPtr->list.size = elementCnt * sizeof(RICaction_Admitted_ItemIEs_t); - DU_ALLOC(admitListPtr->list.array, admitListPtr->list.size); - if(admitListPtr->list.array == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for RIC Admit List failed"); - ret = RFAILED; - } - else + DU_ALLOC(notAdmitList->list.array[idx], sizeof(RICaction_NotAdmitted_ItemIEs_t)); + if(notAdmitList->list.array[idx] == NULLP) { - for(idx=0 ; idxlist.array[idx], sizeof(RICaction_Admitted_ItemIEs_t)); - if(admitListPtr->list.array[idx] == NULLP) - { - ret = RFAILED; - } - } - if(ret != RFAILED) - { - idx=0; - fillRicAdmitList((RICaction_Admitted_ItemIEs_t *)admitListPtr->list.array[idx]); - } + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d]", __func__, __LINE__); + return RFAILED; } - } - return ret; + + notAdmitItem = (RICaction_NotAdmitted_ItemIEs_t *)notAdmitList->list.array[idx]; + notAdmitItem->id = ProtocolIE_IDE2_id_RICaction_NotAdmitted_Item; + notAdmitItem->criticality = CriticalityE2_reject; + notAdmitItem->value.present = RICaction_NotAdmitted_ItemIEs__value_PR_RICaction_NotAdmitted_Item; + notAdmitItem->value.choice.RICaction_NotAdmitted_Item.ricActionID = \ + subsRspInfo->rejectedActionList[idx].id; + fillE2Cause(¬AdmitItem->value.choice.RICaction_NotAdmitted_Item.cause, \ + subsRspInfo->rejectedActionList[idx].failureCause); + } + return ROK; } + /******************************************************************* * * @breif Deallocation of BuildAndSendRicSubscriptionRsp memory @@ -1223,152 +1785,166 @@ uint8_t BuildRicAdmitList(RICaction_Admitted_List_t *admitListPtr) * * @return void * - * ******************************************************************/ void FreeRicSubscriptionRsp(E2AP_PDU_t *e2apRicMsg) { RICsubscriptionResponse_t *ricSubscriptionRsp= NULLP; uint8_t idx=0; - uint8_t idx1=0; - RICaction_Admitted_List_t *admitListPtr; + uint8_t listIdx=0; + RICaction_Admitted_List_t *admitList = NULLP; + RICaction_NotAdmitted_List_t *notAdmitList = NULLP; if(e2apRicMsg != NULLP) { if(e2apRicMsg->choice.successfulOutcome != NULLP) { - ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse; - if(ricSubscriptionRsp) - { - if(ricSubscriptionRsp->protocolIEs.list.array != NULLP) - { - for(idx=0; idxprotocolIEs.list.count; idx++) - { - if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP) - { - switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id) - { - case ProtocolIE_IDE2_id_RICrequestID: - break; - - case ProtocolIE_IDE2_id_RANfunctionID: - break; - - case ProtocolIE_IDE2_id_RICactions_Admitted: - { - admitListPtr = &ricSubscriptionRsp->protocolIEs.list.\ - array[idx]->value.choice.RICaction_Admitted_List; - if(admitListPtr->list.array != NULLP) - { - for(idx1=0 ; idx1list.count; idx1++ ) - { - if(admitListPtr->list.array[idx1] != NULLP) - { - DU_FREE(admitListPtr->list.array[idx1], - sizeof(RICaction_Admitted_ItemIEs_t)); - } - } - DU_FREE(admitListPtr->list.array, admitListPtr->list.size); - } - break; - } - default: - break; - } - DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], \ - sizeof(RICsubscriptionResponse_IEs_t)); - } - } - DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, \ - ricSubscriptionRsp->protocolIEs.list.size); - } - } - DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); - } - DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t)); - } -} -/******************************************************************* - * - * @brief Builds and Send the RicSubscriptionRsp - * - * @details - * - * Function : BuildAndSendRicSubscriptionRsp - * - * functionality:Fills the RicSubscriptionRsp - * - * @return ROK - success - * RFAILED - failure - * - ******************************************************************/ -uint8_t FillRicSubscriptionRsp(RICsubscriptionResponse_t *ricSubscriptionRsp ) -{ - uint8_t idx=0; - uint8_t ret = ROK; - uint8_t elementCnt = 0; - uint8_t BuildRicRequestIdret=ROK; - uint8_t BuildRicAdmitListret=ROK; - - elementCnt=3; - ricSubscriptionRsp->protocolIEs.list.count = elementCnt; + ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse; + if(ricSubscriptionRsp) + { + if(ricSubscriptionRsp->protocolIEs.list.array != NULLP) + { + for(idx=0; idxprotocolIEs.list.count; idx++) + { + if(ricSubscriptionRsp->protocolIEs.list.array[idx] != NULLP) + { + switch(ricSubscriptionRsp->protocolIEs.list.array[idx]->id) + { + case ProtocolIE_IDE2_id_RICactions_Admitted: + { + admitList = &ricSubscriptionRsp->protocolIEs.list.\ + array[idx]->value.choice.RICaction_Admitted_List; + if(admitList->list.array != NULLP) + { + for(listIdx=0 ; listIdx < admitList->list.count; listIdx++) + { + DU_FREE(admitList->list.array[listIdx], sizeof(RICaction_Admitted_ItemIEs_t)); + } + DU_FREE(admitList->list.array, admitList->list.size); + } + break; + } + case ProtocolIE_IDE2_id_RICactions_NotAdmitted: + { + notAdmitList = &ricSubscriptionRsp->protocolIEs.list.\ + array[idx]->value.choice.RICaction_NotAdmitted_List; + if(notAdmitList->list.array != NULLP) + { + for(listIdx=0 ; listIdx < notAdmitList->list.count; listIdx++) + { + DU_FREE(notAdmitList->list.array[listIdx], sizeof(RICaction_NotAdmitted_ItemIEs_t)); + } + DU_FREE(notAdmitList->list.array, notAdmitList->list.size); + } + break; + } + default: + break; + } + DU_FREE(ricSubscriptionRsp->protocolIEs.list.array[idx], sizeof(RICsubscriptionResponse_IEs_t)); + } + } + DU_FREE(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size); + } + } + DU_FREE(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + } + DU_FREE(e2apRicMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Fill RIC Subscription Response IEs + * + * @details + * + * Function : fillRicSubscriptionRsp + * + * functionality: Fill RIC Subscription Response IEs + * + * @param Pointer to RIC subscription response + * Subscription response information + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t fillRicSubscriptionRsp(RICsubscriptionResponse_t *ricSubscriptionRsp, PendingSubsRspInfo *subsRspInfo) +{ + uint8_t ieIdx = 0; + uint8_t elementCnt = 0; + RICsubscriptionResponse_IEs_t *subsRspIe = NULLP; + + elementCnt = 3; + if(subsRspInfo->numOfRejectedActions) + elementCnt++; + + ricSubscriptionRsp->protocolIEs.list.count = elementCnt; ricSubscriptionRsp->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionResponse_IEs_t); - DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, \ - ricSubscriptionRsp->protocolIEs.list.size); + DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array, ricSubscriptionRsp->protocolIEs.list.size); if(ricSubscriptionRsp->protocolIEs.list.array == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation for FillRicSubscriptionRsp failed"); - ret = RFAILED; + DU_LOG("\nERROR --> E2AP : Memory allocation failed at %s : line %d", __func__, __LINE__); + return RFAILED; } - else + + for(ieIdx=0; ieIdxprotocolIEs.list.count; ieIdx++) { - for(idx=0; idxprotocolIEs.list.count; idx++) + DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionResponse_IEs_t)); + if(ricSubscriptionRsp->protocolIEs.list.array[ieIdx] == NULLP) { - DU_ALLOC(ricSubscriptionRsp->protocolIEs.list.array[idx], \ - sizeof(RICsubscriptionResponse_IEs_t)); - if(ricSubscriptionRsp->protocolIEs.list.array[idx] == NULLP) - { - ret = RFAILED; - } + DU_LOG("\nERROR --> E2AP : Memory allocation failed at [%s] : line [%d] : ieIdx [%d]", __func__, __LINE__,ieIdx); + return RFAILED; } - if(ret != RFAILED) - { + } - idx=0; - ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICrequestID; - ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\ - RICsubscriptionRequest_IEs__value_PR_RICrequestID; - BuildRicRequestIdret = - BuildRicRequestId(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICrequestID); - if(BuildRicRequestIdret != ROK) - { - ret = RFAILED; - } - else - { - idx++; - ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RANfunctionID; - ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\ - RICsubscriptionRequest_IEs__value_PR_RANfunctionID; - ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RANfunctionID = 1; + /* RIC Request ID */ + ieIdx=0; + subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx]; + subsRspIe->id = ProtocolIE_IDE2_id_RICrequestID; + subsRspIe->criticality = CriticalityE2_reject; + subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RICrequestID; + subsRspIe->value.choice.RICrequestID.ricRequestorID = subsRspInfo->requestId.requestorId; + subsRspIe->value.choice.RICrequestID.ricInstanceID = subsRspInfo->requestId.instanceId; + + /* RAN Function ID */ + ieIdx++; + subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx]; + subsRspIe->id = ProtocolIE_IDE2_id_RANfunctionID; + subsRspIe->criticality = CriticalityE2_reject; + subsRspIe->value.present = RICsubscriptionRequest_IEs__value_PR_RANfunctionID; + subsRspIe->value.choice.RANfunctionID = subsRspInfo->ranFuncId; + + /* RIC Action Admitted List */ + ieIdx++; + subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx]; + subsRspIe->id = ProtocolIE_IDE2_id_RICactions_Admitted; + subsRspIe->criticality = CriticalityE2_reject; + subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List; + if(BuildRicActionAdmitList(&subsRspIe->value.choice.RICaction_Admitted_List, subsRspInfo) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill RIC Action Admitted List in RIC Subscription Response"); + return RFAILED; + } - idx++; - ricSubscriptionRsp->protocolIEs.list.array[idx]->id = ProtocolIE_IDE2_id_RICactions_Admitted; - ricSubscriptionRsp->protocolIEs.list.array[idx]->criticality = CriticalityE2_reject; - ricSubscriptionRsp->protocolIEs.list.array[idx]->value.present =\ - RICsubscriptionResponse_IEs__value_PR_RICaction_Admitted_List; - BuildRicAdmitListret = - BuildRicAdmitList(&ricSubscriptionRsp->protocolIEs.list.array[idx]->value.choice.RICaction_Admitted_List); - if(BuildRicAdmitListret != ROK) - { - ret = RFAILED; - } - } + /* RIC Action Not Admitted List */ + if(subsRspInfo->numOfRejectedActions) + { + ieIdx++; + subsRspIe = ricSubscriptionRsp->protocolIEs.list.array[ieIdx]; + subsRspIe->id = ProtocolIE_IDE2_id_RICactions_NotAdmitted; + subsRspIe->criticality = CriticalityE2_reject; + subsRspIe->criticality = CriticalityE2_reject; + subsRspIe->value.present = RICsubscriptionResponse_IEs__value_PR_RICaction_NotAdmitted_List; + if(BuildRicActionNotAdmitList(&subsRspIe->value.choice.RICaction_NotAdmitted_List, subsRspInfo) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to fill RIC Action Not Admitted List in RIC Subscription Response"); + return RFAILED; } - } - return ret; + } + + return ROK; } + /******************************************************************* * * @brief Builds and Send the RicSubscriptionRsp @@ -1384,14 +1960,12 @@ uint8_t FillRicSubscriptionRsp(RICsubscriptionResponse_t *ricSubscriptionRsp ) * ******************************************************************/ -uint8_t BuildAndSendRicSubscriptionRsp() +uint8_t BuildAndSendRicSubscriptionRsp(PendingSubsRspInfo *subsRspInfo) { - - E2AP_PDU_t *e2apRicMsg = NULLP; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apRicMsg = NULLP; RICsubscriptionResponse_t *ricSubscriptionRsp=NULLP; - asn_enc_rval_t encRetVal; - uint8_t ret = RFAILED; - uint8_t FillRicricSubscriptionRspret; + asn_enc_rval_t encRetVal; while(true) { @@ -1400,28 +1974,28 @@ uint8_t BuildAndSendRicSubscriptionRsp() DU_ALLOC(e2apRicMsg, sizeof(E2AP_PDU_t)); if(e2apRicMsg == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); - break; + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); + break; } + e2apRicMsg->present = E2AP_PDU_PR_successfulOutcome; DU_ALLOC(e2apRicMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); if(e2apRicMsg->choice.successfulOutcome == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation for RIC subscription Response failed"); - break; + DU_LOG("\nERROR --> E2AP : Memory allocation for RIC subscription Response failed"); + break; } e2apRicMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription; e2apRicMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; - e2apRicMsg->choice.successfulOutcome->value.present = \ - SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse; + e2apRicMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_RICsubscriptionResponse; + ricSubscriptionRsp = &e2apRicMsg->choice.successfulOutcome->value.choice.RICsubscriptionResponse; - FillRicricSubscriptionRspret = FillRicSubscriptionRsp(ricSubscriptionRsp); - if(FillRicricSubscriptionRspret != ROK) + if(fillRicSubscriptionRsp(ricSubscriptionRsp, subsRspInfo) != ROK) { - DU_LOG("\nERROR --> E2AP : Memory allocation for RICsubscriptionResponseIE failed"); - break; + DU_LOG("\nERROR --> E2AP : Memory allocation for RICsubscriptionResponseIE failed"); + break; } /* Prints the Msg formed */ @@ -1429,49 +2003,48 @@ uint8_t BuildAndSendRicSubscriptionRsp() memset(encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf,\ - encBuf); + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apRicMsg, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Response structure (at %s)\n",\ - encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); - break; + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Response 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 response \n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC subscription response \n"); #ifdef DEBUG_ASN_PRINT - for(int i=0; i< encBufSize; i++) - { - printf("%x",encBuf[i]); - } + 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 Response failed"); - break; + DU_LOG("\nERROR --> E2AP : Sending RIC Subscription Response failed"); + break; } ret = ROK; break; } - FreeRicSubscriptionRsp(e2apRicMsg); + FreeRicSubscriptionRsp(e2apRicMsg); return ret; } /****************************************************************** * - * @brief Deallocation of memory allocated bu aper decoder for e2 setup response + * @brief Deallocation of memory allocated by aper decoder for e2 setup response * * @details * * Function : freeAperDecodingOfE2SetupRsp * - * Functionality: Deallocation of memory allocated bu aper decoder for e2 + * Functionality: Deallocation of memory allocated by aper decoder for e2 * setup response * * @params[in] E2setupResponse_t *e2SetRspMsg; @@ -1548,13 +2121,16 @@ void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg) * RFAILED - failure * * ****************************************************************/ + uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx =0, transId=0; + uint8_t arrIdx =0, transId=0, idx=0; uint32_t recvBufLen; - E2setupResponse_t *e2SetRspMsg; - CmLList *node; - E2NodeComponent *e2NodeComponentInfo; + E2setupResponse_t *e2SetRspMsg=NULL; + CmLList *node=NULL; + E2NodeComponent *e2NodeComponentInfo=NULL; + E2nodeComponentConfigAdditionAck_List_t *e2NodeCfgAckList=NULL; + E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem=NULL; DU_LOG("\nINFO --> E2AP : E2 Setup Response received"); duCb.e2Status = TRUE; //Set E2 status as true @@ -1590,156 +2166,943 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) 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: - 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) + { + 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; + } + } + break; + } + + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in E2SetupRsp:%ld", + e2SetRspMsg->protocolIEs.list.array[arrIdx]->id); + break; + } + } + freeAperDecodingOfE2SetupRsp(e2SetRspMsg); + + if(duSendE2NodeConfigurationUpdate() != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 node config update"); + return RFAILED; + } + return ROK; +} + +/******************************************************************* + * + * @brief Free RIC Subscription Request + * + * @details + * + * Function : freeAperDecodingOfRicSubsReq + * + * Functionality : Free RIC Subscription Request + * + * @return void + * + ******************************************************************/ +void freeAperDecodingOfRicSubsReq(RICsubscriptionRequest_t *ricSubscriptionReq) +{ + uint8_t idx = 0; + uint8_t elementIdx = 0; + RICsubscriptionDetails_t *subsDetails = NULLP; + RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP; + + if(ricSubscriptionReq->protocolIEs.list.array) + { + for(idx=0; idx < ricSubscriptionReq->protocolIEs.list.count; idx++) + { + switch(ricSubscriptionReq->protocolIEs.list.array[idx]->id) + { + case ProtocolIE_IDE2_id_RICsubscriptionDetails: + { + subsDetails = &(ricSubscriptionReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails); + free(subsDetails->ricEventTriggerDefinition.buf); + + if(subsDetails->ricAction_ToBeSetup_List.list.array) + { + for(elementIdx = 0; elementIdx < subsDetails->ricAction_ToBeSetup_List.list.count; elementIdx++) + { + if(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]) + { + actionItem = (RICaction_ToBeSetup_ItemIEs_t *)subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]; + if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) + { + free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition->buf); + free(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition); + } + free(subsDetails->ricAction_ToBeSetup_List.list.array[elementIdx]); + } + } + free(subsDetails->ricAction_ToBeSetup_List.list.array); + } + break; + } + } + free(ricSubscriptionReq->protocolIEs.list.array[idx]); + } + free(ricSubscriptionReq->protocolIEs.list.array); + } +} + +/******************************************************************* + * + * @brief Free Event Trigger Definition + * + * @details + * + * Function : freeAperDecodingOfEventTriggerDef + * + * Functionality: Free Event Trigger Definition + * + * @params[in] E2SM-KPM Event Trigger Definition + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *eventTiggerDef) +{ + if(eventTiggerDef) + { + switch(eventTiggerDef->eventDefinition_formats.present) + { + case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING: + break; + + case E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_eventDefinition_Format1: + free(eventTiggerDef->eventDefinition_formats.choice.eventDefinition_Format1); + break; + } + } +} + +/******************************************************************* + * + * @brief Extract E2SM-KPM Event trigger definition + * + * @details + * + * Function : extractEventTriggerDef + * + * Functionality : This function : + * - Decodes E2SM-KPM Event Trigger Definition + * - Validates that even trigger style is supported by E2 node + * - Stores event trigger details in local DB + * + * @params[in] RAN Function Database structure + * RIC Subscription Info to be added to RAN function + * RIC Event Trigger Definition buffer received from RIC + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ + RICeventTriggerDefinition_t *ricEventTriggerDef, E2FailureCause *failureCause) +{ + uint8_t ret = RFAILED; + uint8_t eventIdx = 0; + asn_dec_rval_t rval ={0}; + E2SM_KPM_EventTriggerDefinition_t eventTiggerDef, *eventTiggerDefPtr = NULLP; + + /* Decoding E2SM-KPM Even Trigger Definition */ + eventTiggerDefPtr = &eventTiggerDef; + memset(eventTiggerDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t)); + + rval = aper_decode(0, &asn_DEF_E2SM_KPM_EventTriggerDefinition, (void **)&eventTiggerDefPtr, ricEventTriggerDef->buf,\ + ricEventTriggerDef->size, 0, 0); + if(rval.code == RC_FAIL || rval.code == RC_WMORE) + { + DU_LOG("\nERROR --> E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition"); + failureCause->causeType = E2_PROTOCOL; + failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE; + return RFAILED; + } + printf("\n"); + xer_fprint(stdout, &asn_DEF_E2SM_KPM_EventTriggerDefinition, eventTiggerDefPtr); + + /* Validating the received event trigger definition format */ + for(eventIdx = 0; eventIdx < ranFuncDb->numOfEventTriggerStyleSupported; eventIdx++) + { + if((eventTiggerDefPtr->eventDefinition_formats.present != \ + E2SM_KPM_EventTriggerDefinition__eventDefinition_formats_PR_NOTHING) && \ + (eventTiggerDefPtr->eventDefinition_formats.present == ranFuncDb->eventTriggerStyleList[eventIdx].formatType)) + { + ricSubscriptionInfo->eventTriggerDefinition.formatType = ranFuncDb->eventTriggerStyleList[eventIdx].formatType; + ricSubscriptionInfo->eventTriggerDefinition.choice.format1.reportingPeriod = \ + eventTiggerDefPtr->eventDefinition_formats.choice.eventDefinition_Format1->reportingPeriod; + + ret = ROK; + break; + } + } + + if(ret == RFAILED) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED; + } + /* Free E2SM_KPM_EventTriggerDefinition_t */ + freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr); + return ret; +} + +/******************************************************************* + * + * @brief Free RIC Action Definition + * + * @details + * + * Function : freeAperDecodingOfRicActionDefinition + * + * Functionality: Free RIC Action Definition + * + * @params[in] E2SM-KPM Action definition + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfRicActionDefinition(E2SM_KPM_ActionDefinition_t *actionDef) +{ + uint8_t elementIdx = 0; + E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP; + MeasurementInfoItem_t *measItem = NULLP; + + switch(actionDef->actionDefinition_formats.present) + { + case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1: + { + if(actionDef->actionDefinition_formats.choice.actionDefinition_Format1) + { + actionFormat1 = actionDef->actionDefinition_formats.choice.actionDefinition_Format1; + if(actionFormat1->measInfoList.list.array) + { + for(elementIdx = 0; elementIdx < actionFormat1->measInfoList.list.count; elementIdx++) + { + if(actionFormat1->measInfoList.list.array[elementIdx]) + { + measItem = actionFormat1->measInfoList.list.array[elementIdx]; + switch(measItem->measType.present) + { + case MeasurementType_PR_NOTHING: + break; + + case MeasurementType_PR_measName: + { + free(measItem->measType.choice.measName.buf); + break; + } + + case MeasurementType_PR_measID: + break; + } + free(measItem); + } + } + free(actionFormat1->measInfoList.list.array); + } + free(actionFormat1); + } + break; + } + case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format2: + case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format3: + case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format4: + case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format5: + default: + break; + } +} + +/******************************************************************* + * + * @brief Extract Measurement Info list from action definition + * + * @details + * + * Function : extractMeasInfoList + * + * Functionality : This function : + * - Traverses Measurement-to-be-subscribed list + * - Validates that each measurement in Measurement-to-be-subscribed + * list is supported in RAN-Function->Measurement-supported list. + * - If all measurements in an action is supported by RAN function, + * it is added to measurement-subscribed list in local DB + * + * @params[in] Measurement Info supported list by RAN function + * Measurement Info to be subscribed as requested by RIC + * Measurement Info finally subscribed + * Memory failure indicator + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoList_t *measInfoToBeSubscribedList, \ + CmLListCp *measInfoSubscribedList, bool *memFailure) +{ + uint8_t elementIdx = 0; + MeasurementInfoForAction *measInfoSupportedDb = NULLP; + MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP; + CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;; + MeasurementInfoItem_t *measItem = NULLP; + + /* Validate Measurement list is supported by E2 node. + * + * Traverse and compare the Measurement-Supported List in E2 + * node with Measurement-to-be-subscribed list received from RIC. + * If a match is found, add it to measurement-subscription list. + */ + for(elementIdx = 0; elementIdx < measInfoToBeSubscribedList->list.count; elementIdx++) + { + measInfoSubscribedDb = NULLP; + measToAddNode = NULLP; + measItem = measInfoToBeSubscribedList->list.array[elementIdx]; + + CM_LLIST_FIRST_NODE(measInfoSupportedList, supportedMeasNode); + while(supportedMeasNode) + { + measInfoSupportedDb = (MeasurementInfoForAction*)supportedMeasNode->node; + switch(measItem->measType.present) + { + case MeasurementType_PR_measName: + { + if(!strcmp(measInfoSupportedDb->measurementTypeName, (char *)measItem->measType.choice.measName.buf)) + { + DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo)); + } + break; + } + + case MeasurementType_PR_measID: + { + if(measInfoSupportedDb->measurementTypeId == measItem->measType.choice.measID) + { + DU_ALLOC(measInfoSubscribedDb, sizeof(MeasurementInfo)); + } + break; + } + + default: + { + DU_LOG("\nERROR -> DUAPP: Invalid Measurement-type identifier in \ + E2SM-KPM Action Definition Format"); + break; + } + } /* End of switch, for measurement type identifier */ + + /* If measurement type is supported, add to measurement-subscription list */ + if(measInfoSubscribedDb) + { + measInfoSubscribedDb->measurementTypeId = measInfoSupportedDb->measurementTypeId; + memcpy(measInfoSubscribedDb->measurementTypeName, measInfoSupportedDb->measurementTypeName, \ + strlen(measInfoSupportedDb->measurementTypeName)); + + DU_ALLOC(measToAddNode, sizeof(CmLList)); + if(measToAddNode) + { + measToAddNode->node = (PTR) measInfoSubscribedDb; + cmLListAdd2Tail(measInfoSubscribedList, measToAddNode); + + /* Break out of while loop if measurement info is found in measurement-supported list */ + break; + } + else + { + DU_FREE(measInfoSubscribedDb, sizeof(MeasurementInfo)); + measInfoSubscribedDb = NULLP; + *memFailure = true; + break; + } + } + + supportedMeasNode = supportedMeasNode->next; + + } /* End of while for traversing measurement-supported list in a report style */ + + /* If a measurement-to-be-subscribed is not found in measurement-supported list in this report style + * Then : + * Delete all entries from measurement-subscription list and + * 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)); + } + break; + } + + } /* End of for loop , traversing measurement-to-be-subscribed list */ + + /* If all measurement-to-be-subscribed was found in measurement-supported list and + * was added to measurement-subscription list successfully, return from here */ + if(measInfoToBeSubscribedList->list.count == measInfoSubscribedList->count) + return ROK; + + return RFAILED; +} + +/******************************************************************* + * + * @brief Extract E2SM-KPM Action definition + * + * @details + * + * Function : extractRicActionDef + * + * Functionality : This function : + * - Decodes E2SM-KPM Action Definition + * - Validates that action is supported by E2 node + * - Stores action details in local DB + * + * @params[in] RAN Function Database structure + * RIC subscription's Action definition to be added to + * RAN function + * RIC Action Definition buffer received from RIC + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\ + E2FailureCause *failureCause) +{ + bool memFailure = false; + uint8_t styleIdx = 0; + asn_dec_rval_t rval ={0}; + + E2SM_KPM_ActionDefinition_t actionDef, *actionDefPtr = NULLP; + E2SM_KPM_ActionDefinition_Format1_t *actionFormat1 = NULLP; + CmLListCp *measInfoSupportedList = NULLP; + CmLListCp *measInfoSubscribedList = NULLP; + + /* Decoding E2SM-KPM Action Definition */ + actionDefPtr = &actionDef; + memset(actionDefPtr, 0, sizeof(E2SM_KPM_EventTriggerDefinition_t)); + + rval = aper_decode(0, &asn_DEF_E2SM_KPM_ActionDefinition, (void **)&actionDefPtr, ricActionDef->buf,\ + ricActionDef->size, 0, 0); + if(rval.code == RC_FAIL || rval.code == RC_WMORE) + { + DU_LOG("\nERROR --> E2AP : ASN decode failed for E2SM-KPM Action Definition"); + failureCause->causeType = E2_PROTOCOL; + failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE; + return RFAILED; + } + printf("\n"); + xer_fprint(stdout, &asn_DEF_E2SM_KPM_ActionDefinition, actionDefPtr); + + + /* Validate if Report style to subscribe is supported by E2 Node */ + for(styleIdx= 0; styleIdx < ranFuncDb->numOfReportStyleSupported; styleIdx++) + { + /* Validate Report style type and report style format type is supported by E2 Node */ + if((ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType == actionDefPtr->ric_Style_Type) && + (ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType == actionDefPtr->actionDefinition_formats.present)) + { + /* Fetch Report stype type and format type */ + actionDefDb->styleType = actionDefPtr->ric_Style_Type; + actionDefDb->formatType = actionDefPtr->actionDefinition_formats.present; + + switch(actionDefPtr->actionDefinition_formats.present) + { + case E2SM_KPM_ActionDefinition__actionDefinition_formats_PR_actionDefinition_Format1: + { + actionFormat1 = actionDefPtr->actionDefinition_formats.choice.actionDefinition_Format1; + + /* Fetch granularity period */ + actionDefDb->choice.format1.granularityPeriod = actionFormat1->granulPeriod; + + /* Validate and add the Measurement to subscription list */ + measInfoSupportedList = &ranFuncDb->reportStyleList[styleIdx].measurementInfoList; + measInfoSubscribedList = &actionDefDb->choice.format1.measurementInfoList; + if(extractMeasInfoList(measInfoSupportedList, &actionFormat1->measInfoList, \ + measInfoSubscribedList, &memFailure) == ROK) + { + if(!memFailure) + { + /* Free E2SM_KPM_ActionDefinition_t */ + freeAperDecodingOfRicActionDefinition(actionDefPtr); + return ROK; + } + } + + break; /* End of E2SM-KPM Action definition format 1 case */ + } + + default : + { + DU_LOG("\nERROR -> DUAPP: Only E2SM-KPM Action Definition Format 1 is supported"); + break; + } + } /* End of switch for E2SM-KPM Action definition formats */ + } + + if(memFailure) + { + failureCause->causeType = E2_MISCELLANEOUS; + failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; + break; + } + } /* End of for loop, traversing Report-styles-supported list in E2 node */ + + /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */ + memset(actionDefDb, 0, sizeof(ActionDefinition)); + freeAperDecodingOfRicActionDefinition(actionDefPtr); + + if(failureCause->causeType == E2_NOTHING) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + } + return RFAILED; +} + +/******************************************************************* + * + * @brief Extract RIC Action to be setup + * + * @details + * + * Function : extractRicActionToBeSetup + * + * Functionality : This function : + * - Validates that each action-to-be-setup is supported by E2 node + * - Stores event trigger details in local DB + * + * @params[in] RAN Function Database structure + * RIC Subscription Info to be added to RAN function + * RIC Action To Be Setup List received from RIC + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ + RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause, PendingSubsRspInfo *subsRsp) +{ + uint8_t actionIdx = 0; + uint8_t ricActionId = 0; + RICaction_ToBeSetup_ItemIEs_t *actionItem = NULLP; + + if(actionList->list.array) + { + for(actionIdx = 0; actionIdx < actionList->list.count; actionIdx++) + { + actionItem =(RICaction_ToBeSetup_ItemIEs_t *)actionList->list.array[actionIdx]; + switch(actionItem->id) + { + case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item: + { + /* If Action type is REPORT and + * If RIC action definition's extraction and validation passes, + * Then : + * This action is added to action sequence list of subscription info */ + ricActionId = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; + + if(actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType == RICactionType_report) + { + ricSubscriptionInfo->actionSequence[ricActionId-1].id = ricActionId; + ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT; + + if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \ + actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK) + { + ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD; + ricSubscriptionInfo->numOfActions++; + break; + } + } + + /* In case of any failure, action is rejected + * Added to rejected-action-list in subscription response */ + memset(&ricSubscriptionInfo->actionSequence[ricActionId-1], 0, sizeof(ActionInfo)); + subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].id = ricActionId; + if(failureCause->causeType == E2_NOTHING) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + } + memcpy(&subsRsp->rejectedActionList[subsRsp->numOfRejectedActions].failureCause, \ + failureCause, sizeof(E2FailureCause)); + subsRsp->numOfRejectedActions++; + break; + } + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id); + break; + } + } + } + + /* If there is even 1 action that can be added, return ROK */ + if(ricSubscriptionInfo->numOfActions) + return ROK; + + if(failureCause->causeType == E2_NOTHING) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + } + return RFAILED; +} + +/****************************************************************** + * + * @brief Processes RIC Subscription Req sent by RIC + * + * @details + * + * Function : procRicSubscriptionRequest + * + * Functionality: Processes RIC Subscription Request from RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) +{ + uint8_t idx = 0; + uint8_t ret = ROK; + uint16_t ranFuncId = 0; + RicRequestId ricReqId; + CmLList *ricSubscriptionNode = NULLP; + RanFunction *ranFuncDb = NULLP; + RICsubscriptionRequest_t *ricSubsReq = NULLP; + RICsubscriptionDetails_t *subsDetails = NULLP; + RicSubscription *ricSubscriptionInfo = NULLP; + E2FailureCause failureCause; + + DU_LOG("\nINFO --> E2AP : RIC Subscription request received"); + + memset(&failureCause, 0, sizeof(E2FailureCause)); + memset(&ricReqId, 0, sizeof(RicRequestId)); + + ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; + for(idx=0; idxprotocolIEs.list.count; idx++) + { + if(ricSubsReq->protocolIEs.list.array[idx]) + { + switch(ricSubsReq->protocolIEs.list.array[idx]->id) + { + case ProtocolIE_IDE2_id_RICrequestID: + { + ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID; + + break; + } + + case ProtocolIE_IDE2_id_RANfunctionID: + { + ranFuncId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RANfunctionID; + + /* Validating RAN Function id */ + ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId); + + if(!ranFuncDb) + { + failureCause.causeType = E2_RIC_REQUEST; + failureCause.cause = E2_RAN_FUNCTION_ID_INVALID; + ret = RFAILED; + break; + } + + if(ranFuncDb->numPendingSubsRsp >= MAX_PENDING_SUBSCRIPTION_RSP) + { + failureCause.causeType = E2_RIC_REQUEST; + failureCause.cause = E2_FUNCTION_RESOURCE_LIMIT; + ret = RFAILED; + break; + } + + DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription)); + if(!ricSubscriptionInfo) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for ricSubscriptionInfo"); + failureCause.causeType = E2_MISCELLANEOUS; + failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; + ret = RFAILED; + break; + } + ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId; + ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId; + + memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo)); + memcpy(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].requestId, + &ricReqId, sizeof(RicRequestId)); + ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp].ranFuncId = ranFuncId; + break; + } + + case ProtocolIE_IDE2_id_RICsubscriptionDetails: + { + subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails; + + /* Decode, Validate and record Event Trigger Definition */ + if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \ + &failureCause) != ROK) + { + ret = RFAILED; + break; + } + + /* Decode, Validate and record RIC actions */ + if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \ + &failureCause, &ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp]) != ROK) + { + ret = RFAILED; + break; + } + } + break; + + default: + DU_LOG("\nERROR --> E2AP : Invalid IE received in RIC SubsReq:%ld", + ricSubsReq->protocolIEs.list.array[idx]->id); + break; + } - default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in E2SetupRsp:%ld", - e2SetRspMsg->protocolIEs.list.array[arrIdx]->id); + if(ret == RFAILED) break; } } - freeAperDecodingOfE2SetupRsp(e2SetRspMsg); - - node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD); - if(!node) + + freeAperDecodingOfRicSubsReq(ricSubsReq); + + if(ret == ROK) { - DU_LOG("\nERROR --> E2AP : Received e2NodeComponentInfo is null"); - return RFAILED; + /* Add RAN subcription detail to RAN function */ + DU_ALLOC(ricSubscriptionNode, sizeof(CmLList)); + if(ricSubscriptionNode) + { + ricSubscriptionNode->node = (PTR) ricSubscriptionInfo; + cmLListAdd2Tail(&ranFuncDb->subscriptionList, ricSubscriptionNode); + } + + ranFuncDb->numPendingSubsRsp++; + +#ifdef KPI_CALCULATION + /* Send statistics request to other DU entities */ + BuildAndSendStatsReq(ranFuncId, ricSubscriptionInfo); +#endif + + /* TODO : Trigger RIC Indication once statistics indication is + * received from MAC . + * TBD in future gerrit */ + //BuildAndSendRicIndication(ricSubscriptionInfo); } else { - e2NodeComponentInfo = (E2NodeComponent*)node->node; - 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)); + DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription)); + + if(ranFuncDb) + { + memset(&ranFuncDb->pendingSubsRspInfo[ranFuncDb->numPendingSubsRsp], 0, sizeof(PendingSubsRspInfo)); + } + + /* Send RIC Subcription Failure */ + BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause); } - BuildAndSendE2NodeConfigUpdate(); - return ROK; + return ret; } /****************************************************************** * - * @brief Processes RIC Subscription Req sent by RIC + * @brief Free RIC Subscription Failure * * @details * - * Function : procRicSubsReq + * Function : FreeRicSubscriptionFailure * - * Functionality: Processes E2 Setup Response sent by CU + * Functionality: Free RIC Subscription Failure * - * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @params[in] E2AP PDU + * @return void + * + * ****************************************************************/ +void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t elemIdx = 0; + RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP; + + if(e2apMsg) + { + if(e2apMsg->choice.unsuccessfulOutcome) + { + ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure; + if(ricSubscriptionFailure->protocolIEs.list.array) + { + for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++) + { + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t)); + } + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size); + } + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + } + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/****************************************************************** + * + * @brief Fill and Send RIC Subscription Failure to RIC + * + * @details + * + * Function : BuildAndSendRicSubscriptionFailure + * + * Functionality: Fill and Send RIC Subscription Failure to RIC + * + * @params[in] RIC Request ID + * RAN Function ID + * Cause of Failure * @return ROK - success * RFAILED - failure * * ****************************************************************/ - -uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) +uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause) { - uint8_t idx; - uint8_t ied; - uint8_t ret = ROK; - CmLList *ricSubscriptionNode = NULLP; - RICsubscriptionRequest_t *ricSubsReq; - RicSubscription *ricSubscriptionInfo; - RICaction_ToBeSetup_ItemIEs_t *actionItem; - - DU_LOG("\nINFO --> E2AP : RIC Subscription request received"); - ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; + uint8_t ret = RFAILED; + uint8_t elementCnt = 0, elemIdx = 0; + E2AP_PDU_t *e2apMsg = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP; + RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP; - for(idx=0; idxprotocolIEs.list.count; idx++) + while(true) { - if(ricSubsReq->protocolIEs.list.array[idx]) + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Failure\n"); + + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) { - switch(ricSubsReq->protocolIEs.list.array[idx]->id) + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); + break; + } + + e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + if(e2apMsg->choice.unsuccessfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); + break; + } + e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription; + e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure; + + ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure; + + elementCnt = 3; + ricSubscriptionFailure->protocolIEs.list.count = elementCnt; + ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *); + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size); + if(!ricSubscriptionFailure->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); + break; + } + + for(elemIdx = 0; elemIdx < elementCnt; elemIdx++) + { + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t)); + if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx]) { - case ProtocolIE_IDE2_id_RICrequestID: - { - /* TODO :- ricSubscriptionInfo details will be stored based on - * RAN function id, so first we need to search RAN function and then add - * subscription details to that ran function */ - DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription)); - if(!ricSubscriptionInfo) - { - DU_LOG("\nERROR --> E2AP : Memory allocation failed for ricSubscriptionInfo"); - return RFAILED; - } - ricSubscriptionInfo->requestId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID; - ricSubscriptionInfo->requestId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID; - DU_ALLOC(ricSubscriptionNode, sizeof(CmLList)); - if(ricSubscriptionNode) - { - ricSubscriptionNode->node = (PTR) ricSubscriptionInfo; - cmLListAdd2Tail(&duCb.e2apDb.ranFunction[0].subscriptionList,ricSubscriptionNode); - } - break; - } - case ProtocolIE_IDE2_id_RANfunctionID: - { - duCb.e2apDb.ranFunction[0].id = ricSubsReq->protocolIEs.list.array[idx]-> \ - value.choice.RANfunctionID; - break; - } - case ProtocolIE_IDE2_id_RICsubscriptionDetails: - { - if(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ - list.array) - { - actionItem =(RICaction_ToBeSetup_ItemIEs_t *)ricSubsReq->protocolIEs.list\ - .array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List\ - .list.array[0]; + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \ + __func__, __LINE__, elemIdx); + break; + } + } + if(elemIdx < elementCnt) + break; - for(ied = 0; ied < ricSubsReq->protocolIEs.list.array[idx]->value.choice.\ - RICsubscriptionDetails.ricAction_ToBeSetup_List.list.count; ied++) - { - switch(actionItem->id) - { - case ProtocolIE_IDE2_id_RICaction_ToBeSetup_Item: - { - ricSubscriptionInfo->actionSequence[0].id = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionID; - ricSubscriptionInfo->actionSequence[0].type = actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionType; - break; - } - default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in RicSetupLst:%ld",actionItem->id); - break; - } - free(actionItem); - } - free(ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails.ricAction_ToBeSetup_List.\ - list.array); - -#ifdef KPI_CALCULATION - /* This is a dummy trigger for statistics request. It will - * be removed in next gerrit and actual statistics request - * will be sent when RIC subscription request is received - * from RIC */ - ricSubscriptionInfo->actionSequence[0].definition.styleType = 1; - BuildAndSendStatsReq(ricSubscriptionInfo->actionSequence[0].definition); -#endif - } - break; - } + elemIdx = 0; + + /* RIC Request ID */ + ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++]; + ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsFailIe->criticality = CriticalityE2_reject; + ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID; + ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId; + ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId; + + /* RAN Function ID */ + ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++]; + ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsFailIe->criticality = CriticalityE2_reject; + ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID; + ricSubsFailIe->value.choice.RANfunctionID = ranFuncId; + + /* Cause */ + ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++]; + ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2; + ricSubsFailIe->criticality = CriticalityE2_reject; + ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2; + fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause); - default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in RIC SubsReq:%ld", - ricSubsReq->protocolIEs.list.array[idx]->id); - 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 Failure Message (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); } - free(ricSubsReq->protocolIEs.list.array[idx]); +#endif } - } - free(ricSubsReq->protocolIEs.list.array); - ret = BuildAndSendRicSubscriptionRsp(); - { - BuildAndSendRicIndication(ricSubscriptionInfo); - } + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nINFO --> E2AP : Sending RIC Subscription Failure"); + + } + ret = ROK; + break; + } + FreeRicSubscriptionFailure(e2apMsg); return ret; } @@ -1759,63 +3122,63 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) ******************************************************************/ void FreeRicIndication(E2AP_PDU_t *e2apMsg) { - uint8_t idx=0; + uint8_t idx = 0; RICindication_t *ricIndicationMsg= NULLP; - if(e2apMsg != NULLP) { if(e2apMsg->choice.initiatingMessage != NULLP) { - ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication; - if(ricIndicationMsg!= NULLP) - { - if(ricIndicationMsg->protocolIEs.list.array != NULLP) - { - for(idx=0; idxprotocolIEs.list.count; idx++) - { - if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP) - { - 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; - - case ProtocolIE_IDE2_id_RICindicationHeader: - { - DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\ - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size); - break; - } - case ProtocolIE_IDE2_id_RICindicationMessage: - { - DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\ - ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size); - break; - } - default: - break; - } - DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t)); - } - } - DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size); - } - } - DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + ricIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.RICindication; + if(ricIndicationMsg!= NULLP) + { + if(ricIndicationMsg->protocolIEs.list.array != NULLP) + { + for(idx=0; idxprotocolIEs.list.count; idx++) + { + if(ricIndicationMsg->protocolIEs.list.array[idx] != NULLP) + { + 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; + + case ProtocolIE_IDE2_id_RICindicationHeader: + { + DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.buf,\ + ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationHeader.size); + break; + } + case ProtocolIE_IDE2_id_RICindicationMessage: + { + DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.buf,\ + ricIndicationMsg->protocolIEs.list.array[idx]->value.choice.RICindicationMessage.size); + break; + } + default: + break; + } + DU_FREE(ricIndicationMsg->protocolIEs.list.array[idx],sizeof(RICindication_IEs_t)); + } + } + DU_FREE(ricIndicationMsg->protocolIEs.list.array,ricIndicationMsg->protocolIEs.list.size); + } + } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); } DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); } } + /******************************************************************* * * brief Fill the RicIndication Message @@ -2023,6 +3386,60 @@ uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo) return ret; } +/******************************************************************* + * + * @brief free e2 node component configuration req and rsp + * + * @details + * + * Function : freeE2NodeComponentConfiguration + * + * Functionality: + * - free e2 node component configuration req and rsp + * + * @params[in] E2nodeComponentConfiguration_t *e2nodeComponentConfiguration + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void freeE2NodeComponentConfiguration(E2nodeComponentConfiguration_t *e2nodeComponentConfiguration) +{ + /* Free E2 Node Component Request Part */ + DU_FREE(e2nodeComponentConfiguration->e2nodeComponentRequestPart.buf, e2nodeComponentConfiguration->e2nodeComponentRequestPart.size); + + /* Free E2 Node Component Response Part */ + DU_FREE(e2nodeComponentConfiguration->e2nodeComponentResponsePart.buf, e2nodeComponentConfiguration->e2nodeComponentResponsePart.size); + +} + +/******************************************************************* + * + * @brief free e2 node component component identifier + * + * @details + * + * Function : freeE2NodeComponentIdentifier + * + * Functionality: + * - free e2 node component component identifier + * + * @params[in] E2nodeComponentID_t *componentID + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void freeE2NodeComponentIdentifier(E2nodeComponentID_t *componentID) +{ + 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)); + } + +} + /******************************************************************* * * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg @@ -2039,10 +3456,17 @@ uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo) * RFAILED - failure * * ****************************************************************/ + void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx =0; - E2nodeConfigurationUpdate_t *e2NodeConfigUpdate; + 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; if(e2apMsg != NULLP) { @@ -2053,7 +3477,70 @@ void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg) { for(arrIdx = 0; arrIdx < e2NodeConfigUpdate->protocolIEs.list.count; arrIdx++) { - DU_FREE(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_IEs_t)); + if(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]) + { + + switch(e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + break; + + 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]; + + 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); } @@ -2080,13 +3567,13 @@ void FreeE2NodeConfigUpdate(E2AP_PDU_t *e2apMsg) * * ****************************************************************/ -uint8_t BuildAndSendE2NodeConfigUpdate() +uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *e2NodeList) { - uint8_t arrIdx = 0,elementCnt = 1; - uint8_t ret = ROK; - E2AP_PDU_t *e2apMsg = NULLP; - E2nodeConfigurationUpdate_t *e2NodeConfigUpdate = 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 E2 Node config update\n"); do @@ -2097,25 +3584,31 @@ uint8_t BuildAndSendE2NodeConfigUpdate() 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"); - DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); - return RFAILED; + 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*); - /* Initialize the Ric Indication members */ - DU_ALLOC(e2NodeConfigUpdate->protocolIEs.list.array, \ - e2NodeConfigUpdate->protocolIEs.list.size); + 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"); @@ -2132,22 +3625,67 @@ uint8_t BuildAndSendE2NodeConfigUpdate() 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; - e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID; + transId = assignTransactionId(); + e2NodeConfigUpdate->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId; + + 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) + { + 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) + { + + 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) + { + DU_LOG("\nERROR --> E2AP : Failed to remove the E2 node configuration"); + 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); + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { DU_LOG("\nERROR --> E2AP : Could not encode E2nodeConfigurationUpdate structure (at %s)\n",\ @@ -2167,9 +3705,13 @@ uint8_t BuildAndSendE2NodeConfigUpdate() if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize)) { DU_LOG("\nERROR --> E2AP : Sending E2 node config update failed"); - return RFAILED; + 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); @@ -2233,7 +3775,7 @@ void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg) * RFAILED - failure * * ****************************************************************/ -uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause) +uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause) { uint8_t ieIdx = 0, elementCnt = 0, transId = 0; uint8_t ret = RFAILED; @@ -2303,30 +3845,7 @@ uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause 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; - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present = failureType; - switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present) - { - case CauseE2_PR_NOTHING: - break; - case CauseE2_PR_ricRequest: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest = failureCause; - break; - case CauseE2_PR_ricService: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService = failureCause; - break; - case CauseE2_PR_e2Node: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node = failureCause; - break; - case CauseE2_PR_transport: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport = failureCause; - break; - case CauseE2_PR_protocol: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol = failureCause; - break; - case CauseE2_PR_misc: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc = failureCause; - break; - } + fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause); /* Prints the Msg formed */ xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); @@ -2476,13 +3995,13 @@ uint8_t procResetResponse(E2AP_PDU_t *e2apMsg) /****************************************************************** * - * @brief Deallocation of memory allocated bu aper decoder for e2 setup Failure + * @brief Deallocation of memory allocated by aper decoder for e2 setup Failure * * @details * * Function : freeAperDecodingOfE2SetupFailure * - * Functionality: Deallocation of memory allocated bu aper decoder for e2 + * Functionality: Deallocation of memory allocated by aper decoder for e2 * setup Failure * * @params[in] E2setupFailure_t *e2SetupFailure; @@ -2552,7 +4071,7 @@ void procE2SetupFailure(E2AP_PDU_t *e2apMsg) } case ProtocolIE_IDE2_id_TimeToWaitE2: { - timerValue = covertE2WaitTimerEnumToValue(e2SetupFailure->protocolIEs.list.array[arrIdx]->value.choice.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); @@ -2571,13 +4090,13 @@ void procE2SetupFailure(E2AP_PDU_t *e2apMsg) } /****************************************************************** * - * @brief Deallocation of memory allocated bu aper decoder for RIC service Query + * @brief Deallocation of memory allocated by aper decoder for RIC service Query * * @details * * Function : freeAperDecodingOfRicServiceQuery * - * Functionality: Deallocation of memory allocated bu aper decoder for RIC + * Functionality: Deallocation of memory allocated by aper decoder for RIC * service Query * * @params[in] RICserviceQuery_t *ricServiceQuery; @@ -2945,6 +4464,7 @@ uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate) } 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; @@ -3060,7 +4580,306 @@ void procRicServiceQuery(E2AP_PDU_t *e2apMsg) 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 Handles received E2AP message and sends back response @@ -3140,6 +4959,16 @@ void E2APMsgHdlr(Buffer *mBuf) procE2SetupFailure(e2apMsg); break; } + case UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure: + { + procE2NodeConfigUpdateFailure(e2apMsg); + break; + } + case UnsuccessfulOutcomeE2__value_PR_RICserviceUpdateFailure: + { + procRicServiceUpdateFailure(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome [%d]",\ @@ -3171,6 +5000,13 @@ void E2APMsgHdlr(Buffer *mBuf) procResetResponse(e2apMsg); break; } + case SuccessfulOutcomeE2__value_PR_RICserviceUpdateAcknowledge: + { + procRicServiceUpdateAck(e2apMsg); + break; + } + + default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome [%d]",\ @@ -3188,7 +5024,7 @@ void E2APMsgHdlr(Buffer *mBuf) { case InitiatingMessageE2__value_PR_RICsubscriptionRequest: { - procRicSubsReq(e2apMsg); + procRicSubscriptionRequest(e2apMsg); break; } case InitiatingMessageE2__value_PR_RICserviceQuery: @@ -3196,6 +5032,11 @@ void E2APMsgHdlr(Buffer *mBuf) procRicServiceQuery(e2apMsg); break; } + case InitiatingMessageE2__value_PR_ErrorIndicationE2: + { + DU_LOG("\nINFO --> E2AP : Error indication received"); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\