From 3740878d9d4bf9ab3d2639f0495b77f3f45bd3cb Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Wed, 30 Aug 2023 12:29:58 +0530 Subject: [PATCH 1/1] [Epic-ID: ODUHIGH-516][Task-ID: 527] Implementation of E2 Node Configuration Update Procedure Change-Id: Ia47f6f4578c6c8c7ee359f866cf9f7317cc6632c Signed-off-by: pborla --- src/du_app/du_cfg.c | 1 + src/du_app/du_e2_conversions.c | 49 ++- src/du_app/du_e2_conversions.h | 3 +- src/du_app/du_e2ap_mgr.c | 132 ++++++ src/du_app/du_e2ap_mgr.h | 33 +- src/du_app/du_e2ap_msg_hdl.c | 859 +++++++++++++++++++++++++++++++++------- src/du_app/du_e2ap_msg_hdl.h | 3 +- src/du_app/du_f1ap_msg_hdl.c | 115 ++---- src/du_app/du_tmr.c | 28 ++ src/ric_stub/ric_e2ap_msg_hdl.c | 377 ++++++++++-------- src/ric_stub/ric_e2ap_msg_hdl.h | 2 + 11 files changed, 1215 insertions(+), 387 deletions(-) diff --git a/src/du_app/du_cfg.c b/src/du_app/du_cfg.c index 849f5ec86..762a5c296 100644 --- a/src/du_app/du_cfg.c +++ b/src/du_app/du_cfg.c @@ -1167,6 +1167,7 @@ uint8_t duReadCfg() /* Initialize the timer blocks */ cmInitTimers(&(duCb.e2apDb.e2TimersInfo.e2Timers.e2SetupTimer), 1); cmInitTimers(&(duCb.e2apDb.e2TimersInfo.e2Timers.ricServiceUpdateTimer.timer), 1); + cmInitTimers(&(duCb.e2apDb.e2TimersInfo.e2Timers.e2NodeConfigUpdate.timer), 1); /* Initialzie the timer queue */ memset(&(duCb.duTimersInfo.tmrTq), 0, sizeof(CmTqType) * DU_TQ_SIZE); diff --git a/src/du_app/du_e2_conversions.c b/src/du_app/du_e2_conversions.c index d0bbb5bff..497223c47 100644 --- a/src/du_app/du_e2_conversions.c +++ b/src/du_app/du_e2_conversions.c @@ -23,6 +23,7 @@ #include "TimeToWaitE2.h" #include "du_app_mac_inf.h" #include "du_e2ap_mgr.h" +#include "E2nodeComponentInterfaceType.h" /************************************************************************ * @@ -30,7 +31,7 @@ * * @details * - * Function : covertE2WaitTimerEnumToValue + * Function : convertE2WaitTimerEnumToValue * * Functionality: Converts enum values into actual value of E2 wait timer * @@ -39,7 +40,7 @@ * * **********************************************************************/ -uint8_t covertE2WaitTimerEnumToValue(uint8_t timerToWait) +uint8_t convertE2WaitTimerEnumToValue(uint8_t timerToWait) { switch(timerToWait) { @@ -110,6 +111,50 @@ void convertDuCauseToE2Cause(CauseOfResult l2Cause, E2FailureCause *failureCause } } +/************************************************************************ + * + * @brief Converts InterfaceType into E2nodeComponentInterfaceType value + * + * @details + * + * Function : convertInterfaceToE2ComponentInterfaceType + * + * Functionality: Convert InterfaceType into E2nodeComponentInterfaceType + * value + * + * @params[in] Actual value of interface + * @return Enum value of e2 interface + * + * **********************************************************************/ + +uint8_t convertInterfaceToE2ComponentInterfaceType(uint8_t interface) +{ + switch(interface) + { + case NG: + return E2nodeComponentInterfaceType_ng; + + case XN: + return E2nodeComponentInterfaceType_xn; + + case E1: + return E2nodeComponentInterfaceType_e1; + + case F1: + return E2nodeComponentInterfaceType_f1; + + case W1: + return E2nodeComponentInterfaceType_w1; + + case S1: + return E2nodeComponentInterfaceType_s1; + + case X2: + return E2nodeComponentInterfaceType_x2; + } + return RFAILED; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_e2_conversions.h b/src/du_app/du_e2_conversions.h index 3600d15d5..329b4fa28 100644 --- a/src/du_app/du_e2_conversions.h +++ b/src/du_app/du_e2_conversions.h @@ -18,8 +18,9 @@ /* This file contains definitions of E2 conversion functions */ -uint8_t covertE2WaitTimerEnumToValue(uint8_t timerToWait); void convertDuCauseToE2Cause(CauseOfResult l2Cause, E2FailureCause *failureCause); +uint8_t convertInterfaceToE2ComponentInterfaceType(uint8_t interface); +uint8_t convertE2WaitTimerEnumToValue(uint8_t timerToWait); /********************************************************************** End of file diff --git a/src/du_app/du_e2ap_mgr.c b/src/du_app/du_e2ap_mgr.c index 57d3cbb49..58f5845e7 100644 --- a/src/du_app/du_e2ap_mgr.c +++ b/src/du_app/du_e2ap_mgr.c @@ -656,6 +656,138 @@ void e2ProcStatsInd(MacStatsInd *statsInd) } } +/****************************************************************** + * + * @brief Search E2 node component with the help of action type + * + * @details + * + * Function : fetchE2NodeComponentInfo + * + * Functionality: Search E2 node component with the help of action type + * + * @params[in] + * Type of interface + * Component action type + * Pointer to E2 component node to be searched + * @return CmLList + * + * ****************************************************************/ + +E2NodeComponent *fetchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType, CmLList **e2ComponentNode) +{ + E2NodeComponent *e2NodeComponentInfo=NULLP; + + if(duCb.e2apDb.e2NodeComponentList.count) + { + CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, *e2ComponentNode); + while(*e2ComponentNode) + { + e2NodeComponentInfo = (E2NodeComponent*)((*e2ComponentNode)->node); + if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentActionType == componentActionType)) + { + + break; + } + + *e2ComponentNode = (*e2ComponentNode)->next; + e2NodeComponentInfo = NULLP; + } + } + return e2NodeComponentInfo; +} + +/******************************************************************* + * + * @brief add or modify E2NodeComponent list + * + * @details + * + * Function : addOrModifyE2NodeComponent + * + * Functionality: add or modify E2NodeComponent list + * + * @parameter + * Type of interface + * Component action type + * boolean variable to check req or rsp msg type + * Size of buffer which needs to be store + * buffer string which needs to be store + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +uint8_t addOrModifyE2NodeComponent(InterfaceType interfaceType, uint8_t action, bool reqPart, uint8_t bufSize, char *bufString) +{ + E2NodeComponent *e2NodeComponentInfo= NULL; + CmLList *node = NULLP; + + if(reqPart == true) + { + DU_ALLOC(e2NodeComponentInfo, sizeof(E2NodeComponent)); + if(!e2NodeComponentInfo) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for e2NodeComponentInfo in %s",__func__); + return RFAILED; + } + e2NodeComponentInfo->interfaceType =interfaceType; + e2NodeComponentInfo->componentId=duCfgParam.duId; + e2NodeComponentInfo->componentActionType = action; + e2NodeComponentInfo->reqBufSize = bufSize; + + DU_ALLOC(e2NodeComponentInfo->componentRequestPart, bufSize); + if(e2NodeComponentInfo->componentRequestPart == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for componentRequestPart"); + DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent)); + return RFAILED; + } + memcpy(e2NodeComponentInfo->componentRequestPart, bufString, e2NodeComponentInfo->reqBufSize); + DU_ALLOC(node, sizeof(CmLList)); + if(node) + { + node->node = (PTR) e2NodeComponentInfo; + cmLListAdd2Tail(&duCb.e2apDb.e2NodeComponentList, node); + } + else + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for e2NodeComponentList node"); + DU_FREE(e2NodeComponentInfo->componentRequestPart, bufSize); + DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent)); + return RFAILED; + } + } + else + { + if(duCb.e2apDb.e2NodeComponentList.count) + { + e2NodeComponentInfo = fetchE2NodeComponentInfo(interfaceType, action, &node); + if(e2NodeComponentInfo->componentRequestPart== NULLP) + { + DU_LOG("\nERROR --> E2AP : E2 node Component request part is not present"); + return RFAILED; + } + + e2NodeComponentInfo->rspBufSize = bufSize; + DU_ALLOC(e2NodeComponentInfo->componentResponsePart, bufSize); + if(e2NodeComponentInfo->componentResponsePart == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed to store the encoding of rsp"); + return RFAILED; + } + memcpy(e2NodeComponentInfo->componentResponsePart, bufString, e2NodeComponentInfo->rspBufSize); + return ROK; + } + else + { + DU_LOG("\nERROR --> E2AP : Unable to find the node"); + return RFAILED; + } + } + return ROK; +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_e2ap_mgr.h b/src/du_app/du_e2ap_mgr.h index e1e6dea71..e1195d5ef 100644 --- a/src/du_app/du_e2ap_mgr.h +++ b/src/du_app/du_e2ap_mgr.h @@ -18,10 +18,12 @@ /* This file contains all E2AP message handler related functionality */ #define MAX_E2_SETUP_TMR 1 +#define MAX_E2_NODE_CONFIG_UPDATE_TMR 1 #define MAX_RIC_SERVICE_UPDATE_TMR 1 #define EVENT_E2_SETUP_TMR 1 #define EVENT_RIC_SERVICE_UPDATE_TMR 2 +#define EVENT_E2_NODE_CONFIG_UPDATE_TMR 3 #define MAX_NUM_TRANSACTION 256 /* As per, O-RAN WG3 E2AP v3.0, section 9.2.33 */ #define MAX_RAN_FUNCTION 256 /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.1.2.2 : maxofRANfunctionID */ @@ -67,9 +69,11 @@ typedef enum typedef enum { E2_NODE_COMPONENT_ADD, - E2_NODE_COMPONENT_UPDATE + E2_NODE_COMPONENT_UPDATE, + E2_NODE_COMPONENT_DEL }ComponentActionType; + /* O-RAN.WG3.E2AP-R003-v03.00 : Section 9.2.30 */ typedef enum { @@ -214,10 +218,33 @@ typedef struct CmTimer timer; }RicServiceUpdateTimer; +typedef struct e2NodeCfgItem +{ + InterfaceType interface; + ComponentActionType actionType; +}E2NodeConfigItem; + +typedef struct e2NodeCfgList +{ + uint16_t addE2NodeCount; + E2NodeConfigItem addE2Node[MAX_E2_NODE_COMPONENT]; + uint16_t updateE2NodeCount; + E2NodeConfigItem updateE2Node[MAX_E2_NODE_COMPONENT]; + uint16_t removeE2NodeCount; + E2NodeConfigItem removeE2Node[MAX_E2_NODE_COMPONENT]; +}E2NodeConfigList; + +typedef struct +{ + E2NodeConfigList configList; + CmTimer timer; +}E2NodeConfigUpdateTimer; + typedef struct e2Timer { CmTimer e2SetupTimer; - RicServiceUpdateTimer ricServiceUpdateTimer; + RicServiceUpdateTimer ricServiceUpdateTimer; + E2NodeConfigUpdateTimer e2NodeConfigUpdate; /* More timers can be added to this structure in future */ }E2Timer; @@ -461,6 +488,8 @@ void e2ProcStatsInd(MacStatsInd *statsInd); uint8_t ResetE2Request(E2ProcedureDirection dir, E2FailureCause resetCause); uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize); +E2NodeComponent *fetchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType, CmLList **e2ComponentNode); +uint8_t addOrModifyE2NodeComponent(InterfaceType interfaceType, uint8_t action, bool reqPart, uint8_t bufSize, char *bufString); /********************************************************************** End of file diff --git a/src/du_app/du_e2ap_msg_hdl.c b/src/du_app/du_e2ap_msg_hdl.c index 686dc8ff6..8838d716b 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -52,6 +52,104 @@ #include "MeasurementInfoItem.h" #include "RANfunctionsIDcause-List.h" +/****************************************************************** + * + * @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); +} + /******************************************************************* * * @brief Fill E2 Failure Cause @@ -186,39 +284,143 @@ uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId) return ret; } -/****************************************************************** +/******************************************************************* * - * @brief Search E2 node component with the help of action type + * @brief fill the E2 node config information * * @details * - * Function : searchE2NodeComponentInfo + * Function : fillE2NodeConfig * - * Functionality: Search E2 node component with the help of action type + * Functionality: fill E2 node config information * - * @params[in] uint8_t componentActionType - * @return CmLList + * @params[in] + * Pointer to e2NodeCfg to be filled + * E2 Node Component information + * Type of configuration + * @return ROK - success + * RFAILED - failure * - * ****************************************************************/ + ******************************************************************/ -CmLList *searchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componentActionType) +uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType) { - E2NodeComponent *e2NodeComponentInfo; - CmLList *node; + 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) + { + 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; + } + } + /* 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) + { + /* 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 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); + } + + if(configType == CONFIG_DEL) + { + /* 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; + } - if(duCb.e2apDb.e2NodeComponentList.count) + /* E2 Node Component Request Part */ + if(e2NodeComponentInfo->componentRequestPart) { - CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); - while(node) + configuration->e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ; + DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\ + configuration->e2nodeComponentRequestPart.size); + if(configuration->e2nodeComponentRequestPart.buf == NULLP) { - e2NodeComponentInfo = (E2NodeComponent*)node->node; - if((e2NodeComponentInfo->interfaceType == interfaceType) && (e2NodeComponentInfo->componentActionType == componentActionType)) - break; - else - node = node->next; + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); + return RFAILED; + } + + memcpy(configuration->e2nodeComponentRequestPart.buf,\ + e2NodeComponentInfo->componentRequestPart, configuration->\ + e2nodeComponentRequestPart.size); + } + else + { + DU_LOG("\nERROR --> E2AP: componentRequestPart is null "); + return RFAILED; + } + + /* E2 Node Component Response Part */ + if(e2NodeComponentInfo->componentResponsePart) + { + 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 in function %s at line %d",__func__,__LINE__); + return RFAILED; } + memcpy(configuration->e2nodeComponentResponsePart.buf, e2NodeComponentInfo->componentResponsePart, configuration->\ + e2nodeComponentResponsePart.size); + } + else + { + DU_LOG("\nERROR --> E2AP: componentResponsePart is null"); + return RFAILED; } - return node; + + return ROK; } /******************************************************************* @@ -231,21 +433,36 @@ CmLList *searchE2NodeComponentInfo(InterfaceType interfaceType, uint8_t componen * * Functionality: Building E2 node config addition list * - * @params[in] E2nodeComponentConfigAddition_List_t *e2NodeAddList + * @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 BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList, uint8_t procedureCode, uint16_t count, E2NodeConfigItem *e2NodeList) { uint8_t arrIdx = 0; - CmLList *node; - E2NodeComponent *e2NodeComponentInfo; - E2nodeComponentConfigAddition_ItemIEs_t *e2NodeAddItemIe; - E2nodeComponentConfigAddition_Item_t *e2NodeAddItem; + 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.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) @@ -262,93 +479,190 @@ uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAdd 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; + } } - - node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD); - if(!node) + 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 --> E2AP : Received e2NodeComponentInfo is null"); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); return RFAILED; } - 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) + for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++) { - e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ; - DU_ALLOC(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\ - e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.size); - if(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf == NULLP) + DU_ALLOC(e2NodeUpdateList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdate_ItemIEs_t)); + if(e2NodeUpdateList->list.array[arrIdx] == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); return RFAILED; } - memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentRequestPart.buf,\ - e2NodeComponentInfo->componentRequestPart, e2NodeAddItem->e2nodeComponentConfiguration.\ - e2nodeComponentRequestPart.size); - } - else - { - DU_LOG("\nERROR --> E2AP: componentRequestPart is null "); - 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; - /* 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) + if(fillE2NodeConfig((PTR)e2NodeUpdateItem, e2NodeComponentInfo, CONFIG_MOD) != ROK) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + DU_LOG("\nERROR --> E2AP : Failed to fill the E2 node configuration"); return RFAILED; } - memcpy(e2NodeAddItem->e2nodeComponentConfiguration.e2nodeComponentResponsePart.buf, \ - e2NodeComponentInfo->componentResponsePart, e2NodeAddItem->e2nodeComponentConfiguration.\ - e2nodeComponentResponsePart.size); + } - else + 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: componentResponsePart is null"); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__); 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) - { - 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< e2NodeRemoveList->list.count; arrIdx++) { - DU_LOG("\nERROR -->list. E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); - return RFAILED; + 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; + } + } - e2NodeAddItem->e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[arrIdx] = e2NodeComponentInfo->componentId; return ROK; - } - /******************************************************************* * * @brief deallocation of E2SM_KPM_RANfunction_Description_t @@ -1109,7 +1423,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; @@ -1528,13 +1842,13 @@ uint8_t BuildAndSendRicSubscriptionRsp(PendingSubsRspInfo *subsRspInfo) /****************************************************************** * - * @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; @@ -1611,13 +1925,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 @@ -1656,7 +1973,37 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) } 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", @@ -1665,24 +2012,12 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) } } freeAperDecodingOfE2SetupRsp(e2SetRspMsg); - - node = searchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD); - if(!node) + + if(duSendE2NodeConfigurationUpdate() != ROK) { - DU_LOG("\nERROR --> E2AP : Received e2NodeComponentInfo is null"); + DU_LOG("\nERROR --> E2AP : Failed to send E2 node config update"); return RFAILED; } - 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)); - } - - BuildAndSendE2NodeConfigUpdate(); return ROK; } @@ -2855,6 +3190,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 @@ -2871,10 +3260,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) { @@ -2885,7 +3281,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); } @@ -2912,13 +3371,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 @@ -2929,25 +3388,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"); @@ -2964,22 +3429,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",\ @@ -2999,9 +3509,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); @@ -3285,13 +3799,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; @@ -3361,7 +3875,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); @@ -3380,13 +3894,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; @@ -4083,7 +4597,7 @@ void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg) } case ProtocolIE_IDE2_id_TimeToWaitE2: { - timerValue = covertE2WaitTimerEnumToValue(ricServiceFailure->protocolIEs.list.array[arrIdx]->value.choice.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); @@ -4105,6 +4619,71 @@ void procRicServiceUpdateFailure(E2AP_PDU_t *e2apMsg) 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 @@ -4184,6 +4763,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]",\ diff --git a/src/du_app/du_e2ap_msg_hdl.h b/src/du_app/du_e2ap_msg_hdl.h index fffdfdbcd..d2ef51b3d 100644 --- a/src/du_app/du_e2ap_msg_hdl.h +++ b/src/du_app/du_e2ap_msg_hdl.h @@ -23,8 +23,9 @@ void E2APMsgHdlr(Buffer *mBuf); uint8_t BuildAndSendE2SetupReq(); uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause); -uint8_t BuildAndSendE2NodeConfigUpdate(); +uint8_t BuildAndSendE2NodeConfigUpdate(E2NodeConfigList *recvList); uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate); +uint8_t duSendE2NodeConfigurationUpdate(); uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo); uint8_t BuildAndSendRicSubscriptionRsp(PendingSubsRspInfo *subsRspInfo); diff --git a/src/du_app/du_f1ap_msg_hdl.c b/src/du_app/du_f1ap_msg_hdl.c index b30f89d30..c263e5292 100644 --- a/src/du_app/du_f1ap_msg_hdl.c +++ b/src/du_app/du_f1ap_msg_hdl.c @@ -1588,91 +1588,6 @@ void FreeF1SetupReq(F1AP_PDU_t *f1apMsg) } } -/******************************************************************* - * - * @brief add or modify E2NodeComponent list - * - * @details - * - * Function : addOrModifyE2NodeComponent - * - * Functionality: add or modify E2NodeComponent list - * - * @parameter uint8_t componentactiontype, bool reqPart, uint8_t bufSize, char *bufString - * @return ROK - success - * RFAILED - failure - * - ******************************************************************/ -uint8_t addOrModifyE2NodeComponent(uint8_t action, bool reqPart, uint8_t bufSize, char *bufString) -{ - E2NodeComponent *e2NodeComponentInfo; - CmLList *node = NULLP; - - if(action == E2_NODE_COMPONENT_ADD) - { - if(reqPart == true) - { - DU_ALLOC(e2NodeComponentInfo, sizeof(E2NodeComponent)); - if(!e2NodeComponentInfo) - { - DU_LOG("\nERROR --> F1AP : Memory allocation failed for e2NodeComponentInfo in %s",__func__); - return RFAILED; - } - e2NodeComponentInfo->interfaceType =F1; - e2NodeComponentInfo->componentId=duCfgParam.duId; - e2NodeComponentInfo->componentActionType = action; - e2NodeComponentInfo->reqBufSize = bufSize; - - DU_ALLOC(e2NodeComponentInfo->componentRequestPart, bufSize); - if(e2NodeComponentInfo->componentRequestPart == NULLP) - { - DU_LOG("\nERROR --> F1AP : Memory allocation failed for componentRequestPart"); - DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent)); - return RFAILED; - } - memcpy(e2NodeComponentInfo->componentRequestPart, bufString, e2NodeComponentInfo->reqBufSize); - DU_ALLOC(node, sizeof(CmLList)); - if(node) - { - node->node = (PTR) e2NodeComponentInfo; - cmLListAdd2Tail(&duCb.e2apDb.e2NodeComponentList, node); - } - else - { - DU_LOG("\nERROR --> F1AP : Memory allocation failed for e2NodeComponentList node"); - DU_FREE(e2NodeComponentInfo->componentRequestPart, bufSize); - DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent)); - return RFAILED; - } - } - else - { - if(duCb.e2apDb.e2NodeComponentList.count) - { - CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); - while(node) - { - e2NodeComponentInfo = (E2NodeComponent*)node->node; - if((e2NodeComponentInfo->interfaceType == F1) && (e2NodeComponentInfo->componentActionType == action)) - { - e2NodeComponentInfo->rspBufSize = bufSize; - - DU_ALLOC(e2NodeComponentInfo->componentResponsePart, bufSize); - if(e2NodeComponentInfo->componentResponsePart == NULLP) - { - DU_LOG("\nERROR --> F1AP : Memory allocation failed to store the encoding of f1setup rsp"); - return RFAILED; - } - memcpy(e2NodeComponentInfo->componentResponsePart, bufString, e2NodeComponentInfo->rspBufSize); - break; - } - node = node->next; - } - } - } - } - return ROK; -} /******************************************************************* * * @brief Builds and Send the F1SetupRequest @@ -1844,7 +1759,11 @@ uint8_t BuildAndSendF1SetupReq() } - addOrModifyE2NodeComponent(E2_NODE_COMPONENT_ADD, true, encBufSize, encBuf); + if(addOrModifyE2NodeComponent(F1, E2_NODE_COMPONENT_ADD, true, encBufSize, encBuf) !=ROK) + { + DU_LOG("\nERROR --> F1AP : Failed to add the e2 node in the list"); + break; + } /* Sending msg */ if(sendF1APMsg() != ROK) { @@ -2843,6 +2762,11 @@ uint8_t BuildAndSendDUConfigUpdate(ServCellAction servCellAction) } #endif } + if(addOrModifyE2NodeComponent(F1, E2_NODE_COMPONENT_UPDATE, true, encBufSize, encBuf)!=ROK) + { + DU_LOG("\nERROR --> F1AP : Failed to update the e2 node in the list"); + break; + } /* Sending msg */ if(sendF1APMsg() != ROK) { @@ -15628,7 +15552,11 @@ uint8_t procF1SetupRsp(F1AP_PDU_t *f1apMsg, MsgLen recvBufLen, char *recvBuf) duProcF1SetupRsp(); freeAperDecodeF1SetupRsp(f1SetRspMsg); - addOrModifyE2NodeComponent(E2_NODE_COMPONENT_ADD, false, recvBufLen, recvBuf); + if(addOrModifyE2NodeComponent(F1, E2_NODE_COMPONENT_ADD, false, recvBufLen, recvBuf) !=ROK) + { + DU_LOG("\nERROR --> F1AP : Failed to add the e2 node in the list"); + return RFAILED; + } if(BuildAndSendE2SetupReq() != ROK) { @@ -15806,11 +15734,12 @@ uint8_t duProcGnbDuCfgUpdAckMsg(uint8_t transId) * * Functionality: added free part for the memory allocated by aper_decoder * -* @params[in] F1AP_PDU_t *f1apMsg +* @params[in] F1AP_PDU_t *f1apMsg, MsgLen recvBufLen, char *recvBuf * @return void * * ****************************************************************/ -uint8_t procF1GNBDUCfgUpdAck(F1AP_PDU_t *f1apMsg) + +uint8_t procF1GNBDUCfgUpdAck(F1AP_PDU_t *f1apMsg, MsgLen recvBufLen, char *recvBuf) { uint8_t ieIdx=0,transId=0; GNBDUConfigurationUpdateAcknowledge_t *gnbDuAck = NULLP; @@ -15852,6 +15781,12 @@ uint8_t procF1GNBDUCfgUpdAck(F1AP_PDU_t *f1apMsg) } #endif + if(addOrModifyE2NodeComponent(F1, E2_NODE_COMPONENT_UPDATE, false, recvBufLen, recvBuf) !=ROK) + { + DU_LOG("\nERROR --> F1AP : Failed to update the e2 node in the list"); + return RFAILED; + } + freeAperDecodeGnbDuAck(gnbDuAck); return ROK; } @@ -18035,7 +17970,7 @@ void F1APMsgHdlr(Buffer *mBuf) case SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge: { - procF1GNBDUCfgUpdAck(f1apMsg); + procF1GNBDUCfgUpdAck(f1apMsg, recvBufLen, recvBuf); break; } diff --git a/src/du_app/du_tmr.c b/src/du_app/du_tmr.c index 838dd3586..4a1bda79f 100644 --- a/src/du_app/du_tmr.c +++ b/src/du_app/du_tmr.c @@ -52,6 +52,7 @@ bool duChkTmr(PTR cb, int16_t tmrEvnt) DU_LOG("\nERROR --> DU_APP : duChkTmr: Invalid tmr Evnt [%d]", tmrEvnt); return TRUE; } + break; } case EVENT_RIC_SERVICE_UPDATE_TMR: { @@ -62,6 +63,15 @@ bool duChkTmr(PTR cb, int16_t tmrEvnt) } break; } + case EVENT_E2_NODE_CONFIG_UPDATE_TMR: + { + if(((E2NodeConfigUpdateTimer *)cb)->timer.tmrEvnt == EVENT_E2_NODE_CONFIG_UPDATE_TMR) + { + DU_LOG("\nERROR --> DU_APP : duChkTmr: Invalid tmr Evnt [%d]", tmrEvnt); + return TRUE; + } + break; + } default: { DU_LOG("\nERROR --> DU_APP : duChkTmr: Invalid tmr Evnt [%d]", tmrEvnt); @@ -108,6 +118,16 @@ void duStartTmr(PTR cb, int16_t tmrEvnt, uint8_t timerValue) arg.max = MAX_RIC_SERVICE_UPDATE_TMR; break; } + case EVENT_E2_NODE_CONFIG_UPDATE_TMR: + { + E2NodeConfigUpdateTimer *cfgUpdateTimer; + cfgUpdateTimer = ((E2NodeConfigUpdateTimer*)cb); + TMR_CALCUATE_WAIT(arg.wait, timerValue, duCb.duTimersInfo.tmrRes); + + arg.timers = &cfgUpdateTimer->timer; + arg.max = MAX_E2_NODE_CONFIG_UPDATE_TMR; + break; + } default: { DU_LOG("\nERROR --> DU : duStartTmr: Invalid tmr Evnt [%d]", tmrEvnt); @@ -158,6 +178,14 @@ void duTmrExpiry(PTR cb,int16_t tmrEvnt) BuildAndSendRicServiceUpdate(ricServiceUpdateTimer->ricService); break; } + case EVENT_E2_NODE_CONFIG_UPDATE_TMR: + { + E2NodeConfigUpdateTimer *cfgUpdateTimer; + + cfgUpdateTimer = ((E2NodeConfigUpdateTimer*)cb); + BuildAndSendE2NodeConfigUpdate(&cfgUpdateTimer->configList); + break; + } default: { DU_LOG("\nERROR --> DU : duStartTmr: Invalid tmr Evnt [%d]", tmrEvnt); diff --git a/src/ric_stub/ric_e2ap_msg_hdl.c b/src/ric_stub/ric_e2ap_msg_hdl.c index ac6dccbaa..0e495432e 100644 --- a/src/ric_stub/ric_e2ap_msg_hdl.c +++ b/src/ric_stub/ric_e2ap_msg_hdl.c @@ -100,7 +100,7 @@ uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId) if(ODU_ADD_POST_MSG_MULT((Data *)encBuf, encBufSize, mBuf) == ROK) { ODU_PRINT_MSG(mBuf, 0,0); - + if(sctpSend(duId, mBuf) != ROK) { DU_LOG("\nERROR --> E2AP : SCTP Send for E2 failed"); @@ -121,10 +121,228 @@ uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId) DU_LOG("\nERROR --> E2AP : Failed to allocate memory"); return RFAILED; } - + return ROK; } /* SendE2APMsg */ +/******************************************************************* + * + * @brief deallocate memory allocated in E2 Node Config Update Failure + * + * @details + * + * Function : FreeE2ConfigUpdateFail + * + * Functionality: deallocate memory allocated in E2 Node Config Update Failure + * + * @params[in] E2AP_PDU_t *e2apMsg + * + * @return void + * ****************************************************************/ + +void FreeE2ConfigUpdateFail(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx = 0; + E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL; + + if(e2apMsg) + { + if(e2apMsg->choice.unsuccessfulOutcome) + { + e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure; + if(e2NodeCfgUpdFail->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateFailure_IEs_t)); + } + RIC_FREE(e2NodeCfgUpdFail->protocolIEs.list.array, e2NodeCfgUpdFail->protocolIEs.list.size); + } + RIC_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + } + RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/******************************************************************* + * + * @brief Buld and send the E2 Node Config Update failure + * + * @details + * + * Function : BuildAndSendE2NodeConfigUpdateFailure + * + * Functionality: + * - Buld and send the E2 Node Config Update failure + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint8_t transId, uint8_t causeInfo, uint8_t causeReason) +{ + E2AP_PDU_t *e2apMsg = NULL; + asn_enc_rval_t encRetVal; + uint8_t arrIdx=0; + uint8_t elementCnt=0; + bool memAllocFailed = false; + E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdateFail=NULL; + + DU_LOG("\nINFO --> E2AP : Building E2 Node Config Update failure\n"); + while(true) + { + RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); + break; + } + e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; + RIC_ALLOC(e2apMsg->choice.unsuccessfulOutcome , sizeof(struct UnsuccessfulOutcomeE2)); + if(e2apMsg->choice.unsuccessfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); + break; + } + + e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate; + e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateFailure; + e2NodeCfgUpdateFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure; + + elementCnt = 3; + e2NodeCfgUpdateFail->protocolIEs.list.count = elementCnt; + e2NodeCfgUpdateFail->protocolIEs.list.size = elementCnt * sizeof(struct E2nodeConfigurationUpdateFailure_IEs *); + + RIC_ALLOC(e2NodeCfgUpdateFail->protocolIEs.list.array, e2NodeCfgUpdateFail->protocolIEs.list.size); + if(e2NodeCfgUpdateFail->protocolIEs.list.array == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation for E2 node config update failure array failed"); + break; + } + + for(arrIdx=0; arrIdxprotocolIEs.list.array[arrIdx], sizeof(struct E2nodeConfigurationUpdateFailure_IEs)); + if(e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx] == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation for E2 node config update failure IEs failed"); + memAllocFailed = true; + break; + } + } + + if(memAllocFailed == true) + { + break; + } + + /* Trans Id */ + arrIdx = 0; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TransactionID; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = transId; + + arrIdx++; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_CauseE2; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_CauseE2; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.present = causeInfo; + if(causeInfo == CauseE2_PR_e2Node) + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.e2Node = causeReason; + else + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.CauseE2.choice.misc = causeReason; + + arrIdx++; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TimeToWaitE2; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_ignore; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.present = E2setupFailureIEs__value_PR_TimeToWaitE2; + e2NodeCfgUpdateFail->protocolIEs.list.array[arrIdx]->value.choice.TimeToWaitE2 = TimeToWaitE2_v5s; + + 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); + + /* Check encode results */ + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2 Node Config Update failure structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Node Config Update Failure\n"); + for(int i=0; i< encBufSize; i++) + { + DU_LOG("%x",encBuf[i]); + } + } + + if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Sending E2 Node Config Update Failure failed"); + break; + } + break; + } + + FreeE2ConfigUpdateFail(e2apMsg); + return ROK; +} + +/******************************************************************* + * + * @brief process the E2 node configuration update + * + * @details + * + * Function : ProcE2NodeConfigUpdate + * + * Functionality: Process E2 node configuration update + * + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ + +void ProcE2NodeConfigUpdate(uint32_t duId, E2nodeConfigurationUpdate_t *e2NodeConfigUpdate) +{ + uint8_t ieIdx = 0, duIdx = 0; + uint8_t transId = 0, e2NodeUpdateListIdx=0; + DuDb *duDb = NULLP; + E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList=NULLP; + E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe=NULLP; + E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULLP; + + if(e2NodeConfigUpdate) + { + if(e2NodeConfigUpdate->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < e2NodeConfigUpdate->protocolIEs.list.count; ieIdx++) + { + if(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]) + { + switch(e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + transId = e2NodeConfigUpdate->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; + break; + + default: + { + /*TODO - Other IEs will be handling in next gerrit*/ + break; + } + } + } + } + } + } +} + /******************************************************************* * * @brief Builds Global RIC Id Params @@ -1620,159 +1838,6 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t *e2SetupReq) } return ROK; } - -/******************************************************************* - * - * @brief Deallocate the memory allocated for E2nodeConfigurationUpdate msg - * - * @details - * - * Function : FreeE2NodeConfigUpdate - * - * Functionality: - * - freeing the memory allocated for E2nodeConfigurationUpdate - * - * @params[in] E2AP_PDU_t *e2apMsg - * @return ROK - success - * RFAILED - failure - * - * ****************************************************************/ -void FreeE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg) -{ - uint8_t arrIdx =0; - E2nodeConfigurationUpdate_t *e2NodeConfigUpdateAck; - - if(e2apMsg != NULLP) - { - if(e2apMsg->choice.successfulOutcome != NULLP) - { - e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge; - if(e2NodeConfigUpdateAck->protocolIEs.list.array != NULLP) - { - for(arrIdx = 0; arrIdx < e2NodeConfigUpdateAck->protocolIEs.list.count; arrIdx++) - { - RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdate_t)); - } - RIC_FREE(e2NodeConfigUpdateAck->protocolIEs.list.array, e2NodeConfigUpdateAck->protocolIEs.list.size); - } - RIC_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); - } - RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t)); - } -} - -/******************************************************************* - * - * @brief Buld and send the E2 node config update msg - * - * @details - * - * Function : BuildAndSendE2NodeConfigUpdate - * - * Functionality: - * - Buld and send the E2 node config update msg - * @return ROK - success - * RFAILED - failure - * - * ****************************************************************/ - -uint8_t BuildAndSendE2NodeConfigUpdateAck(uint32_t duId) -{ - uint8_t arrIdx = 0,elementCnt = 1; - uint8_t ret = ROK; - E2AP_PDU_t *e2apMsg = NULLP; - E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck = NULLP; - asn_enc_rval_t encRetVal; /* Encoder return value */ - - DU_LOG("\nINFO --> E2AP : Building E2 Node config update Ack Message\n"); - do - { - RIC_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); - if(e2apMsg == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); - break; - } - e2apMsg->present = E2AP_PDU_PR_successfulOutcome; - RIC_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); - if(e2apMsg->choice.successfulOutcome == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed"); - RIC_FREE(e2apMsg, sizeof(E2AP_PDU_t)); - return RFAILED; - } - - e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; - e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2nodeConfigurationUpdate; - e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge; - e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge; - - e2NodeConfigUpdateAck->protocolIEs.list.count = elementCnt; - e2NodeConfigUpdateAck->protocolIEs.list.size = elementCnt * sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t*); - /* Initialize the Ric Indication members */ - RIC_ALLOC(e2NodeConfigUpdateAck->protocolIEs.list.array, \ - e2NodeConfigUpdateAck->protocolIEs.list.size); - if(e2NodeConfigUpdateAck->protocolIEs.list.array == NULLP) - { - DU_LOG("\nERROR --> E2AP : Memory allocation for e2NodeConfigUpdateAck failed"); - break; - } - - for(arrIdx =0; arrIdxprotocolIEs.list.array[arrIdx], sizeof(E2nodeConfigurationUpdateAcknowledge_IEs_t)); - if(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx] == NULLP) - { - - DU_LOG("\nERROR --> E2AP : Memory allocation for e2NodeConfigUpdateAck failed"); - break; - } - } - - arrIdx = 0; - /* TransactionID */ - e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id = ProtocolIE_IDE2_id_TransactionID; - e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->criticality = CriticalityE2_reject; - e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.present = E2nodeConfigurationUpdateAcknowledge_IEs__value_PR_TransactionID; - e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.TransactionID = TRANS_ID; - - - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); - - memset(encBuf, 0, ENC_BUF_MAX_LEN); - encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf,\ - encBuf); - if(encRetVal.encoded == ENCODE_FAIL) - { - DU_LOG("\nERROR --> E2AP : Could not encode E2 Node config update ack structure (at %s)\n",\ - encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); - return RFAILED; - } - else - { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Node config update ack \n"); - for(int i=0; i< encBufSize; i++) - { - DU_LOG("%x",encBuf[i]); - } - } - - - /* Sending msg */ - if(SendE2APMsg(RIC_APP_MEM_REG, RIC_POOL, duId) != ROK) - { - DU_LOG("\nERROR --> E2AP : Failed to send E2 Node config update ack "); - return RFAILED; - } - - break; - }while(true); - - FreeE2NodeConfigUpdateAck(e2apMsg); - return ret; -} - /******************************************************************* * * @brief Deallocate the memory allocated for E2 Reset Response @@ -3031,7 +3096,7 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf) case InitiatingMessageE2__value_PR_E2nodeConfigurationUpdate: { DU_LOG("\nINFO --> E2AP : E2 node config update received"); - BuildAndSendE2NodeConfigUpdateAck(*duId); + ProcE2NodeConfigUpdate(*duId, &e2apMsg->choice.initiatingMessage->value.choice.E2nodeConfigurationUpdate); break; } case InitiatingMessageE2__value_PR_ResetRequestE2: diff --git a/src/ric_stub/ric_e2ap_msg_hdl.h b/src/ric_stub/ric_e2ap_msg_hdl.h index e370ed6c0..6872d962b 100644 --- a/src/ric_stub/ric_e2ap_msg_hdl.h +++ b/src/ric_stub/ric_e2ap_msg_hdl.h @@ -58,6 +58,8 @@ uint8_t BuildAndSendE2SetupRsp(DuDb *duDb, uint8_t transId); uint8_t BuildAndSendRicSubscriptionReq(DuDb *duDb); uint8_t SendE2APMsg(Region region, Pool pool, uint32_t duId); uint8_t BuildAndSendRicServiceQuery(DuDb *duDb); +uint8_t BuildAndSendE2NodeConfigUpdateFailure(uint32_t duId, uint8_t transId, uint8_t causeInfo, uint8_t causeReason); + /********************************************************************** End of file **********************************************************************/ -- 2.16.6