X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Fdu_app%2Fdu_e2ap_msg_hdl.c;h=ece43c87beba5f7250c8220a59965d33c2b3793d;hb=refs%2Fchanges%2F63%2F11863%2F5;hp=0a5cec50b95e21c977c3963f3211c56cd60adad5;hpb=548dcf8b2ea8a02fefb50bd590f324b6f4c9ca18;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 0a5cec50b..ece43c87b 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -119,41 +119,98 @@ void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause) /******************************************************************* * - * @brief Free the ErrorIndication Message + * @brief Printing Type and Cause of failure * * @details * - * Function : FreeRicIndication + * Function : printE2ErrorCause * - * Functionality: Free the ErrorIndication Message + * Functionality: Printing Type and Cause of failure * - * @params[in] - * E2AP_PDU is to freed + * @params[in] E2 Cause * @return void * ******************************************************************/ -void FreeErrorIndication(E2AP_PDU_t *e2apMsg) +void printE2ErrorCause(CauseE2_t *cause) { - uint8_t arrIdx = 0; - ErrorIndicationE2_t *errorIndicationMsg= NULLP; + switch(cause->present) + { + case CauseE2_PR_ricRequest: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Request", cause->choice.ricRequest); + break; + } + case CauseE2_PR_ricService: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "RIC_Service", cause->choice.ricService); + break; + } + case CauseE2_PR_e2Node: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "E2_Node", cause->choice.e2Node); + break; + } + case CauseE2_PR_transport: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "Transport", cause->choice.transport); + break; + } + case CauseE2_PR_protocol: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "Protocol", cause->choice.protocol); + break; + } + case CauseE2_PR_misc: + { + DU_LOG("Failure_Type [%s] Cause [%ld]", "Miscellaneous", cause->choice.misc); + break; + } + default: + { + DU_LOG("Failure_Type and Cause unknown"); + break; + } + } +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for E2 Removal Failure + * + * @details + * + * Function : FreeE2RemovalFailure + * + * Functionality: + * - freeing the memory allocated for E2RemovalFailure + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +void FreeE2RemovalFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0; + E2RemovalFailure_t *e2RemovalFailure=NULLP; if(e2apMsg != NULLP) { - if(e2apMsg->choice.initiatingMessage != NULLP) + if(e2apMsg->choice.unsuccessfulOutcome != NULLP) { - errorIndicationMsg = &e2apMsg->choice.initiatingMessage->value.choice.ErrorIndicationE2; - if(errorIndicationMsg!= NULLP) + e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure; + if(e2RemovalFailure->protocolIEs.list.array) { - if(errorIndicationMsg->protocolIEs.list.array != NULLP) + for(ieIdx=0; ieIdx < e2RemovalFailure->protocolIEs.list.count; ieIdx++) { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + if(e2RemovalFailure->protocolIEs.list.array[ieIdx]) { - DU_FREE(errorIndicationMsg->protocolIEs.list.array[arrIdx],sizeof(ErrorIndicationE2_t)); + DU_FREE(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t)); } - DU_FREE(errorIndicationMsg->protocolIEs.list.array,errorIndicationMsg->protocolIEs.list.size); } + DU_FREE(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size); } - DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + DU_FREE(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); } DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); } @@ -161,880 +218,1291 @@ void FreeErrorIndication(E2AP_PDU_t *e2apMsg) /******************************************************************* * - * @brief Builds and Send the ErrorIndication Message + * @brief Buld and send the E2 Removal Failure msg * * @details * - * Function : BuildAndSendErrorIndication - * - * Functionality:Fills the ErrorIndication Message + * Function : BuildAndSendE2RemovalFailure * - * @params[in] - * Trans id - * Ric req id - * Ran function id - * Cause of failure + * Functionality: + * - Buld and send the E2 Removal Failure Message + * @params[in] Trans Id * @return ROK - success * RFAILED - failure * - ******************************************************************/ + * ****************************************************************/ -uint8_t BuildAndSendErrorIndication(int8_t transId, RicRequestId requestId, uint16_t ranFuncId, E2FailureCause failureCause) +uint8_t BuildAndSendRemovalFailure(uint8_t transId, 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 */ + uint8_t ieIdx = 0, elementCnt = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + E2RemovalFailure_t *e2RemovalFailure=NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ - while(true) + DU_LOG("\nINFO --> E2AP : Building E2 Removal Failure Message\n"); + do { - 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__); + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); break; } + e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; - e2apMsg->present = E2AP_PDU_PR_initiatingMessage; - DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); - if(e2apMsg->choice.initiatingMessage == NULLP) + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + if(e2apMsg->choice.unsuccessfulOutcome == NULLP) { - DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__); + DU_LOG("\nERROR --> E2AP : Memory allocation 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*); + e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal; + e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_E2RemovalFailure; + e2RemovalFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2RemovalFailure; - /* Initialize the E2Setup members */ - DU_ALLOC(errorIndicationMsg->protocolIEs.list.array, errorIndicationMsg->protocolIEs.list.size); - if(errorIndicationMsg->protocolIEs.list.array == NULLP) + elementCnt = 2; + e2RemovalFailure->protocolIEs.list.count = elementCnt; + e2RemovalFailure->protocolIEs.list.size = elementCnt * sizeof(E2RemovalFailureIEs_t *); + DU_ALLOC(e2RemovalFailure->protocolIEs.list.array, e2RemovalFailure->protocolIEs.list.size); + if(!e2RemovalFailure->protocolIEs.list.array) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__); + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); break; } - - for(arrIdx = 0; arrIdx < elementCnt; (arrIdx)++) + + for(ieIdx=0; ieIdx < elementCnt; ieIdx++) { - DU_ALLOC(errorIndicationMsg->protocolIEs.list.array[arrIdx], sizeof(ErrorIndicationE2_IEs_t)); - if(errorIndicationMsg->protocolIEs.list.array[arrIdx] == NULLP) + DU_ALLOC(e2RemovalFailure->protocolIEs.list.array[ieIdx], sizeof(E2RemovalFailureIEs_t)); + if(!e2RemovalFailure->protocolIEs.list.array[ieIdx]) { - DU_LOG("\nERROR --> E2AP : Memory allocation failed for array [%d] elements in %s at line %d", arrIdx, __func__, __LINE__); + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); break; } } - if(arrIdx < elementCnt) + if(ieIdx < 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; - } + ieIdx = 0; + e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = E2RemovalFailureIEs__value_PR_TransactionID; + e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; /* 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 */ + ieIdx++; + e2RemovalFailure->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2; + e2RemovalFailure->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore; + e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.present = ErrorIndicationE2_IEs__value_PR_CauseE2; + fillE2Cause(&e2RemovalFailure->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, failureCause); + 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 Error Indication Message (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode E2 removal failure structure (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 + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Removal Failure \n"); for(int i=0; i< encBufSize; i++) { - printf("%x",encBuf[i]); - } -#endif + DU_LOG("%x",encBuf[i]); + } } + /* Sending msg */ if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { - DU_LOG("\nINFO --> E2AP : Sending Error Indication Message"); - + DU_LOG("\nERROR --> E2AP : Failed to send E2 Removal Failure"); + break; } + ret = ROK; break; - } - FreeErrorIndication(e2apMsg); + }while(true); + + FreeE2RemovalFailure(e2apMsg); return ret; } -/****************************************************************** +/******************************************************************* * - * @brief Deallocation of memory allocated by aper decoder for e2 - * Config Update Failure + * @brief Deallocate the memory allocated for E2 Removal Response * * @details * - * Function : freeAperDecodingOfE2Node Config UpdateFailure + * Function : FreeE2RemovalResponse * - * Functionality: Deallocation of memory allocated by aper decoder - * for e2 Config Update Failure + * Functionality: + * - freeing the memory allocated for E2RemovalResponse * - * @params[in] E2nodeConfigurationUpdateFailure_t to be deallocated - * @return void + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure * * ****************************************************************/ - -void freeAperDecodingOfE2NodeConfigUpdateFailure(E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail) +void FreeE2RemovalResponse(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx =0; + uint8_t ieIdx =0; + E2RemovalResponse_t *e2RemovalResponse=NULLP; - if(e2NodeCfgUpdFail) + if(e2apMsg != NULLP) { - if(e2NodeCfgUpdFail->protocolIEs.list.array) + if(e2apMsg->choice.successfulOutcome != NULLP) { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse; + if(e2RemovalResponse->protocolIEs.list.array) { - if(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]) + for(ieIdx=0; ieIdx < e2RemovalResponse->protocolIEs.list.count; ieIdx++) { - free(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]); + if(e2RemovalResponse->protocolIEs.list.array[ieIdx]) + { + DU_FREE(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t)); + } } + DU_FREE(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size); } - free(e2NodeCfgUpdFail->protocolIEs.list.array); + DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); } } -/****************************************************************** +/******************************************************************* * - * @brief Processes E2 Node Config Update Failure sent by RIC + * @brief Buld and send the E2 Removal Response msg * * @details * - * Function : procE2NodeConfigUpdateFailure - * - * Functionality: Processes E2 Node Config Update failure sent by RIC + * Function : BuildAndSendE2RemovalResponse * - * @params[in] E2AP_PDU_t ASN decoded E2AP message + * Functionality: + * - Buld and send the E2 Removal Response Message + * @params[in] Trans Id * @return ROK - success * RFAILED - failure * * ****************************************************************/ - -void procE2NodeConfigUpdateFailure(E2AP_PDU_t *e2apMsg) +uint8_t BuildAndSendRemovalResponse(uint8_t transId) { - 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; + uint8_t ieIdx = 0, elementCnt = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + E2RemovalResponse_t *e2RemovalResponse=NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + DU_LOG("\nINFO --> E2AP : Building E2 Removal Response Message\n"); + do { - switch(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->id) + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) { - 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; + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + e2apMsg->present = E2AP_PDU_PR_successfulOutcome; + + DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(e2apMsg->choice.successfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_E2removal; + e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_E2RemovalResponse; + e2RemovalResponse = &e2apMsg->choice.successfulOutcome->value.choice.E2RemovalResponse; + + elementCnt = 1; + e2RemovalResponse->protocolIEs.list.count = elementCnt; + e2RemovalResponse->protocolIEs.list.size = elementCnt * sizeof(E2RemovalResponseIEs_t *); + DU_ALLOC(e2RemovalResponse->protocolIEs.list.array, e2RemovalResponse->protocolIEs.list.size); + if(!e2RemovalResponse->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + + for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(e2RemovalResponse->protocolIEs.list.array[ieIdx], sizeof(E2RemovalResponseIEs_t)); + if(!e2RemovalResponse->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed in %s at line %d", __func__, __LINE__); + break; + } + } + if(ieIdx < elementCnt) + break; + + ieIdx = 0; + e2RemovalResponse->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + e2RemovalResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.present = E2RemovalResponseIEs__value_PR_TransactionID; + e2RemovalResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode E2 removal response structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Removal Response \n"); + for(int i=0; i< encBufSize; i++) + { + DU_LOG("%x",encBuf[i]); + } + } + + /* Sending msg */ + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 Removal Response"); + break; + } + + ret = ROK; + break; + }while(true); + + FreeE2RemovalResponse(e2apMsg); + return ret; +} + +/****************************************************************** + * + * @brief Deallocation of memory allocated by aper decoder for Removal req + * + * @details + * + * Function : freeAperDecodingOfE2RemovalReq + * + * Functionality: Deallocation of memory allocated by aper decoder for + * Removal req + * + * @params[in] Pointer to removalReq + * @return void + * + * ****************************************************************/ +void freeAperDecodingOfE2RemovalReq(E2RemovalRequest_t *removalReq) +{ + uint8_t arrIdx=0; + + if(removalReq) + { + if(removalReq->protocolIEs.list.array) + { + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(removalReq->protocolIEs.list.array[arrIdx]) + { + free(removalReq->protocolIEs.list.array[arrIdx]); } + } + free(removalReq->protocolIEs.list.array); } } - - freeAperDecodingOfE2NodeConfigUpdateFailure(e2NodeCfgUpdFail); } /******************************************************************* * - * @brief Builds Global gNodeB Params + * @brief Process Removal req received from RIC * * @details * - * Function : BuildGlobalgNBId + * Function : procE2RemovalRequest * - * Functionality: Building the Plmn and gNB id + * Functionality: Process Removal req received from RIC * - * @params[in] GlobalE2node_gNB_ID_t *gNbId - * @return ROK - success - * RFAILED - failure + * @param E2AP_PDU_t *e2apMsg + * @return void * ******************************************************************/ -uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId) +void procE2RemovalRequest(E2AP_PDU_t *e2apMsg) { - uint8_t unused = 0; - uint8_t byteSize = 4; - uint8_t gnbId = duCb.gnbId; - uint8_t ret = ROK; + uint8_t arrIdx =0, transId =0, count =0; + E2FailureCause failureCause; + E2RemovalRequest_t *removalReq=NULLP; - /* fill Global gNB ID Id */ - gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t); - gNbId->global_gNB_ID.plmn_id.buf = NULLP; - DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size); - if(gNbId->global_gNB_ID.plmn_id.buf == NULLP) - { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for Plmn buffer"); - ret = RFAILED; - } - else + DU_LOG("\nINFO --> E2AP : E2 Removal request received"); + removalReq = &e2apMsg->choice.initiatingMessage->value.choice.E2RemovalRequest; + + count =removalReq->protocolIEs.list.count; + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) { - buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \ - gNbId->global_gNB_ID.plmn_id.buf); - gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID; - /* Allocate Buffer size */ - gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t); - gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP; - DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \ - gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size); - if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP) - { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for gnb buffer"); - ret = RFAILED; - } - else + switch(removalReq->protocolIEs.list.array[arrIdx]->id) { - fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId); + case ProtocolIE_IDE2_id_TransactionID: + { + transId = removalReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid IE recevied [%d]", transId); + break; + } } } - - /* fill gNB-DU ID */ - DU_ALLOC( gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t)); - if(gNbId->gNB_DU_ID == NULLP) + + if(transId>=0 && transId<=255) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for gNB_DU_ID "); - ret = RFAILED; + if(BuildAndSendRemovalResponse(transId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send Removal response"); + } } else { - gNbId->gNB_DU_ID->size = sizeof(uint8_t); - DU_ALLOC( gNbId->gNB_DU_ID->buf, sizeof(uint8_t)); - if(gNbId->gNB_DU_ID->buf) + failureCause.causeType = E2_PROTOCOL; + failureCause.cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE; + + if(BuildAndSendRemovalFailure(transId, failureCause) != ROK) { - gNbId->gNB_DU_ID->buf[0] =duCb.e2apDb.e2NodeId; + DU_LOG("\nERROR --> E2AP : Failed to build and send Removal response"); } - else + } + freeAperDecodingOfE2RemovalReq(removalReq); +} + +/******************************************************************* + * + * @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) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for gNB_DU_ID buffer"); - ret = RFAILED; + 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)); } - - return ret; } /******************************************************************* * - * @brief fill the E2 node config information + * @brief Builds and Send the ErrorIndication Message * * @details * - * Function : fillE2NodeConfig + * Function : BuildAndSendErrorIndication * - * Functionality: fill E2 node config information + * Functionality:Fills the ErrorIndication Message * - * @params[in] - * Pointer to e2NodeCfg to be filled - * E2 Node Component information - * Type of configuration + * @params[in] + * Trans id + * Ric req id + * Ran function id + * Cause of failure * @return ROK - success * RFAILED - failure * ******************************************************************/ -uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType) +uint8_t BuildAndSendErrorIndication(int8_t transId, RicRequestId requestId, uint16_t ranFuncId, E2FailureCause failureCause) { - 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) + 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) { - case CONFIG_ADD: - { - e2NodeAddItem = (E2nodeComponentConfigAddition_Item_t*)e2NodeCfg; - interfaceType = &e2NodeAddItem->e2nodeComponentInterfaceType; - componentID = &e2NodeAddItem->e2nodeComponentID; - configuration = &e2NodeAddItem->e2nodeComponentConfiguration; - break; - } - case CONFIG_MOD: + DU_LOG("\nINFO --> E2AP : Building Error Indication Message\n"); + + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) { - e2NodeUpdateItem = (E2nodeComponentConfigUpdate_Item_t *) e2NodeCfg; - interfaceType = &e2NodeUpdateItem->e2nodeComponentInterfaceType; - componentID = &e2NodeUpdateItem->e2nodeComponentID; - configuration = &e2NodeUpdateItem->e2nodeComponentConfiguration; + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__); break; } - case CONFIG_DEL: + + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) { - e2NodeRemovalItem = (E2nodeComponentConfigRemoval_Item_t*) e2NodeCfg; - interfaceType = &e2NodeRemovalItem->e2nodeComponentInterfaceType; - componentID = &e2NodeRemovalItem->e2nodeComponentID; + DU_LOG("\nERROR --> E2AP : Memory allocation for E2AP-PDU failed in %s at line %d",__func__, __LINE__); break; } - default: + 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) { - DU_LOG("\nERROR --> E2AP : Configuration type %d does not supported ", configType); - return RFAILED; + elementCnt++; } - } - /* 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) + + 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 in function %s at line %d",__func__,__LINE__); - return RFAILED; + DU_LOG("\nERROR --> E2AP : Memory allocation failed for array elements in %s at line %d",__func__, __LINE__); + break; } - 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); + + 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; - if(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP) + arrIdx = 0; + + if(transId >=0 && transId<=255) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); - return RFAILED; + /* 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; } - 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; - } - /* E2 Node Component Request Part */ - if(e2NodeComponentInfo->componentRequestPart) - { - configuration->e2nodeComponentRequestPart.size = e2NodeComponentInfo->reqBufSize ; - DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\ - configuration->e2nodeComponentRequestPart.size); - if(configuration->e2nodeComponentRequestPart.buf == NULLP) + /* 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: Memory allocation failed in function %s at line %d",__func__,__LINE__); - return RFAILED; + 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 } - memcpy(configuration->e2nodeComponentRequestPart.buf,\ - e2NodeComponentInfo->componentRequestPart, configuration->\ - e2nodeComponentRequestPart.size); - } - else - { - DU_LOG("\nERROR --> E2AP: componentRequestPart is null "); - return RFAILED; + 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; +} - /* E2 Node Component Response Part */ - if(e2NodeComponentInfo->componentResponsePart) +/****************************************************************** + * + * @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) { - configuration->e2nodeComponentResponsePart.size = e2NodeComponentInfo->rspBufSize; - DU_ALLOC(configuration->e2nodeComponentResponsePart.buf, configuration->e2nodeComponentResponsePart.size); - if(configuration->e2nodeComponentResponsePart.buf == NULLP) + if(e2NodeCfgUpdFail->protocolIEs.list.array) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); - return RFAILED; + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + if(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]) + { + free(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]); + } + } + free(e2NodeCfgUpdFail->protocolIEs.list.array); } - memcpy(configuration->e2nodeComponentResponsePart.buf, e2NodeComponentInfo->componentResponsePart, configuration->\ - e2nodeComponentResponsePart.size); - } - else - { - DU_LOG("\nERROR --> E2AP: componentResponsePart is null"); - return RFAILED; } - - return ROK; } -/******************************************************************* +/****************************************************************** * - * @brief Builds E2 node config addition list + * @brief Processes E2 Node Config Update Failure sent by RIC * * @details * - * Function : BuildE2NodeConfigAddList - * - * Functionality: Building E2 node config addition list + * Function : procE2NodeConfigUpdateFailure * - * @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 + * Functionality: Processes E2 Node Config Update failure sent by RIC * + * @params[in] E2AP_PDU_t ASN decoded E2AP message * @return ROK - success * RFAILED - failure * - ******************************************************************/ + * ****************************************************************/ -uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList, uint8_t procedureCode, uint16_t count, E2NodeConfigItem *e2NodeList) +void procE2NodeConfigUpdateFailure(E2AP_PDU_t *e2apMsg) { - 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; + uint8_t arrIdx =0, transId =0, timerValue=0; + E2nodeConfigurationUpdateFailure_t *e2NodeCfgUpdFail=NULL; - 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; - } + DU_LOG("\nINFO --> E2AP : E2 Node Config Update failure received"); + e2NodeCfgUpdFail = &e2apMsg->choice.unsuccessfulOutcome->value.choice.E2nodeConfigurationUpdateFailure; - for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++) + for(arrIdx=0; arrIdxprotocolIEs.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) + switch(e2NodeCfgUpdFail->protocolIEs.list.array[arrIdx]->id) { - /* 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; + 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; } - 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; + 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; + } } } - return ROK; + + freeAperDecodingOfE2NodeConfigUpdateFailure(e2NodeCfgUpdFail); } /******************************************************************* * - * @brief Builds E2 node config update list + * @brief Builds Global gNodeB Params * * @details * - * Function : BuildE2NodeConfigUpdateList - * - * Functionality: Building E2 node config update list + * Function : BuildGlobalgNBId * - * @params[in] - * E2nodeComponentConfigUpdate_List_t to be filled - * Count of E2 node to be update in the list - * Received list of E2 node configuration + * Functionality: Building the Plmn and gNB id * + * @params[in] GlobalE2node_gNB_ID_t *gNbId * @return ROK - success * RFAILED - failure * ******************************************************************/ -uint8_t BuildE2NodeConfigUpdateList(E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList, uint16_t count, E2NodeConfigItem *updateE2Node) +uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId) { - uint8_t arrIdx = 0; - CmLList *node =NULL; - E2NodeComponent *e2NodeComponentInfo =NULL; - E2nodeComponentConfigUpdate_ItemIEs_t *e2NodeUpdateItemIe =NULL; - E2nodeComponentConfigUpdate_Item_t *e2NodeUpdateItem =NULL; + uint8_t unused = 0; + uint8_t byteSize = 4; + uint8_t gnbId = duCb.gnbId; + uint8_t ret = ROK; - 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) + /* fill Global gNB ID Id */ + gNbId->global_gNB_ID.plmn_id.size = 3 * sizeof(uint8_t); + gNbId->global_gNB_ID.plmn_id.buf = NULLP; + DU_ALLOC(gNbId->global_gNB_ID.plmn_id.buf , gNbId->global_gNB_ID.plmn_id.size); + if(gNbId->global_gNB_ID.plmn_id.buf == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); - return RFAILED; + DU_LOG("\nERROR --> E2AP: Memory allocation failed for Plmn buffer"); + ret = RFAILED; } - - for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++) + else { - DU_ALLOC(e2NodeUpdateList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdate_ItemIEs_t)); - if(e2NodeUpdateList->list.array[arrIdx] == NULLP) + buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \ + gNbId->global_gNB_ID.plmn_id.buf); + gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID; + /* Allocate Buffer size */ + gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t); + gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP; + DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \ + gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size); + if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); - return RFAILED; + DU_LOG("\nERROR --> E2AP: Memory allocation failed for gnb buffer"); + ret = RFAILED; } - - e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node); - if(!e2NodeComponentInfo) + else { - DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); - return RFAILED; + fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId); } + } - 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) + /* fill gNB-DU ID */ + DU_ALLOC( gNbId->gNB_DU_ID, sizeof(GNB_DU_ID_t)); + if(gNbId->gNB_DU_ID == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed for gNB_DU_ID "); + ret = RFAILED; + } + else + { + gNbId->gNB_DU_ID->size = sizeof(uint8_t); + DU_ALLOC( gNbId->gNB_DU_ID->buf, sizeof(uint8_t)); + if(gNbId->gNB_DU_ID->buf) { - DU_LOG("\nERROR --> E2AP : Failed to fill the E2 node configuration"); - return RFAILED; + gNbId->gNB_DU_ID->buf[0] =duCb.e2apDb.e2NodeId; + } + else + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed for gNB_DU_ID buffer"); + ret = RFAILED; } - } - return ROK; + return ret; } - /******************************************************************* * - * @brief Builds E2 node config remove list + * @brief fill the E2 node config information * * @details * - * Function :BuildE2NodeConfigRemoveList + * Function : fillE2NodeConfig * - * Functionality: Building E2 node config remove list + * Functionality: fill E2 node config information * - * @params[in] - * E2nodeComponentConfigRemoval_List_t to be filled - * Count of E2 node to be remove in the list - * Received list of E2 node configuration + * @params[in] + * Pointer to e2NodeCfg to be filled + * E2 Node Component information + * Type of configuration * @return ROK - success * RFAILED - failure * ******************************************************************/ -uint8_t BuildE2NodeConfigRemoveList(E2nodeComponentConfigRemoval_List_t *e2NodeRemoveList, uint16_t count, E2NodeConfigItem *updateE2Node) +uint8_t fillE2NodeConfig(PTR e2NodeCfg, E2NodeComponent *e2NodeComponentInfo, ConfigType configType) { - uint8_t arrIdx = 0; - CmLList *node=NULL; - E2NodeComponent *e2NodeComponentInfo=NULL; - E2nodeComponentConfigRemoval_ItemIEs_t *e2NodeRemovalItemIe=NULL; + E2NodeConfig *e2NodeConfig=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; - - 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) + + switch(configType) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigRemoveList %d",__LINE__); - return RFAILED; + case CONFIG_ADD: + { + e2NodeAddItem = (E2nodeComponentConfigAddition_Item_t*)e2NodeCfg; + interfaceType = &e2NodeAddItem->e2nodeComponentInterfaceType; + componentID = &e2NodeAddItem->e2nodeComponentID; + configuration = &e2NodeAddItem->e2nodeComponentConfiguration; + e2NodeConfig = e2NodeComponentInfo->addConfiguration; + break; + } + case CONFIG_MOD: + { + e2NodeUpdateItem = (E2nodeComponentConfigUpdate_Item_t *) e2NodeCfg; + interfaceType = &e2NodeUpdateItem->e2nodeComponentInterfaceType; + componentID = &e2NodeUpdateItem->e2nodeComponentID; + configuration = &e2NodeUpdateItem->e2nodeComponentConfiguration; + e2NodeConfig = e2NodeComponentInfo->updateConfiguration; + 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< e2NodeRemoveList->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(e2NodeRemoveList->list.array[arrIdx], sizeof(E2nodeComponentConfigRemoval_ItemIEs_t)); - if(e2NodeRemoveList->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 BuildE2NodeConfigRemoveList %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); - e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].actionType, &node); - if(!e2NodeComponentInfo) + if(componentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf == NULLP) { - DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); + 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; + } - 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) + /* E2 Node Component Request Part */ + if(e2NodeConfig->componentRequestPart) + { + configuration->e2nodeComponentRequestPart.size = e2NodeConfig->reqBufSize ; + DU_ALLOC(configuration->e2nodeComponentRequestPart.buf,\ + configuration->e2nodeComponentRequestPart.size); + if(configuration->e2nodeComponentRequestPart.buf == NULLP) { - DU_LOG("\nERROR --> E2AP : Failed to fill the E2 node configuration"); + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); return RFAILED; } + memcpy(configuration->e2nodeComponentRequestPart.buf,\ + e2NodeConfig->componentRequestPart, configuration->\ + e2nodeComponentRequestPart.size); + } + else + { + DU_LOG("\nERROR --> E2AP: componentRequestPart is null "); + return RFAILED; + } + + /* E2 Node Component Response Part */ + if(e2NodeConfig->componentResponsePart) + { + configuration->e2nodeComponentResponsePart.size = e2NodeConfig->rspBufSize; + DU_ALLOC(configuration->e2nodeComponentResponsePart.buf, configuration->e2nodeComponentResponsePart.size); + if(configuration->e2nodeComponentResponsePart.buf == NULLP) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at line %d",__func__,__LINE__); + return RFAILED; + } + memcpy(configuration->e2nodeComponentResponsePart.buf, e2NodeConfig->componentResponsePart, configuration->\ + e2nodeComponentResponsePart.size); + } + else + { + DU_LOG("\nERROR --> E2AP: componentResponsePart is null"); + return RFAILED; } + return ROK; } + /******************************************************************* * - * @brief deallocation of E2SM_KPM_RANfunction_Description_t + * @brief Builds E2 node config addition list * * @details * - * Function : freeE2smKpmRanFunctionDefinition + * Function : BuildE2NodeConfigAddList * - * Functionality: deallocation of E2SM_KPM_RANfunction_Description_t + * Functionality: Building E2 node config addition list * - * @params[in] E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition - * @return void + * @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 * ******************************************************************/ -void freeE2smKpmRanFunctionDefinition(E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition) +uint8_t BuildE2NodeConfigAddList(E2nodeComponentConfigAddition_List_t *e2NodeAddList, uint8_t procedureCode, uint16_t count, E2NodeConfigItem *e2NodeList) { - MeasurementInfo_Action_Item_t *measInfoList; - uint8_t eventTriggerIdx, reportStyleIdx, measInfoIdx; - RANfunction_Name_t *ranFuncName; - struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle; - struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *eventTriggerStyle; - if(ranFunctionDefinition) + 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) { - ranFuncName = &ranFunctionDefinition->ranFunction_Name; - /* Free RAN function Name */ - DU_FREE(ranFuncName->ranFunction_ShortName.buf, ranFuncName->ranFunction_ShortName.size); - DU_FREE(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size); - DU_FREE(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + return RFAILED; + } - /* Sequence of Event Trigger styles */ - eventTriggerStyle = ranFunctionDefinition->ric_EventTriggerStyle_List; - if(eventTriggerStyle) + for(arrIdx = 0; arrIdx< e2NodeAddList->list.count; arrIdx++) + { + DU_ALLOC(e2NodeAddList->list.array[arrIdx], sizeof(E2nodeComponentConfigAddition_ItemIEs_t)); + if(e2NodeAddList->list.array[arrIdx] == NULLP) { - if(eventTriggerStyle->list.array) - { - for(eventTriggerIdx =0;eventTriggerIdxlist.count; eventTriggerIdx++) - { - if(eventTriggerStyle->list.array[eventTriggerIdx]) - { - DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.buf,\ - eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.size); - DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx], sizeof(RIC_EventTriggerStyle_Item_t )); - } - } - DU_FREE(eventTriggerStyle->list.array, eventTriggerStyle->list.size) - } - DU_FREE(eventTriggerStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List)); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigAddList %d",__LINE__); + return RFAILED; } - /* Sequence of Report styles */ - ricReportStyle = ranFunctionDefinition->ric_ReportStyle_List; - if(ricReportStyle) + if(procedureCode == ProcedureCodeE2_id_E2setup) { - if(ricReportStyle->list.array) + /* Getting all of the E2 node configuration's information from DuCb one by one*/ + if(arrIdx == 0) { - for(reportStyleIdx =0;reportStyleIdxlist.count; reportStyleIdx++) - { - if(ricReportStyle->list.array[reportStyleIdx]) - { - if(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf) - { - DU_FREE(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf,\ - ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.size); - } - if(ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array) - { - for(measInfoIdx=0; measInfoIdxlist.array[reportStyleIdx]->measInfo_Action_List.list.count; \ - measInfoIdx++) - { - measInfoList = ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array[measInfoIdx]; - if(measInfoList) - { - DU_FREE(measInfoList->measID, sizeof(long)); - DU_FREE(measInfoList->measName.buf, measInfoList->measName.size); - DU_FREE(measInfoList,sizeof(MeasurementInfo_Action_Item_t)); - } - } - DU_FREE(measInfoList,ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.size); - } - DU_FREE(ricReportStyle->list.array[reportStyleIdx], sizeof(RIC_ReportStyle_Item_t)); - } - } - DU_FREE(ricReportStyle->list.array, ricReportStyle->list.size); + CM_LLIST_FIRST_NODE(&duCb.e2apDb.e2NodeComponentList, node); } - DU_FREE(ricReportStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List)); + 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].componentId, &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; } - DU_FREE(ranFunctionDefinition, sizeof(E2SM_KPM_RANfunction_Description_t)); } + return ROK; } /******************************************************************* * - * @brief fill the e2sm ric report style + * @brief Builds E2 node config update list * * @details * - * Function : fillRicReportStyle + * Function : BuildE2NodeConfigUpdateList * - * Functionality: fill the report style + * 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 * - * @params[in] RanFunction *ranFuncDb, struct - * E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle * @return ROK - success * RFAILED - failure * ******************************************************************/ -uint8_t fillRicReportStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle) + +uint8_t BuildE2NodeConfigUpdateList(E2nodeComponentConfigUpdate_List_t *e2NodeUpdateList, uint16_t count, E2NodeConfigItem *updateE2Node) { - uint8_t styleIdx, measInfoIdx; - MeasurementInfo_Action_List_t *measInfo; - CmLList *node; - - ricReportStyle->list.count = ranFuncDb->numOfReportStyleSupported; - ricReportStyle->list.size = ricReportStyle->list.count * sizeof(RIC_ReportStyle_Item_t*); - DU_ALLOC(ricReportStyle->list.array, ricReportStyle->list.size); - if(!ricReportStyle->list.array) + 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: Memory allocation failed for ranFuncDefinition %d",__LINE__); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); return RFAILED; } - for(styleIdx =0;styleIdxlist.count; styleIdx++) + for(arrIdx = 0; arrIdx< e2NodeUpdateList->list.count; arrIdx++) { - DU_ALLOC(ricReportStyle->list.array[styleIdx], sizeof(RIC_ReportStyle_Item_t)); - if(!ricReportStyle->list.array[styleIdx]) + DU_ALLOC(e2NodeUpdateList->list.array[arrIdx], sizeof(E2nodeComponentConfigUpdate_ItemIEs_t)); + if(e2NodeUpdateList->list.array[arrIdx] == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__); + DU_LOG("\nERROR --> E2AP: Memory allocation failed for BuildE2NodeConfigUpdateList %d",__LINE__); return RFAILED; } - - /* RIC Report Style Type */ - ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType; - - /* RIC Report Style Format Type */ - ricReportStyle->list.array[styleIdx]->ric_ActionFormat_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType; - - /* RIC Report Style Name */ - ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size = strlen(ranFuncDb->reportStyleList[styleIdx].reportStyle.name); - DU_ALLOC(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf,\ - ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size); - if(!ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf) + + e2NodeComponentInfo= fetchE2NodeComponentInfo(updateE2Node[arrIdx].interface, updateE2Node[arrIdx].componentId, &node); + if(!e2NodeComponentInfo) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__); + DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); return RFAILED; } - memcpy(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf, ranFuncDb->reportStyleList[styleIdx].reportStyle.name,\ - ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size); - /* RIC Indication Header Format Type*/ - ricReportStyle->list.array[styleIdx]->ric_IndicationHeaderFormat_Type = ranFuncDb->ricIndicationHeaderFormat; + 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; - /* RIC Indication Message Format Type*/ - ricReportStyle->list.array[styleIdx]->ric_IndicationMessageFormat_Type = ranFuncDb->ricIndicationMessageFormat; - - /* Measurement Info Action List */ - CmLListCp measInfoList =ranFuncDb->reportStyleList[styleIdx].measurementInfoList; - if(!measInfoList.count) + if(fillE2NodeConfig((PTR)e2NodeUpdateItem, e2NodeComponentInfo, CONFIG_MOD) != ROK) { - continue; + DU_LOG("\nERROR --> E2AP : Failed to fill the E2 node configuration"); + return RFAILED; } - CM_LLIST_FIRST_NODE(&ranFuncDb->reportStyleList[styleIdx].measurementInfoList, node); - measInfo = &ricReportStyle->list.array[styleIdx]->measInfo_Action_List; + } + return ROK; - measInfo->list.count = measInfoList.count; - measInfo->list.size = measInfoList.count*sizeof(MeasurementInfo_Action_Item_t*); +} + + +/******************************************************************* + * + * @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].componentId, &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 + * + * @details + * + * Function : freeE2smKpmRanFunctionDefinition + * + * Functionality: deallocation of E2SM_KPM_RANfunction_Description_t + * + * @params[in] E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition + * @return void + * + ******************************************************************/ + +void freeE2smKpmRanFunctionDefinition(E2SM_KPM_RANfunction_Description_t *ranFunctionDefinition) +{ + MeasurementInfo_Action_Item_t *measInfoList; + uint8_t eventTriggerIdx, reportStyleIdx, measInfoIdx; + RANfunction_Name_t *ranFuncName; + struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle; + struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List *eventTriggerStyle; + if(ranFunctionDefinition) + { + ranFuncName = &ranFunctionDefinition->ranFunction_Name; + /* Free RAN function Name */ + DU_FREE(ranFuncName->ranFunction_ShortName.buf, ranFuncName->ranFunction_ShortName.size); + DU_FREE(ranFuncName->ranFunction_E2SM_OID.buf, ranFuncName->ranFunction_E2SM_OID.size); + DU_FREE(ranFuncName->ranFunction_Description.buf, ranFuncName->ranFunction_Description.size); + + /* Sequence of Event Trigger styles */ + eventTriggerStyle = ranFunctionDefinition->ric_EventTriggerStyle_List; + if(eventTriggerStyle) + { + if(eventTriggerStyle->list.array) + { + for(eventTriggerIdx =0;eventTriggerIdxlist.count; eventTriggerIdx++) + { + if(eventTriggerStyle->list.array[eventTriggerIdx]) + { + DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.buf,\ + eventTriggerStyle->list.array[eventTriggerIdx]->ric_EventTriggerStyle_Name.size); + DU_FREE(eventTriggerStyle->list.array[eventTriggerIdx], sizeof(RIC_EventTriggerStyle_Item_t )); + } + } + DU_FREE(eventTriggerStyle->list.array, eventTriggerStyle->list.size) + } + DU_FREE(eventTriggerStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_EventTriggerStyle_List)); + } + + /* Sequence of Report styles */ + ricReportStyle = ranFunctionDefinition->ric_ReportStyle_List; + if(ricReportStyle) + { + if(ricReportStyle->list.array) + { + for(reportStyleIdx =0;reportStyleIdxlist.count; reportStyleIdx++) + { + if(ricReportStyle->list.array[reportStyleIdx]) + { + if(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf) + { + DU_FREE(ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.buf,\ + ricReportStyle->list.array[reportStyleIdx]->ric_ReportStyle_Name.size); + } + if(ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array) + { + for(measInfoIdx=0; measInfoIdxlist.array[reportStyleIdx]->measInfo_Action_List.list.count; \ + measInfoIdx++) + { + measInfoList = ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.array[measInfoIdx]; + if(measInfoList) + { + DU_FREE(measInfoList->measID, sizeof(long)); + DU_FREE(measInfoList->measName.buf, measInfoList->measName.size); + DU_FREE(measInfoList,sizeof(MeasurementInfo_Action_Item_t)); + } + } + DU_FREE(measInfoList,ricReportStyle->list.array[reportStyleIdx]->measInfo_Action_List.list.size); + } + DU_FREE(ricReportStyle->list.array[reportStyleIdx], sizeof(RIC_ReportStyle_Item_t)); + } + } + DU_FREE(ricReportStyle->list.array, ricReportStyle->list.size); + } + DU_FREE(ricReportStyle, sizeof(struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List)); + } + DU_FREE(ranFunctionDefinition, sizeof(E2SM_KPM_RANfunction_Description_t)); + } +} + +/******************************************************************* + * + * @brief fill the e2sm ric report style + * + * @details + * + * Function : fillRicReportStyle + * + * Functionality: fill the report style + * + * @params[in] RanFunction *ranFuncDb, struct + * E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t fillRicReportStyle(RanFunction *ranFuncDb, struct E2SM_KPM_RANfunction_Description__ric_ReportStyle_List *ricReportStyle) +{ + uint8_t styleIdx, measInfoIdx; + MeasurementInfo_Action_List_t *measInfo; + CmLList *node; + + ricReportStyle->list.count = ranFuncDb->numOfReportStyleSupported; + ricReportStyle->list.size = ricReportStyle->list.count * sizeof(RIC_ReportStyle_Item_t*); + DU_ALLOC(ricReportStyle->list.array, ricReportStyle->list.size); + if(!ricReportStyle->list.array) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed for ranFuncDefinition %d",__LINE__); + return RFAILED; + } + + for(styleIdx =0;styleIdxlist.count; styleIdx++) + { + DU_ALLOC(ricReportStyle->list.array[styleIdx], sizeof(RIC_ReportStyle_Item_t)); + if(!ricReportStyle->list.array[styleIdx]) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__); + return RFAILED; + } + + /* RIC Report Style Type */ + ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.styleType; + + /* RIC Report Style Format Type */ + ricReportStyle->list.array[styleIdx]->ric_ActionFormat_Type = ranFuncDb->reportStyleList[styleIdx].reportStyle.formatType; + + /* RIC Report Style Name */ + ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size = strlen(ranFuncDb->reportStyleList[styleIdx].reportStyle.name); + DU_ALLOC(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf,\ + ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size); + if(!ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf) + { + DU_LOG("\nERROR --> E2AP: Memory allocation failed in function %s at %d",__func__,__LINE__); + return RFAILED; + } + memcpy(ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.buf, ranFuncDb->reportStyleList[styleIdx].reportStyle.name,\ + ricReportStyle->list.array[styleIdx]->ric_ReportStyle_Name.size); + + /* RIC Indication Header Format Type*/ + ricReportStyle->list.array[styleIdx]->ric_IndicationHeaderFormat_Type = ranFuncDb->ricIndicationHeaderFormat; + + /* RIC Indication Message Format Type*/ + ricReportStyle->list.array[styleIdx]->ric_IndicationMessageFormat_Type = ranFuncDb->ricIndicationMessageFormat; + + /* Measurement Info Action List */ + CmLListCp measInfoList =ranFuncDb->reportStyleList[styleIdx].measurementInfoList; + if(!measInfoList.count) + { + continue; + } + + CM_LLIST_FIRST_NODE(&ranFuncDb->reportStyleList[styleIdx].measurementInfoList, node); + measInfo = &ricReportStyle->list.array[styleIdx]->measInfo_Action_List; + + measInfo->list.count = measInfoList.count; + measInfo->list.size = measInfoList.count*sizeof(MeasurementInfo_Action_Item_t*); DU_ALLOC(measInfo->list.array, measInfo->list.size); if(!measInfo->list.array) { @@ -1524,8 +1992,8 @@ void FreeE2SetupReq(E2AP_PDU_t *e2apMsg) uint8_t BuildAndSendE2SetupReq() { uint8_t arrIdx = 0, elementCnt=0; - uint8_t transId = 0, ret = ROK; - bool memAllocFailed; + uint8_t transId = 0, ret = RFAILED; + bool memAllocFailed = false; E2AP_PDU_t *e2apMsg = NULLP; E2setupRequest_t *e2SetupReq = NULLP; asn_enc_rval_t encRetVal; /* Encoder return value */ @@ -2115,32 +2583,131 @@ void freeAperDecodingOfE2SetupRsp(E2setupResponse_t *e2SetRspMsg) } } } + /****************************************************************** * - * @brief Processes E2 Setup Response sent by RIC + * @brief handling of e2 noe config update ack ies * * @details * - * Function : procE2SetupRsp - * - * Functionality: Processes E2 Setup Response sent by RIC + * Function :handleE2NodeConfigUpdateAckIes * - * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure + * Functionality: handling of e2 noe config update ack ies * - * ****************************************************************/ + * @params[in] + * Pointer to the E2 Node cfg + * Procedure code + * @return void +******************************************************************/ -uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) +void handleE2NodeConfigUpdateAckIes(PTR e2NodeCfg, uint8_t procedureCode) { - uint8_t arrIdx =0, transId=0, idx=0; - uint32_t recvBufLen; - E2setupResponse_t *e2SetRspMsg=NULL; - CmLList *node=NULL; - E2NodeComponent *e2NodeComponentInfo=NULL; - E2nodeComponentConfigAdditionAck_List_t *e2NodeCfgAckList=NULL; - E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAddAckItem=NULL; - + CmLList *node=NULLP; + E2NodeComponent *e2NodeComponentInfo=NULLP; + E2nodeComponentID_t *e2nodeComponentID=NULLP; + E2nodeComponentConfigRemovalAck_Item_t *removalAckItem=NULLP; + E2nodeComponentConfigUpdateAck_Item_t *updateAckItem=NULLP; + E2nodeComponentConfigAdditionAck_Item_t *additionAckItem=NULLP; + + switch(procedureCode) + { + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + additionAckItem = (E2nodeComponentConfigAdditionAck_Item_t *)e2NodeCfg; + e2nodeComponentID = &additionAckItem->e2nodeComponentID; + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + updateAckItem = (E2nodeComponentConfigUpdateAck_Item_t*) e2NodeCfg; + e2nodeComponentID = &updateAckItem->e2nodeComponentID; + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + removalAckItem= (E2nodeComponentConfigRemovalAck_Item_t*)e2NodeCfg; + e2nodeComponentID = &removalAckItem->e2nodeComponentID; + break; + } + } + + switch(e2nodeComponentID->present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, e2nodeComponentID->choice.e2nodeComponentInterfaceTypeF1->gNB_DU_ID.buf[0], &node); + if(!e2NodeComponentInfo) + { + DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); + return; + } + break; + } + default: + break; + } + + switch(procedureCode) + { + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig)); + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig)); + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node); + if(e2NodeComponentInfo->addConfiguration) + { + DU_FREE(e2NodeComponentInfo->addConfiguration->componentRequestPart, e2NodeComponentInfo->addConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration->componentResponsePart, e2NodeComponentInfo->addConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->addConfiguration, sizeof(E2NodeConfig)); + } + if(e2NodeComponentInfo->updateConfiguration) + { + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentRequestPart, e2NodeComponentInfo->updateConfiguration->reqBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration->componentResponsePart, e2NodeComponentInfo->updateConfiguration->rspBufSize); + DU_FREE(e2NodeComponentInfo->updateConfiguration, sizeof(E2NodeConfig)); + } + DU_FREE(node, sizeof(CmLList)); + break; + } + } +} + +/****************************************************************** + * + * @brief Processes E2 Setup Response sent by RIC + * + * @details + * + * Function : procE2SetupRsp + * + * Functionality: Processes E2 Setup Response sent by RIC + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return void + * + * ****************************************************************/ + +void procE2SetupRsp(E2AP_PDU_t *e2apMsg) +{ + bool invalidTransId = false; + uint8_t arrIdx =0, transId=0, idx=0; + uint32_t recvBufLen; + E2setupResponse_t *e2SetRspMsg=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 e2SetRspMsg = &e2apMsg->choice.successfulOutcome->value.choice.E2setupResponse; @@ -2160,7 +2727,7 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) else { DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - return RFAILED; + invalidTransId = true; } break; } @@ -2170,60 +2737,47 @@ uint8_t procE2SetupRsp(E2AP_PDU_t *e2apMsg) /* To store the Ric Id Params */ recvBufLen = sizeof(e2SetRspMsg->protocolIEs.list.array[arrIdx]->value\ .choice.GlobalRIC_ID.pLMN_Identity.size); - memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\ - ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen); + memcpy(&duCb.e2apDb.ricId.plmnId, e2SetRspMsg->protocolIEs.list.array[arrIdx]\ + ->value.choice.GlobalRIC_ID.pLMN_Identity.buf, recvBufLen); bitStringToInt(&e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.GlobalRIC_ID.ric_ID, &duCb.e2apDb.ricId); /*TODO : duCb.e2apDb.ricId.plmnId memory to be deallocated after the usage */ break; } case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: - { - e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; - for(idx =0; idx list.count; idx++) { - e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx]; - switch(e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present) + e2NodeCfgAckList = &e2SetRspMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; + for(idx =0; idx list.count; idx++) { - case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: - { - e2NodeComponentInfo = fetchE2NodeComponentInfo(F1, E2_NODE_COMPONENT_ADD, &node); - if(!e2NodeComponentInfo) - { - DU_LOG("\nERROR --> E2AP : Received null e2NodeComponentInfo at line number %d",__LINE__); - return RFAILED; - } - else - { - cmLListDelFrm(&duCb.e2apDb.e2NodeComponentList, node); - DU_FREE(e2NodeComponentInfo->componentRequestPart, e2NodeComponentInfo->reqBufSize); - DU_FREE(e2NodeComponentInfo->componentResponsePart, e2NodeComponentInfo->rspBufSize); - DU_FREE(e2NodeComponentInfo, sizeof(E2NodeComponent)); - DU_FREE(node, sizeof(CmLList)); - } - break; - } - default: - break; + e2NodeAddAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeCfgAckList->list.array[idx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAddAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck); } + break; } - break; - } default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in E2SetupRsp:%ld", - e2SetRspMsg->protocolIEs.list.array[arrIdx]->id); - break; + { + DU_LOG("\nERROR --> E2AP : Invalid IE received in E2SetupRsp:%ld", + e2SetRspMsg->protocolIEs.list.array[arrIdx]->id); + break; + } + } + + if(invalidTransId == true) + { + break; } } freeAperDecodingOfE2SetupRsp(e2SetRspMsg); - if(duSendE2NodeConfigurationUpdate() != ROK) + if(invalidTransId == false) { - DU_LOG("\nERROR --> E2AP : Failed to send E2 node config update"); - return RFAILED; + if(duSendE2NodeConfigurationUpdate() != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to send E2 node config update"); + } } - return ROK; } /******************************************************************* @@ -2477,8 +3031,8 @@ uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoLis { uint8_t elementIdx = 0; MeasurementInfoForAction *measInfoSupportedDb = NULLP; - MeasurementInfo *measInfoSubscribedDb = NULLP, *measInfoToDel = NULLP; - CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP, *measToDelNode = NULLP;; + MeasurementInfo *measInfoSubscribedDb = NULLP; + CmLList *supportedMeasNode = NULLP, *measToAddNode = NULLP; MeasurementInfoItem_t *measItem = NULLP; /* Validate Measurement list is supported by E2 node. @@ -2912,6 +3466,7 @@ uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) if(ret == ROK) { cmInitTimers(&(ricSubscriptionInfo->ricSubsReportTimer), 1); + ricSubscriptionInfo->action = CONFIG_ADD; /* Add RAN subcription detail to RAN function */ DU_ALLOC(ricSubscriptionNode, sizeof(CmLList)); @@ -4432,6 +4987,7 @@ void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg) * - Buld and send the E2 reset request msg to RIC * * @params[in] + * Reset cause * @return ROK - success * RFAILED - failure * @@ -4517,13 +5073,13 @@ uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause) encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode E2SetupRequest structure (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode reset request structure (at %s)\n",\ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); break; } else { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2SetupRequest\n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for reset request\n"); #ifdef DEBUG_ASN_PRINT for(int i=0; i< encBufSize; i++) { @@ -4605,14 +5161,15 @@ void freeAperDecodingOfE2ResetRsp(ResetResponseE2_t *resetResponse) * Functionality: Processes E2 Reset Response sent by RIC * * @params[in] E2AP_PDU_t ASN decoded E2AP message - * @return ROK - success - * RFAILED - failure + * @return void * * ****************************************************************/ -uint8_t procResetResponse(E2AP_PDU_t *e2apMsg) +void procResetResponse(E2AP_PDU_t *e2apMsg) { - uint8_t ieIdx =0, transId; - ResetResponseE2_t *resetResponse; + bool invalidTransId=false; + uint8_t ieIdx =0, transId =0; + uint16_t ranFuncIdx=0; + ResetResponseE2_t *resetResponse =NULLP; DU_LOG("\nINFO --> E2AP : E2 Reset Response received"); resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2;; @@ -4622,36 +5179,47 @@ uint8_t procResetResponse(E2AP_PDU_t *e2apMsg) switch(resetResponse->protocolIEs.list.array[ieIdx]->id) { case ProtocolIE_IDE2_id_TransactionID: - transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; - if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \ - (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode)) { - memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); + transId = resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID; + if((duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].transactionId == transId) && \ + (duCb.e2apDb.e2TransInfo.e2InitTransaction[transId].procedureCode == e2apMsg->choice.successfulOutcome->procedureCode)) + { + memset(&duCb.e2apDb.e2TransInfo.e2InitTransaction[transId], 0, sizeof(E2TransInfo)); + } + else + { + DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); + invalidTransId = true; + } + break; } - else + case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: { - DU_LOG("\nERROR --> E2AP : Invalid transaction id [%d]", transId); - return RFAILED; + for(ranFuncIdx=0; ranFuncIdx0) + { + deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList)); + memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo)); + } + } + break; } - break; - case ProtocolIE_IDE2_id_CriticalityDiagnosticsE2: - /* As per ORAN WG3 E2AP spec v3.0, section 9.2.2 - Criticality Diagnostics IE is sent by Near-RT RIC when parts of a received message i.e. - Reset Request in this case, have not been comprehended or were missing, or if the message - contained logical errors. - - Processing of this ID should be implemented when negative call flows are to be supported. - */ - break; default: - DU_LOG("\nERROR --> E2AP : Invalid IE received in E2 Reset Response : %ld", - resetResponse->protocolIEs.list.array[ieIdx]->id); - break; + { + DU_LOG("\nERROR --> E2AP : Invalid IE received in E2 Reset Response : %ld", + resetResponse->protocolIEs.list.array[ieIdx]->id); + break; + } + } + + if(invalidTransId == true) + { + break; } } freeAperDecodingOfE2ResetRsp(resetResponse); - return ROK; } /****************************************************************** @@ -5503,33 +6071,26 @@ uint8_t duSendE2NodeConfigurationUpdate() { e2NodeComponentInfo = (E2NodeComponent*)node->node; - if(e2NodeComponentInfo->componentRequestPart && e2NodeComponentInfo->componentResponsePart) + if(e2NodeComponentInfo->addConfiguration) { - switch(e2NodeComponentInfo->componentActionType) - { - case E2_NODE_COMPONENT_ADD: - { - e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType; - e2NodeList.addE2Node[e2NodeList.addE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; - e2NodeList.removeE2NodeCount++; - break; - } - case E2_NODE_COMPONENT_UPDATE: - { - e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType; - e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; - e2NodeList.updateE2NodeCount++; - break; - - } - case E2_NODE_COMPONENT_DEL: - { - e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType; - e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].actionType = e2NodeComponentInfo->componentActionType; - e2NodeList.removeE2NodeCount++; - break; - } - } + e2NodeList.addE2Node[e2NodeList.addE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.addE2Node[e2NodeList.addE2NodeCount].componentId= e2NodeComponentInfo->componentId; + e2NodeList.addE2NodeCount++; + break; + } + if(e2NodeComponentInfo->updateConfiguration) + { + e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.updateE2Node[e2NodeList.updateE2NodeCount].componentId= e2NodeComponentInfo->componentId; + e2NodeList.updateE2NodeCount++; + break; + } + if(e2NodeComponentInfo->deleteConfiguration == true) + { + e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].interface = e2NodeComponentInfo->interfaceType; + e2NodeList.removeE2Node[e2NodeList.removeE2NodeCount].componentId = e2NodeComponentInfo->componentId; + e2NodeList.removeE2NodeCount++; + break; } node = node->next; } @@ -5730,810 +6291,1593 @@ uint8_t FillActionReqdToBeRmvList(RICactions_RequiredToBeRemoved_List_t *actionT DU_ALLOC(actionToBeRmvList->list.array[arrIdx], sizeof(RICaction_RequiredToBeRemoved_ItemIEs_t)); if(!actionToBeRmvList->list.array[arrIdx]) { - DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); - return RFAILED; + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; + } + actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx]; + + actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item; + actionToBeRmv->criticality = CriticalityE2_reject; + actionToBeRmv->value.present = \ + RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item; + actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \ + ricSubscription->actionSequence[actionIdx].actionId; + fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \ + ricSubscription->actionSequence[actionIdx].failureCause); + + arrIdx++; + } + } + + return ROK; +} + +/******************************************************************* + * + * @brief Fill RIC Subscription Modification Required IEs + * + * @details + * + * Function : FillRicSubsModRequired + * + * Functionality: Fill RIC Subscription Modification Required IEs + * + * @param RIC Subscription Modification Required IEs to be filled + * RIC Subscription DB + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription) +{ + uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0; + uint8_t numActionsMod = 0, numActionsRmv = 0; + RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP; + RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList = NULLP; + +/* Unused in case of E2SM-KPM */ +#if 0 + RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP; +#endif + + /* Count number of Actions to be modified or deleted */ + for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + { + if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD) + numActionsMod++; + else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL) + numActionsRmv++; + } + + /* Count number of IEs to be added to messages */ + elementCnt = 2; + if(numActionsMod) + elementCnt++; + if(numActionsRmv) + elementCnt++; + + ricSubsModReqd->protocolIEs.list.count = elementCnt; + ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *); + DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size); + if(!ricSubsModReqd->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; + } + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t)); + if(!ricSubsModReqd->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + return RFAILED; + } + } + + /* RIC Request ID */ + ieIdx = 0; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID; + ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId; + ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId; + + /* RAN Function ID */ + ieIdx++; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID; + ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId; + +/* A RIC Subscription includes RIC subsequent action only for RIC Insert service. + * However, E2SM-KPM supports only RIC Report service. + * Hence there is no subsequent action in RIC subscription that may require modification. + * So commenting the action-modification IEs for the time being + */ +#if 0 + /* RIC Actions Required to be Modified */ + if(numActionsMod) + { + ieIdx++; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = \ + RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List; + actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List; + + if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill actions required to be modified list", __func__); + return RFAILED; + } + } +#endif + + /* RIC Actions Required to be removed */ + if(numActionsRmv) + { + ieIdx++; + ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; + ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List; + ricSubsModReqdIe->criticality = CriticalityE2_reject; + ricSubsModReqdIe->value.present = \ + RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List; + actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List; + + if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill actions required to be removed list", __func__); + return RFAILED; + } + } + + return ROK; +} + +/******************************************************************* + * + * @brief Builds and Send RIC Subscription Modification Required + * message + * + * @details + * + * Function : BuildAndSendRicSubsModRequired + * + * Functionality: Builds and Send RIC Subscription Modification + * Required message + * + * @param RIC Subscription DB + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription) +{ + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionModificationRequired_t *ricSubsModReqd = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Modification Required \n"); + while(true) + { + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + break; + } + + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); + break; + } + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired; + + ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired; + + if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__); + break; + } + + /* Encode */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); + } +#endif + } + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nERROR --> E2AP : Sending RIC Subscription Modification Required failed"); + } + + ret = ROK; + break; + } + + /* Free RIC Subscription modification required */ + FreeRicSubsModRequired(e2apMsg); + return ret; +} + +/******************************************************************* + * + * @brief Free APER decoding of RIC Subscription Modification Confirm + * + * @details + * + * Function : freeAperDecodingOfRicSubsModConfirm + * + * Functionality: Free APER decoding of RIC Subscription + * Modification Confirm + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx = 0, arrIdx=0; + RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP; + RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP; + RICactions_ConfirmedForModification_List_t *modCfmList = NULLP; + RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP; + RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP; + RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP; + + if(e2apMsg && e2apMsg->choice.successfulOutcome) + { + ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm; + if(ricSubsModCfm->protocolIEs.list.array) + { + for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++) + { + if(ricSubsModCfm->protocolIEs.list.array[ieIdx]) + { + ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx]; + switch(ricSubsModCfmIe->id) + { + case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List: + { + modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List; + if(modCfmList->list.array) + { + for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++) + { + if(modCfmList->list.array[arrIdx]) + free(modCfmList->list.array[arrIdx]); + } + free(modCfmList->list.array); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List: + { + modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List; + if(modRefusedList->list.array) + { + for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++) + { + if(modRefusedList->list.array[arrIdx]) + free(modRefusedList->list.array[arrIdx]); + } + free(modRefusedList->list.array); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List: + { + rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List; + if(rmvCfmList->list.array) + { + for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++) + { + if(rmvCfmList->list.array[arrIdx]) + free(rmvCfmList->list.array[arrIdx]); + } + free(rmvCfmList->list.array); + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List: + { + rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List; + if(rmvFailList->list.array) + { + for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++) + { + if(rmvFailList->list.array[arrIdx]) + free(rmvFailList->list.array[arrIdx]); + } + free(rmvFailList->list.array); + } + break; + } + + default: + break; + + } + free(ricSubsModCfmIe); + } + } + free(ricSubsModCfm->protocolIEs.list.array); + } + } +} + +/******************************************************************* + * + * @brief Process RIC Subscription Modification Confirm Message + * + * @details + * + * Function : procRicSubscriptionModificationConfirm + * + * Functionality: Process RIC Subscription Modification Confirm + * Message received from RIC. + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) +{ + uint8_t actionId = 0, ieIdx = 0, arrIdx = 0; + uint16_t ranFuncId = 0; + bool procFailure = false; + RicRequestId ricReqId; + RanFunction *ranFuncDb = NULLP; + CmLList *ricSubsNode = NULLP; + RicSubscription *ricSubsDb = NULLP; + ActionInfo *actionDb = NULLP; + + RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP; + RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP; + +/* Not used in case of E2SM-KPM */ +#if 0 + RICactions_ConfirmedForModification_List_t *modCfmList = NULLP; + RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP; + + RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP; + RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP; +#endif + + RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP; + RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP; + + RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP; + RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP; + + DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Modification Confirm", __func__); + + do{ + if(!e2apMsg) + { + DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + break; + } + + if(!e2apMsg->choice.successfulOutcome) + { + DU_LOG("\nERROR --> E2AP : %s: Successful Outcome in E2AP message is NULL", __func__); + break; + } + + ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm; + if(!ricSubsModCfm->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); + break; + } + + for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++) + { + if(!ricSubsModCfm->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + break; + } + + ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx]; + switch(ricSubsModCfmIe->id) + { + case ProtocolIE_IDE2_id_RICrequestID: + { + memset(&ricReqId, 0, sizeof(RicRequestId)); + ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID; + break; + } + + case ProtocolIE_IDE2_id_RANfunctionID: + { + ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID; + ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId); + if(!ranFuncDb) + { + DU_LOG("\nERROR --> E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId); + procFailure = true; + break; + } + + ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); + if(!ricSubsDb) + { + DU_LOG("\nERROR --> E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\ + __func__, ricReqId.requestorId, ricReqId.instanceId); + procFailure = true; + break; + } + + break; + } + +/* A RIC Subscription includes RIC subsequent action only for RIC Insert service. + * However, E2SM-KPM supports only RIC Report service. + * Hence there is no subsequent action in RIC subscription that may require modification. + * So commenting the action-modification IEs for the time being + */ +#if 0 + case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List: + { + modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List; + for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++) + { + modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx]; + actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID; + + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + actionDb->action = CONFIG_UNKNOWN; + /* Further handling can be added here in future once the + * use case of this procedure is identified */ + } + actionDb = NULLP; + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List: + { + modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List; + for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++) + { + modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx]; + actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + /* Spec doesnt mention if in case of failure, DU should retry for modify action + * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN + */ + actionDb->action = CONFIG_UNKNOWN; + } + actionDb = NULLP; + } + break; + } +#endif + + case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List: + { + rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List; + for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++) + { + rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx]; + actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + deleteActionSequence(actionDb); + actionDb =NULLP; + ricSubsDb->numOfActions--; + /* Further handling can include : + * Deletion of this action from all DU layers + */ + } + actionDb = NULLP; + } + break; + } + + case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List: + { + rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List; + for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++) + { + rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx]; + actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID; + actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); + if(!actionDb) + { + DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); + } + else + { + actionDb->action = CONFIG_UNKNOWN; + } + actionDb = NULLP; + } + break; + } + + default: + break; + } /* End of switch for Protocol IE Id */ + + if(procFailure) + break; + } /* End of for loop for Protocol IE list */ + + break; + }while(true); + + freeAperDecodingOfRicSubsModConfirm(e2apMsg); + return; +} + +/****************************************************************** +* @brief Deallocate the memory allocated for E2 Reset Response +* +* @details +* +* Function : FreeE2ResetResponse +* +* Functionality: +* - freeing the memory allocated for E2ResetResponse +* +* @params[in] E2AP_PDU_t *e2apMsg +* @return ROK - success +* RFAILED - failure +* +* ****************************************************************/ +void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg) +{ + uint8_t ieIdx =0; + ResetResponseE2_t *resetResponse; + + if(e2apMsg != NULLP) + { + if(e2apMsg->choice.successfulOutcome != NULLP) + { + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; + if(resetResponse->protocolIEs.list.array) + { + for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + { + if(resetResponse->protocolIEs.list.array[ieIdx]) + { + DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); + } + } + DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); } - actionToBeRmv = (RICaction_RequiredToBeRemoved_ItemIEs_t *)actionToBeRmvList->list.array[arrIdx]; - - actionToBeRmv->id = ProtocolIE_IDE2_id_RICaction_RequiredToBeRemoved_Item; - actionToBeRmv->criticality = CriticalityE2_reject; - actionToBeRmv->value.present = \ - RICaction_RequiredToBeRemoved_ItemIEs__value_PR_RICaction_RequiredToBeRemoved_Item; - actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.ricActionID = \ - ricSubscription->actionSequence[actionIdx].actionId; - fillE2Cause(&actionToBeRmv->value.choice.RICaction_RequiredToBeRemoved_Item.cause, \ - ricSubscription->actionSequence[actionIdx].failureCause); - arrIdx++; + DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); } - - return ROK; } /******************************************************************* * - * @brief Fill RIC Subscription Modification Required IEs + * @brief Buld and send the E2 Reset Response msg * * @details * - * Function : FillRicSubsModRequired + * Function : BuildAndSendE2ResetResponse * - * Functionality: Fill RIC Subscription Modification Required IEs + * Functionality: + * - Buld and send the E2 Reset Response Message * - * @param RIC Subscription Modification Required IEs to be filled - * RIC Subscription DB + * @params[in] Trans Id * @return ROK - success * RFAILED - failure * - ******************************************************************/ -uint8_t FillRicSubsModRequired(RICsubscriptionModificationRequired_t *ricSubsModReqd, RicSubscription *ricSubscription) + * ****************************************************************/ +uint8_t BuildAndSendResetResponse(uint8_t transId) { - uint8_t ieIdx = 0, elementCnt=0, actionIdx = 0; - uint8_t numActionsMod = 0, numActionsRmv = 0; - RICsubscriptionModificationRequired_IEs_t *ricSubsModReqdIe = NULLP; - RICactions_RequiredToBeModified_List_t *actionToBeModList = NULLP; - RICactions_RequiredToBeRemoved_List_t *actionToBeRmvList = NULLP; + uint8_t ieIdx = 0, elementCnt = 0; + uint8_t ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + ResetResponseE2_t *resetResponse; + asn_enc_rval_t encRetVal; /* Encoder return value */ - /* Count number of Actions to be modified or deleted */ - for(actionIdx = 0; actionIdx < MAX_RIC_ACTION; actionIdx++) + DU_LOG("\nINFO --> E2AP : Building E2 Reset Response Message\n"); + do { - if(ricSubscription->actionSequence[actionIdx].action == CONFIG_MOD) - numActionsMod++; - else if(ricSubscription->actionSequence[actionIdx].action == CONFIG_DEL) - numActionsRmv++; - } + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed"); + break; + } + e2apMsg->present = E2AP_PDU_PR_successfulOutcome; - /* Count number of IEs to be added to messages */ - elementCnt = 2; - if(numActionsMod) - elementCnt++; - if(numActionsRmv) - elementCnt++; + DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(e2apMsg->choice.successfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome"); + break; + } - ricSubsModReqd->protocolIEs.list.count = elementCnt; - ricSubsModReqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionModificationRequired_IEs_t *); - DU_ALLOC(ricSubsModReqd->protocolIEs.list.array, ricSubsModReqd->protocolIEs.list.size); - if(!ricSubsModReqd->protocolIEs.list.array) - { - DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); - return RFAILED; - } + e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset; + e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2; + resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; - for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) - { - DU_ALLOC(ricSubsModReqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionModificationRequired_IEs_t)); - if(!ricSubsModReqd->protocolIEs.list.array[ieIdx]) + elementCnt = 1; + resetResponse->protocolIEs.list.count = elementCnt; + resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *); + DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); + if(!resetResponse->protocolIEs.list.array) { - DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); - return RFAILED; + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array"); + break; } - } - /* RIC Request ID */ - ieIdx = 0; - ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; - ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICrequestID; - ricSubsModReqdIe->criticality = CriticalityE2_reject; - ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RICrequestID; - ricSubsModReqdIe->value.choice.RICrequestID.ricRequestorID = ricSubscription->requestId.requestorId; - ricSubsModReqdIe->value.choice.RICrequestID.ricInstanceID = ricSubscription->requestId.instanceId; + for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + { + DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); + if(!resetResponse->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element"); + break; + } + } + if(ieIdx < elementCnt) + break; - /* RAN Function ID */ - ieIdx++; - ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; - ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RANfunctionID; - ricSubsModReqdIe->criticality = CriticalityE2_reject; - ricSubsModReqdIe->value.present = RICsubscriptionModificationRequired_IEs__value_PR_RANfunctionID; - ricSubsModReqdIe->value.choice.RANfunctionID = ricSubscription->ranFuncId; + ieIdx = 0; + resetResponse->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; + resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; + resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID; + resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; -/* A RIC Subscription includes RIC subsequent action only for RIC Insert service. - * However, E2SM-KPM supports only RIC Report service. - * Hence there is no subsequent action in RIC subscription that may require modification. - * So commenting the action-modification IEs for the time being - */ -#if 0 - /* RIC Actions Required to be Modified */ - if(numActionsMod) - { - ieIdx++; - ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; - ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeModified_List; - ricSubsModReqdIe->criticality = CriticalityE2_reject; - ricSubsModReqdIe->value.present = \ - RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeModified_List; - actionToBeModList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeModified_List; + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); - if(FillActionReqdToBeModList(actionToBeModList, numActionsMod, ricSubscription) != ROK) + 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 : %s: Failed to fill actions required to be modified list", __func__); - return RFAILED; + DU_LOG("\nERROR --> E2AP : Could not encode E2 reset response structure (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Reset Response \n"); + for(int i=0; i< encBufSize; i++) + { + DU_LOG("%x",encBuf[i]); + } } - } -#endif - - /* RIC Actions Required to be removed */ - if(numActionsRmv) - { - ieIdx++; - ricSubsModReqdIe = ricSubsModReqd->protocolIEs.list.array[ieIdx]; - ricSubsModReqdIe->id = ProtocolIE_IDE2_id_RICactionsRequiredToBeRemoved_List; - ricSubsModReqdIe->criticality = CriticalityE2_reject; - ricSubsModReqdIe->value.present = \ - RICsubscriptionModificationRequired_IEs__value_PR_RICactions_RequiredToBeRemoved_List; - actionToBeRmvList = &ricSubsModReqdIe->value.choice.RICactions_RequiredToBeRemoved_List; - if(FillActionReqdToBeRmvList(actionToBeRmvList, numActionsRmv, ricSubscription) != ROK) + /* Sending msg */ + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { - DU_LOG("\nERROR --> E2AP : %s: Failed to fill actions required to be removed list", __func__); - return RFAILED; + DU_LOG("\nERROR --> E2AP : Failed to send E2 Reset Response"); + break; } - } - return ROK; + ret = ROK; + break; + }while(true); + + FreeE2ResetResponse(e2apMsg); + return ret; } -/******************************************************************* +/****************************************************************** * - * @brief Builds and Send RIC Subscription Modification Required - * message + * @brief Deallocation of memory allocated by aper decoder for reset req * * @details * - * Function : BuildAndSendRicSubsModRequired + * Function : freeAperDecodingOfE2ResetReq * - * Functionality: Builds and Send RIC Subscription Modification - * Required message + * Functionality: Deallocation of memory allocated by aper decoder for + * reset req * - * @param RIC Subscription DB - * @return ROK - success - * RFAILED - failure + * @params[in] Pointer to resetReq + * @return void * - ******************************************************************/ -uint8_t BuildAndSendRicSubsModRequired(RicSubscription *ricSubscription) + * ****************************************************************/ +void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq) { - uint8_t ret = RFAILED; - E2AP_PDU_t *e2apMsg = NULLP; - RICsubscriptionModificationRequired_t *ricSubsModReqd = NULLP; - asn_enc_rval_t encRetVal; /* Encoder return value */ - - DU_LOG("\nINFO --> E2AP : Building RIC Subscription Modification Required \n"); - while(true) - { - DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); - if(e2apMsg == NULLP) - { - DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); - break; - } - - e2apMsg->present = E2AP_PDU_PR_initiatingMessage; - DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); - if(e2apMsg->choice.initiatingMessage == NULLP) - { - DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed at line %d", __func__, __LINE__); - break; - } - e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; - e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionModificationRequired; - e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionModificationRequired; - - ricSubsModReqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionModificationRequired; - - if(FillRicSubsModRequired(ricSubsModReqd, ricSubscription) != ROK) - { - DU_LOG("\nERROR --> E2AP : %s: Failed to fill RIC Subscription Modification Required IEs", __func__); - break; - } - - /* Encode */ - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + uint8_t arrIdx=0; - memset(encBuf, 0, ENC_BUF_MAX_LEN); - encBufSize = 0; - encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); - if(encRetVal.encoded == ENCODE_FAIL) - { - DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Modifiction Required structure (at %s)\n",\ - encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); - break; - } - else + if(resetReq) + { + if(resetReq->protocolIEs.list.array) { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Modification Required \n"); -#ifdef DEBUG_ASN_PRINT - for(int i=0; i< encBufSize; i++) + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) { - printf("%x",encBuf[i]); + if(resetReq->protocolIEs.list.array[arrIdx]) + { + free(resetReq->protocolIEs.list.array[arrIdx]); + } } -#endif + free(resetReq->protocolIEs.list.array); } - if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + } +} + +/******************************************************************* + * + * @brief Process reset req received from RIC + * + * @details + * + * Function : procE2ResetRequest + * + * Functionality: Process reset req received from RIC + * + * @param E2AP_PDU_t *e2apMsg + * @return void + * + ******************************************************************/ + +void procE2ResetRequest(E2AP_PDU_t *e2apMsg) +{ + uint16_t ranFuncIdx=0; + uint8_t arrIdx =0, transId =0; + ResetRequestE2_t *resetReq; + + DU_LOG("\nINFO --> E2AP : E2 Reset request received"); + resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + + for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(resetReq->protocolIEs.list.array[arrIdx]->id) { - DU_LOG("\nERROR --> E2AP : Sending RIC Subscription Modification Required failed"); - } + case ProtocolIE_IDE2_id_TransactionID: + { + transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; + break; + } - ret = ROK; - break; + case ProtocolIE_IDE2_id_CauseE2: + { + for(ranFuncIdx=0; ranFuncIdx0) + { + deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList)); + memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo)); + } + } + break; + } + } } - - /* Free RIC Subscription modification required */ - FreeRicSubsModRequired(e2apMsg); - return ret; + if(BuildAndSendResetResponse(transId) != ROK) + { + DU_LOG("\nERROR --> E2AP : Failed to build and send reset response"); + } + freeAperDecodingOfE2ResetReq(resetReq); } /******************************************************************* * - * @brief Free APER decoding of RIC Subscription Modification Confirm + * @brief Free APER decoding of RIC Subscription Modification Refuse * * @details * - * Function : freeAperDecodingOfRicSubsModConfirm + * Function : freeAperDecodingOfRicSubsModRefuse * * Functionality: Free APER decoding of RIC Subscription - * Modification Confirm + * Modification Refuse * * @param E2AP Message PDU * @return void * ******************************************************************/ -void freeAperDecodingOfRicSubsModConfirm(E2AP_PDU_t *e2apMsg) +void freeAperDecodingOfRicSubsModRefuse(E2AP_PDU_t *e2apMsg) { - uint8_t ieIdx = 0, arrIdx=0; - RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP; - RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP; - RICactions_ConfirmedForModification_List_t *modCfmList = NULLP; - RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP; - RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP; - RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP; + uint8_t ieIdx =0; + RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP; - if(e2apMsg && e2apMsg->choice.successfulOutcome) + if(e2apMsg && e2apMsg->choice.unsuccessfulOutcome) { - ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm; - if(ricSubsModCfm->protocolIEs.list.array) + ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse; + if(ricSubsModRefuse->protocolIEs.list.array) { - for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++) + for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++) { - if(ricSubsModCfm->protocolIEs.list.array[ieIdx]) - { - ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx]; - switch(ricSubsModCfmIe->id) - { - case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List: - { - modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List; - if(modCfmList->list.array) - { - for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++) - { - if(modCfmList->list.array[arrIdx]) - free(modCfmList->list.array[arrIdx]); - } - free(modCfmList->list.array); - } - break; - } - - case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List: - { - modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List; - if(modRefusedList->list.array) - { - for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++) - { - if(modRefusedList->list.array[arrIdx]) - free(modRefusedList->list.array[arrIdx]); - } - free(modRefusedList->list.array); - } - break; - } - - case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List: - { - rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List; - if(rmvCfmList->list.array) - { - for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++) - { - if(rmvCfmList->list.array[arrIdx]) - free(rmvCfmList->list.array[arrIdx]); - } - free(rmvCfmList->list.array); - } - break; - } - - case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List: - { - rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List; - if(rmvFailList->list.array) - { - for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++) - { - if(rmvFailList->list.array[arrIdx]) - free(rmvFailList->list.array[arrIdx]); - } - free(rmvFailList->list.array); - } - break; - } - - default: - break; - - } - free(ricSubsModCfmIe); - } + if(ricSubsModRefuse->protocolIEs.list.array[ieIdx]) + free(ricSubsModRefuse->protocolIEs.list.array[ieIdx]); } - free(ricSubsModCfm->protocolIEs.list.array); + free(ricSubsModRefuse->protocolIEs.list.array); } } } /******************************************************************* * - * @brief Process RIC Subscription Modification Confirm Message + * @brief Process RIC Subscription Modification Refuse Message * * @details * - * Function : procRicSubscriptionModificationConfirm + * Function : procRicSubscriptionModificationRefuse * - * Functionality: Process RIC Subscription Modification Confirm + * Functionality: Process RIC Subscription Modification Refuse * Message received from RIC. * * @param E2AP Message PDU * @return void * ******************************************************************/ -void procRicSubscriptionModificationConfirm(E2AP_PDU_t *e2apMsg) +void procRicSubscriptionModificationRefuse(E2AP_PDU_t *e2apMsg) { - uint8_t actionId = 0, ieIdx = 0, arrIdx = 0; + uint8_t ieIdx = 0; uint16_t ranFuncId = 0; - bool procFailure = false; RicRequestId ricReqId; - RanFunction *ranFuncDb = NULLP; - CmLList *ricSubsNode = NULLP; - RicSubscription *ricSubsDb = NULLP; - ActionInfo *actionDb = NULLP; - - RICsubscriptionModificationConfirm_t *ricSubsModCfm = NULLP; - RICsubscriptionModificationConfirm_IEs_t *ricSubsModCfmIe = NULLP; - - RICactions_ConfirmedForModification_List_t *modCfmList = NULLP; - RICaction_ConfirmedForModification_ItemIEs_t *modCfmListItem = NULLP; - - RICactions_RefusedToBeModified_List_t *modRefusedList = NULLP; - RICaction_RefusedToBeModified_ItemIEs_t *modRefusedListItem = NULLP; - - RICactions_ConfirmedForRemoval_List_t *rmvCfmList = NULLP; - RICaction_ConfirmedForRemoval_ItemIEs_t *rmvCfmListItem = NULLP; - - RICactions_RefusedToBeRemoved_List_t *rmvFailList = NULLP; - RICaction_RefusedToBeRemoved_ItemIEs_t *rmvFailListItem = NULLP; + RICsubscriptionModificationRefuse_t *ricSubsModRefuse = NULLP; + RICsubscriptionModificationRefuse_IEs_t *ricSubsModRefuseIe = NULLP; + CauseE2_t *cause = NULLP; - DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Modification Confirm", __func__); + DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Modification Refuse", __func__); do{ if(!e2apMsg) { - DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); - break; - } - - if(!e2apMsg->choice.successfulOutcome) - { - DU_LOG("\nERROR --> E2AP : %s: Successful Outcome in E2AP message is NULL", __func__); - break; - } - - ricSubsModCfm = &e2apMsg->choice.successfulOutcome->value.choice.RICsubscriptionModificationConfirm; - if(!ricSubsModCfm->protocolIEs.list.array) - { - DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); - break; - } - - for(ieIdx = 0; ieIdx < ricSubsModCfm->protocolIEs.list.count; ieIdx++) - { - if(!ricSubsModCfm->protocolIEs.list.array[ieIdx]) - { - DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); - break; - } - - ricSubsModCfmIe = ricSubsModCfm->protocolIEs.list.array[ieIdx]; - switch(ricSubsModCfmIe->id) - { - case ProtocolIE_IDE2_id_RICrequestID: - { - memset(&ricReqId, 0, sizeof(RicRequestId)); - ricReqId.requestorId = ricSubsModCfmIe->value.choice.RICrequestID.ricRequestorID; - ricReqId.instanceId = ricSubsModCfmIe->value.choice.RICrequestID.ricInstanceID; - break; - } - - case ProtocolIE_IDE2_id_RANfunctionID: - { - ranFuncId = ricSubsModCfmIe->value.choice.RANfunctionID; - ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId); - if(!ranFuncDb) - { - DU_LOG("\nERROR --> E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId); - procFailure = true; - break; - } - - ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); - if(!ricSubsDb) - { - DU_LOG("\nERROR --> E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\ - __func__, ricReqId.requestorId, ricReqId.instanceId); - procFailure = true; - break; - } + DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + break; + } - break; - } + if(!e2apMsg->choice.unsuccessfulOutcome) + { + DU_LOG("\nERROR --> E2AP : %s: Unsuccessful Outcome in E2AP message is NULL", __func__); + break; + } -/* A RIC Subscription includes RIC subsequent action only for RIC Insert service. - * However, E2SM-KPM supports only RIC Report service. - * Hence there is no subsequent action in RIC subscription that may require modification. - * So commenting the action-modification IEs for the time being - */ -#if 0 - case ProtocolIE_IDE2_id_RICactionsConfirmedForModification_List: - { - modCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForModification_List; - for(arrIdx = 0; arrIdx < modCfmList->list.count; arrIdx++) - { - modCfmListItem = (RICaction_ConfirmedForModification_ItemIEs_t *)modCfmList->list.array[arrIdx]; - actionId = modCfmListItem->value.choice.RICaction_ConfirmedForModification_Item.ricActionID; + ricSubsModRefuse = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionModificationRefuse; + if(!ricSubsModRefuse->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); + break; + } - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); - if(!actionDb) - { - DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); - } - else - { - actionDb->action = CONFIG_UNKNOWN; - /* Further handling can be added here in future once the - * use case of this procedure is identified */ - } - actionDb = NULLP; - } - break; - } + for(ieIdx = 0; ieIdx < ricSubsModRefuse->protocolIEs.list.count; ieIdx++) + { + if(!ricSubsModRefuse->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + break; + } - case ProtocolIE_IDE2_id_RICactionsRefusedToBeModified_List: + ricSubsModRefuseIe = ricSubsModRefuse->protocolIEs.list.array[ieIdx]; + switch(ricSubsModRefuseIe->id) + { + case ProtocolIE_IDE2_id_RICrequestID: { - modRefusedList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeModified_List; - for(arrIdx = 0; arrIdx < modRefusedList->list.count; arrIdx++) - { - modRefusedListItem = (RICaction_RefusedToBeModified_ItemIEs_t *)modRefusedList->list.array[arrIdx]; - actionId = modRefusedListItem->value.choice.RICaction_RefusedToBeModified_Item.ricActionID; - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); - if(!actionDb) - { - DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); - } - else - { - /* Spec doesnt mention if in case of failure, DU should retry for modify action - * Hence, chaging the action from CONFIG_MOD to CONFIG_UNKNOWN - */ - actionDb->action = CONFIG_UNKNOWN; - } - actionDb = NULLP; - } + memset(&ricReqId, 0, sizeof(RicRequestId)); + ricReqId.requestorId = ricSubsModRefuseIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsModRefuseIe->value.choice.RICrequestID.ricInstanceID; break; } -#endif - case ProtocolIE_IDE2_id_RICactionsConfirmedForRemoval_List: + case ProtocolIE_IDE2_id_RANfunctionID: { - rmvCfmList = &ricSubsModCfmIe->value.choice.RICactions_ConfirmedForRemoval_List; - for(arrIdx = 0; arrIdx < rmvCfmList->list.count; arrIdx++) - { - rmvCfmListItem = (RICaction_ConfirmedForRemoval_ItemIEs_t *)rmvCfmList->list.array[arrIdx]; - actionId = rmvCfmListItem->value.choice.RICaction_ConfirmedForRemoval_Item.ricActionID; - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); - if(!actionDb) - { - DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); - } - else - { - deleteActionSequence(actionDb); - actionDb =NULLP; - ricSubsDb->numOfActions--; - /* Further handling can include : - * Deletion of this action from all DU layers - */ - } - actionDb = NULLP; - } + ranFuncId = ricSubsModRefuseIe->value.choice.RANfunctionID; break; } - case ProtocolIE_IDE2_id_RICactionsRefusedToBeRemoved_List: + case ProtocolIE_IDE2_id_CauseE2: { - rmvFailList = &ricSubsModCfmIe->value.choice.RICactions_RefusedToBeRemoved_List; - for(arrIdx = 0; arrIdx < rmvFailList->list.count; arrIdx++) - { - rmvFailListItem = (RICaction_RefusedToBeRemoved_ItemIEs_t *)rmvFailList->list.array[arrIdx]; - actionId = rmvFailListItem->value.choice.RICaction_RefusedToBeRemoved_Item.ricActionID; - actionDb = fetchActionInfoFromActionId(actionId, ricSubsDb); - if(!actionDb) - { - DU_LOG("\nERROR --> E2AP : %s: Action ID [%d] not found", __func__, actionId); - } - else - { - actionDb->action = CONFIG_UNKNOWN; - } - actionDb = NULLP; - } - break; + DU_LOG("\nDEBUG --> E2AP : %s: RIC subscriptiom modification refused for RIC_Requestor_ID [%d] \ + RIC_Instance_ID [%d] RAN_Function_ID [%d] ", __func__, ricReqId.requestorId, \ + ricReqId.instanceId, ranFuncId); + + cause = &ricSubsModRefuseIe->value.choice.CauseE2; + printE2ErrorCause(cause); } default: break; } /* End of switch for Protocol IE Id */ - - if(procFailure) - break; } /* End of for loop for Protocol IE list */ break; }while(true); - freeAperDecodingOfRicSubsModConfirm(e2apMsg); + freeAperDecodingOfRicSubsModRefuse(e2apMsg); return; } -/****************************************************************** -* @brief Deallocate the memory allocated for E2 Reset Response -* -* @details -* -* Function : FreeE2ResetResponse -* -* Functionality: -* - freeing the memory allocated for E2ResetResponse -* -* @params[in] E2AP_PDU_t *e2apMsg -* @return ROK - success -* RFAILED - failure -* -* ****************************************************************/ -void FreeE2ResetResponse(E2AP_PDU_t *e2apMsg) +/******************************************************************* + * + * @brief Free RIC Subscription Delete Required Message + * + * @details + * + * Function : FreeRicSubscriptionDeleteRequired + * + * Functionality: Free RIC Subscription Delete Required + * + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +void FreeRicSubscriptionDeleteRequired(E2AP_PDU_t *e2apMsg, CmLListCp *ricSubsToBeDelList) { - uint8_t ieIdx =0; - ResetResponseE2_t *resetResponse; + uint8_t ieIdx = 0, arrIdx = 0; + RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP; + RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP; + RICsubscription_List_withCause_t *ricSubsList = NULLP; + CmLList *subsNode = NULLP; - if(e2apMsg != NULLP) + if(e2apMsg) { - if(e2apMsg->choice.successfulOutcome != NULLP) + if(e2apMsg->choice.initiatingMessage) { - resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; - if(resetResponse->protocolIEs.list.array) + ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired; + if(ricSubsDelRqd->protocolIEs.list.array) { - for(ieIdx=0; ieIdx < resetResponse->protocolIEs.list.count; ieIdx++) + for(ieIdx = 0; ieIdx < ricSubsDelRqd->protocolIEs.list.count; ieIdx++) { - if(resetResponse->protocolIEs.list.array[ieIdx]) + if(ricSubsDelRqd->protocolIEs.list.array[ieIdx]) { - DU_FREE(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); + ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx]; + switch(ricSubsDelRqdIe->id) + { + case ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved: + { + ricSubsList = &ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause; + if(ricSubsList->list.array) + { + for(arrIdx = 0; arrIdx < ricSubsList->list.count; arrIdx++) + { + DU_FREE(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t)); + } + DU_FREE(ricSubsList->list.array, ricSubsList->list.size); + } + break; + } + } + DU_FREE(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t)); } } - DU_FREE(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); + DU_FREE(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size); } + DU_FREE(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + } + DU_FREE(e2apMsg, sizeof(E2AP_PDU_t));; + } - DU_FREE(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); + if(ricSubsToBeDelList) + { + CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode); + while(subsNode) + { + cmLListDelFrm(ricSubsToBeDelList, subsNode); + DU_FREE(subsNode, sizeof(CmLList)); + CM_LLIST_FIRST_NODE(ricSubsToBeDelList, subsNode); } - DU_FREE(e2apMsg, sizeof(E2AP_PDU_t)); } } /******************************************************************* * - * @brief Buld and send the E2 Reset Response msg + * @brief Fill list of RIC subscriptions required to be deleted + * with the cause of deletion * * @details * - * Function : BuildAndSendE2ResetResponse + * Function : fillRicSubsListWithCause * - * Functionality: - * - Buld and send the E2 Reset Response Message + * Functionality: Fill list of RIC subscriptions required to be + * deleted with the cause of deletion * - * @params[in] Trans Id + * @param E2AP Message PDU + * @return void + * + ******************************************************************/ +uint8_t fillRicSubsListWithCause(RICsubscription_List_withCause_t *ricSubsList, CmLListCp ricSubsToBeDelList) +{ + uint16_t ieIdx = 0; + CmLList *subsNode = NULLP; + RicSubscription *subsInfo = NULLP; + RICsubscription_withCause_ItemIEs_t *subsItemIe = NULLP; + RICsubscription_withCause_Item_t *subsItem = NULLP; + + ricSubsList->list.count = ricSubsToBeDelList.count; + ricSubsList->list.size = ricSubsList->list.count * sizeof(RICsubscription_withCause_ItemIEs_t *); + DU_ALLOC(ricSubsList->list.array, ricSubsList->list.size); + if(!ricSubsList->list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + return RFAILED; + } + + CM_LLIST_FIRST_NODE(&ricSubsToBeDelList, subsNode); + while(subsNode && (ieIdx < ricSubsList->list.count)) + { + subsInfo = (RicSubscription *)subsNode->node; + DU_ALLOC(ricSubsList->list.array[ieIdx], sizeof(RICsubscription_withCause_ItemIEs_t)); + if(!ricSubsList->list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); + return RFAILED; + } + + subsItemIe = (RICsubscription_withCause_ItemIEs_t *)ricSubsList->list.array[ieIdx]; + subsItemIe->id = ProtocolIE_IDE2_id_RICsubscription_withCause_Item; + subsItemIe->criticality = CriticalityE2_ignore; + subsItemIe->value.present = RICsubscription_withCause_ItemIEs__value_PR_RICsubscription_withCause_Item; + + subsItem = & subsItemIe->value.choice.RICsubscription_withCause_Item; + subsItem->ricRequestID.ricRequestorID = subsInfo->requestId.requestorId; + subsItem->ricRequestID.ricInstanceID = subsInfo->requestId.instanceId; + subsItem->ranFunctionID = subsInfo->ranFuncId; + fillE2Cause(&subsItem->cause, subsInfo->failureCause); + + ieIdx++; + subsNode = subsNode->next; + } + + return ROK; +} + +/******************************************************************* + * + * @brief Builds and Send RIC Subscription delete required + * + * @details + * + * Function : BuildAndSendRicSubscriptionDeleteRequired + * + * Functionality: Build and send RIC subscription delete required. + * There can be 2 approaches to trigger following. One of these + * approaches may/may not be implemented in future: + * 1. It can be triggerred immediately when a RIC subscription's + * End Time has expired. In this case, only this subscription's + * info will be sent in this message. + * Since we have not yet added support to execute RIC + * Subscription based on Start Time and End Timer, this message is + * not triggered anywhere from DU APP yet. + * 2. Another approach is to have a periodic timer to check subscription + * status running in background. + * When RIC Subscription End Time expires, this subscription is + * marked to be deleted. Later when this background timer expires, + * a RIC Subscription delete required is sent with all the + * subscription's info which is marked to be deleted. + * The following function is implemented keeping in mind the second + * approach. + * + * @params[in] * @return ROK - success * RFAILED - failure * - * ****************************************************************/ -uint8_t BuildAndSendResetResponse(uint8_t transId) + ******************************************************************/ +uint8_t BuildAndSendRicSubscriptionDeleteRequired() { - uint8_t ieIdx = 0, elementCnt = 0; - uint8_t ret = RFAILED; - E2AP_PDU_t *e2apMsg = NULLP; - ResetResponseE2_t *resetResponse; - asn_enc_rval_t encRetVal; /* Encoder return value */ + uint8_t elementCnt = 0, ieIdx = 0, ret = RFAILED; + E2AP_PDU_t *e2apMsg = NULLP; + RICsubscriptionDeleteRequired_t *ricSubsDelRqd = NULLP; + RICsubscriptionDeleteRequired_IEs_t *ricSubsDelRqdIe = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + CmLListCp ricSubsToBeDelList; - DU_LOG("\nINFO --> E2AP : Building E2 Reset Response Message\n"); - do + while(true) { + /* Check if there are any RIC subscriptions to be deleted */ + cmLListInit(&ricSubsToBeDelList); + fetchRicSubsToBeDeleted(&ricSubsToBeDelList); + if(ricSubsToBeDelList.count == 0) + { + DU_LOG("\nDEBUG --> E2AP : %s: No RIC subscriptions are required to be deleted", __func__); + return ROK; + } + + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Delete Required Message\n"); + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); if(e2apMsg == NULLP) { - DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse(): Memory allocation for E2AP-PDU failed"); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } - e2apMsg->present = E2AP_PDU_PR_successfulOutcome; - DU_ALLOC(e2apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcomeE2_t)); - if(e2apMsg->choice.successfulOutcome == NULLP) + e2apMsg->present = E2AP_PDU_PR_initiatingMessage; + DU_ALLOC(e2apMsg->choice.initiatingMessage, sizeof(InitiatingMessageE2_t)); + if(e2apMsg->choice.initiatingMessage == NULLP) { - DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for successfulOutcome"); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation for E2AP-PDU failed at line %d",__func__, __LINE__); break; } + e2apMsg->choice.initiatingMessage->procedureCode = ProcedureCodeE2_id_RICsubscriptionDeleteRequired; + e2apMsg->choice.initiatingMessage->criticality = CriticalityE2_reject; + e2apMsg->choice.initiatingMessage->value.present = InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequired; - e2apMsg->choice.successfulOutcome->procedureCode = ProcedureCodeE2_id_Reset; - e2apMsg->choice.successfulOutcome->criticality = CriticalityE2_reject; - e2apMsg->choice.successfulOutcome->value.present = SuccessfulOutcomeE2__value_PR_ResetResponseE2; - resetResponse = &e2apMsg->choice.successfulOutcome->value.choice.ResetResponseE2; - + ricSubsDelRqd = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequired; + elementCnt = 1; - resetResponse->protocolIEs.list.count = elementCnt; - resetResponse->protocolIEs.list.size = elementCnt * sizeof(ResetResponseIEs_t *); - DU_ALLOC(resetResponse->protocolIEs.list.array, resetResponse->protocolIEs.list.size); - if(!resetResponse->protocolIEs.list.array) + ricSubsDelRqd->protocolIEs.list.count = elementCnt; + ricSubsDelRqd->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionDeleteRequired_IEs_t *); + + DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array, ricSubsDelRqd->protocolIEs.list.size); + if(ricSubsDelRqd->protocolIEs.list.array == NULLP) { - DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array"); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for array elements at line %d",__func__, __LINE__); break; } - - for(ieIdx=0; ieIdx < elementCnt; ieIdx++) + + for(ieIdx = 0; ieIdx < elementCnt; ieIdx++) { - DU_ALLOC(resetResponse->protocolIEs.list.array[ieIdx], sizeof(ResetResponseIEs_t)); - if(!resetResponse->protocolIEs.list.array[ieIdx]) + DU_ALLOC(ricSubsDelRqd->protocolIEs.list.array[ieIdx], sizeof(RICsubscriptionDeleteRequired_IEs_t)); + if(ricSubsDelRqd->protocolIEs.list.array[ieIdx] == NULLP) { - DU_LOG("\nERROR --> E2AP : BuildAndSendResetResponse: Memory allocation failed for protocol IE array element"); + DU_LOG("\nERROR --> E2AP : %s: Memory allocation failed for index [%d] at line %d", \ + __func__, ieIdx, __LINE__); break; } } if(ieIdx < elementCnt) - break; - - ieIdx = 0; - resetResponse->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_TransactionID; - resetResponse->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_reject; - resetResponse->protocolIEs.list.array[ieIdx]->value.present = ResetResponseIEs__value_PR_TransactionID; - resetResponse->protocolIEs.list.array[ieIdx]->value.choice.TransactionID = transId; + break; - xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + ieIdx = 0; + ricSubsDelRqdIe = ricSubsDelRqd->protocolIEs.list.array[ieIdx]; + ricSubsDelRqdIe->id = ProtocolIE_IDE2_id_RICsubscriptionToBeRemoved; + ricSubsDelRqdIe->criticality = CriticalityE2_ignore; + ricSubsDelRqdIe->value.present = RICsubscriptionDeleteRequired_IEs__value_PR_RICsubscription_List_withCause; + if(fillRicSubsListWithCause(&ricSubsDelRqdIe->value.choice.RICsubscription_List_withCause, ricSubsToBeDelList)\ + != ROK) + { + DU_LOG("\nERROR --> E2AP : %s: Failed to fill RIC Subscription list with cause", __func__); + break; + } + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); memset(encBuf, 0, ENC_BUF_MAX_LEN); encBufSize = 0; encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); if(encRetVal.encoded == ENCODE_FAIL) { - DU_LOG("\nERROR --> E2AP : Could not encode E2 reset response structure (at %s)\n",\ + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Delete Required Message (at %s)\n",\ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); break; } else { - DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for E2 Reset Response \n"); + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Delete Required Message \n"); +#ifdef DEBUG_ASN_PRINT for(int i=0; i< encBufSize; i++) { - DU_LOG("%x",encBuf[i]); - } + printf("%x",encBuf[i]); + } +#endif } - /* Sending msg */ if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) { - DU_LOG("\nERROR --> E2AP : Failed to send E2 Reset Response"); - break; - } + DU_LOG("\nERROR --> E2AP : Failed to send RIC Susbcription Delete Required Message"); + } ret = ROK; break; - }while(true); + } - FreeE2ResetResponse(e2apMsg); + FreeRicSubscriptionDeleteRequired(e2apMsg, &ricSubsToBeDelList); return ret; } -/****************************************************************** +/******************************************************************* * - * @brief Deallocation of memory allocated by aper decoder for reset req + * @brief Free RIC Subscription Delete Request Message * * @details * - * Function : freeAperDecodingOfE2ResetReq + * Function : freeAperDecodingOfRicSubsDeleteReq * - * Functionality: Deallocation of memory allocated by aper decoder for - * reset req + * Functionality: Free RIC Subscription Delete Request * - * @params[in] Pointer to resetReq + * @param E2AP Message PDU * @return void * - * ****************************************************************/ -void freeAperDecodingOfE2ResetReq(ResetRequestE2_t *resetReq) + ******************************************************************/ +void freeAperDecodingOfRicSubsDeleteReq(E2AP_PDU_t *e2apMsg) { - uint8_t arrIdx=0; + uint8_t ieIdx = 0; + RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP; - if(resetReq) + if(e2apMsg) { - if(resetReq->protocolIEs.list.array) + if(e2apMsg->choice.initiatingMessage) { - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) + ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest; + if(ricSubsDelReq->protocolIEs.list.array) { - if(resetReq->protocolIEs.list.array[arrIdx]) + for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++) { - free(resetReq->protocolIEs.list.array[arrIdx]); + if(ricSubsDelReq->protocolIEs.list.array[ieIdx]) + { + free(ricSubsDelReq->protocolIEs.list.array[ieIdx]); + } } + free(ricSubsDelReq->protocolIEs.list.array); } - free(resetReq->protocolIEs.list.array); } } } /******************************************************************* * - * @brief Process reset req received from RIC + * @brief Process RIC Subscription delete request * * @details * - * Function : procE2ResetRequest + * Function : procRicSubscriptionDeleteRequest * - * Functionality: Process reset req received from RIC + * Functionality: Process RIC subscription delete request. + * Fetch RAN Function and RIC subscription to be deleted. + * Send statistics delete request to MAC for all action sequence + * within this RIC subscription. * - * @param E2AP_PDU_t *e2apMsg + * @params[in] E2AP PDU * @return void * ******************************************************************/ - -void procE2ResetRequest(E2AP_PDU_t *e2apMsg) +void procRicSubscriptionDeleteRequest(E2AP_PDU_t *e2apMsg) { - uint16_t ranFuncIdx=0; - uint8_t arrIdx =0, transId =0; - ResetRequestE2_t *resetReq; + uint8_t ieIdx = 0; + uint16_t ranFuncId = 0; + bool procFailure = false; + RicRequestId ricReqId; + RanFunction *ranFuncDb = NULLP; + CmLList *ricSubsNode = NULLP; + RicSubscription *ricSubsDb = NULLP; + RICsubscriptionDeleteRequest_t *ricSubsDelReq = NULLP; + RICsubscriptionDeleteRequest_IEs_t *ricSubsDelReqIe = NULLP; - DU_LOG("\nINFO --> E2AP : E2 Reset request received"); - resetReq = &e2apMsg->choice.initiatingMessage->value.choice.ResetRequestE2; + DU_LOG("\nINFO --> E2AP : %s: Received RIC Subscription Delete Request", __func__); - for(arrIdx=0; arrIdxprotocolIEs.list.count; arrIdx++) - { - switch(resetReq->protocolIEs.list.array[arrIdx]->id) + do{ + if(!e2apMsg) { - case ProtocolIE_IDE2_id_TransactionID: - { - transId = resetReq->protocolIEs.list.array[arrIdx]->value.choice.TransactionID; - break; - } + DU_LOG("\nERROR --> E2AP : %s: E2AP Message is NULL", __func__); + break; + } - case ProtocolIE_IDE2_id_CauseE2: - { - for(ranFuncIdx=0; ranFuncIdxchoice.initiatingMessage) + { + DU_LOG("\nERROR --> E2AP : %s: Initiating Message in E2AP PDU is NULL", __func__); + break; + } + + ricSubsDelReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionDeleteRequest; + if(!ricSubsDelReq->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : %s: Array conatining E2AP message IEs is null", __func__); + break; + } + + for(ieIdx = 0; ieIdx < ricSubsDelReq->protocolIEs.list.count; ieIdx++) + { + if(!ricSubsDelReq->protocolIEs.list.array[ieIdx]) + { + DU_LOG("\nERROR --> E2AP : %s: IE at index [%d] in E2AP message IEs list is null", __func__, ieIdx); + break; + } + + ricSubsDelReqIe = ricSubsDelReq->protocolIEs.list.array[ieIdx]; + switch(ricSubsDelReqIe->id) + { + case ProtocolIE_IDE2_id_RICrequestID: { - if(duCb.e2apDb.ranFunction[ranFuncIdx].id >0) + memset(&ricReqId, 0, sizeof(RicRequestId)); + ricReqId.requestorId = ricSubsDelReqIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsDelReqIe->value.choice.RICrequestID.ricInstanceID; + break; + } + + case ProtocolIE_IDE2_id_RANfunctionID: + { + ranFuncId = ricSubsDelReqIe->value.choice.RANfunctionID; + ranFuncDb = fetchRanFuncFromRanFuncId(ranFuncId); + if(!ranFuncDb) { - deleteRicSubscriptionList(&(duCb.e2apDb.ranFunction[ranFuncIdx].subscriptionList)); - memset(&(duCb.e2apDb.ranFunction[ranFuncIdx].pendingSubsRspInfo), 0, MAX_PENDING_SUBSCRIPTION_RSP*sizeof(PendingSubsRspInfo)); + DU_LOG("\nERROR --> E2AP : %s: RAN Function ID [%d] not found", __func__, ranFuncId); + procFailure = true; + break; } + + ricSubsDb = fetchSubsInfoFromRicReqId(ricReqId, ranFuncDb, &ricSubsNode); + if(!ricSubsDb) + { + DU_LOG("\nERROR --> E2AP : %s: RIC Subscription not found for Requestor_ID [%d] Instance_ID [%d]",\ + __func__, ricReqId.requestorId, ricReqId.instanceId); + procFailure = true; + break; + } + + //TODO : Send statistics delete request to MAC + break; } + + default: break; + } /* End of switch for Protocol IE Id */ + + if(procFailure) + break; + } /* End of for loop for Protocol IE list */ + + break; + }while(true); + + freeAperDecodingOfRicSubsDeleteReq(e2apMsg); + return; +} + +/******************************************************************* + * + * @brief Deallocate the memory allocated for E2 node configuration + * update ack msg by aper decoder + * + * @details + * + * Function : freeAperDecodingOfE2NodeConfigUpdateAck + * + * Functionality: + * - Deallocate the memory allocated for E2 node configuration + * update ack msg by aper decoder + * + * @params[in] E2AP_PDU_t *e2apMsg + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void freeAperDecodingOfE2NodeConfigUpdateAck(E2nodeConfigurationUpdateAcknowledge_t *updateAckMsg) +{ + uint8_t arrIdx =0, e2NodeConfigIdx=0; + E2nodeComponentConfigUpdateAck_ItemIEs_t *updateAckItemIe=NULL; + E2nodeComponentConfigUpdateAck_List_t *updateAckList=NULL; + E2nodeComponentConfigRemovalAck_ItemIEs_t *removalAckItemIe=NULL; + E2nodeComponentConfigRemovalAck_List_t *removalAckList=NULL; + E2nodeComponentConfigAdditionAck_ItemIEs_t *additionAckItemIte=NULL; + E2nodeComponentConfigAdditionAck_List_t *additionAckList=NULL; + + E2nodeComponentInterfaceF1_t *f1InterfaceInfo=NULLP; + if(updateAckMsg->protocolIEs.list.array != NULLP) + { + for(arrIdx = 0; arrIdx < updateAckMsg->protocolIEs.list.count; arrIdx++) + { + if(updateAckMsg->protocolIEs.list.array[arrIdx]) + { + switch(updateAckMsg->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + additionAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; + if(additionAckList->list.array) + { + for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) + { + additionAckItemIte = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) additionAckList->list.array[e2NodeConfigIdx]; + if(additionAckItemIte) + { + switch(additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + f1InterfaceInfo = additionAckItemIte->value.choice.E2nodeComponentConfigAdditionAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; + free(f1InterfaceInfo->gNB_DU_ID.buf); + free(f1InterfaceInfo); + break; + } + default: + break; + } + free(additionAckItemIte); + } + free(additionAckList->list.array); + } + break; + } + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + updateAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List; + if(updateAckList->list.array) + { + for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) + { + updateAckItemIe = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) updateAckList->list.array[e2NodeConfigIdx]; + if(updateAckItemIe) + { + switch(updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + f1InterfaceInfo = updateAckItemIe->value.choice.E2nodeComponentConfigUpdateAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; + free(f1InterfaceInfo->gNB_DU_ID.buf); + free(f1InterfaceInfo); + break; + } + default: + break; + } + free(updateAckItemIe); + } + } + free(updateAckList->list.array); + } + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + removalAckList =&updateAckMsg->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List; + if(removalAckList->list.array) + { + for(e2NodeConfigIdx=0; e2NodeConfigIdxlist.count; e2NodeConfigIdx++) + { + removalAckItemIe = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) removalAckList->list.array[e2NodeConfigIdx]; + if(removalAckItemIe) + { + switch(removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.present) + { + case E2nodeComponentID_PR_e2nodeComponentInterfaceTypeF1: + { + f1InterfaceInfo = removalAckItemIe->value.choice.E2nodeComponentConfigRemovalAck_Item.e2nodeComponentID.choice.e2nodeComponentInterfaceTypeF1; + free(f1InterfaceInfo->gNB_DU_ID.buf); + free(f1InterfaceInfo); + break; + } + default: + break; + } + free(removalAckItemIe); + } + } + free(removalAckList->list.array); + } + break; + } } + free(updateAckMsg->protocolIEs.list.array[arrIdx]); + } } + free(updateAckMsg->protocolIEs.list.array); } - if(BuildAndSendResetResponse(transId) != ROK) +} + +/****************************************************************** + * + * @brief Processes the E2 node config update ack msg + * + * @details + * + * Function :procE2NodeConfigUpdateAck + * + * Functionality: Processes the E2 node config update ack msg + * + * @params[in] E2AP_PDU_t ASN decoded E2AP message + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ + +void procE2NodeConfigUpdateAck(E2AP_PDU_t *e2apMsg) +{ + uint8_t arrIdx =0; + uint16_t e2CfgIdx =0; + E2nodeConfigurationUpdateAcknowledge_t *e2NodeConfigUpdateAck =NULLP; + E2nodeComponentConfigUpdateAck_List_t *e2NodeConfigUpdateAckList=NULLP; + E2nodeComponentConfigUpdateAck_ItemIEs_t *e2NodeUpdateAckItem=NULLP; + E2nodeComponentConfigRemovalAck_List_t *e2NodeConfigRemovalAckList=NULLP; + E2nodeComponentConfigRemovalAck_ItemIEs_t *e2NodeRemovalAckItem=NULLP; + E2nodeComponentConfigAdditionAck_List_t *e2NodeConfigAdditionAckList=NULLP; + E2nodeComponentConfigAdditionAck_ItemIEs_t *e2NodeAdditionAckItem=NULLP; + + e2NodeConfigUpdateAck = &e2apMsg->choice.successfulOutcome->value.choice.E2nodeConfigurationUpdateAcknowledge; + + if(e2NodeConfigUpdateAck->protocolIEs.list.array) { - DU_LOG("\nERROR --> E2AP : Failed to build and send reset response"); + for(arrIdx =0; arrIdxprotocolIEs.list.count; arrIdx++) + { + switch(e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->id) + { + case ProtocolIE_IDE2_id_TransactionID: + { + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck: + { + e2NodeConfigAdditionAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigAdditionAck_List; + if(e2NodeConfigAdditionAckList->list.array) + { + for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigAdditionAckList->list.count; e2CfgIdx++) + { + e2NodeAdditionAckItem = (E2nodeComponentConfigAdditionAck_ItemIEs_t*) e2NodeConfigAdditionAckList->list.array[e2CfgIdx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeAdditionAckItem->value.choice.E2nodeComponentConfigAdditionAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigAdditionAck); + } + } + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck: + { + e2NodeConfigUpdateAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigUpdateAck_List; + if(e2NodeConfigUpdateAckList->list.array) + { + for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigUpdateAckList->list.count; e2CfgIdx++) + { + e2NodeUpdateAckItem = (E2nodeComponentConfigUpdateAck_ItemIEs_t*) e2NodeConfigUpdateAckList->list.array[e2CfgIdx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeUpdateAckItem->value.choice.E2nodeComponentConfigUpdateAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigUpdateAck); + } + } + break; + } + case ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck: + { + e2NodeConfigRemovalAckList = &e2NodeConfigUpdateAck->protocolIEs.list.array[arrIdx]->value.choice.E2nodeComponentConfigRemovalAck_List; + if(e2NodeConfigRemovalAckList->list.array) + { + for(e2CfgIdx = 0; e2CfgIdx< e2NodeConfigRemovalAckList->list.count; e2CfgIdx++) + { + e2NodeRemovalAckItem = (E2nodeComponentConfigRemovalAck_ItemIEs_t*) e2NodeConfigRemovalAckList->list.array[e2CfgIdx]; + handleE2NodeConfigUpdateAckIes((PTR)&e2NodeRemovalAckItem->value.choice.E2nodeComponentConfigRemovalAck_Item,\ + ProtocolIE_IDE2_id_E2nodeComponentConfigRemovalAck); + } + } + break; + } + } + } } - freeAperDecodingOfE2ResetReq(resetReq); + + freeAperDecodingOfE2NodeConfigUpdateAck(e2NodeConfigUpdateAck); } /******************************************************************* @@ -6625,6 +7969,11 @@ void E2APMsgHdlr(Buffer *mBuf) procRicServiceUpdateFailure(e2apMsg); break; } + case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionModificationRefuse: + { + procRicSubscriptionModificationRefuse(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_unsuccessfulOutcome [%d]",\ @@ -6647,11 +7996,6 @@ void E2APMsgHdlr(Buffer *mBuf) } break; } - case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge: - { - DU_LOG("\nDEBUG --> E2AP : E2 node Config update ack message recevied"); - break; - } case SuccessfulOutcomeE2__value_PR_ResetResponseE2: { procResetResponse(e2apMsg); @@ -6667,7 +8011,11 @@ void E2APMsgHdlr(Buffer *mBuf) procRicSubscriptionModificationConfirm(e2apMsg); break; } - + case SuccessfulOutcomeE2__value_PR_E2nodeConfigurationUpdateAcknowledge: + { + procE2NodeConfigUpdateAck(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_successfulOutcome [%d]",\ @@ -6700,10 +8048,22 @@ void E2APMsgHdlr(Buffer *mBuf) } case InitiatingMessageE2__value_PR_ResetRequestE2: { - DU_LOG("\nINFO --> E2AP : Error indication received"); + DU_LOG("\nINFO --> E2AP : Reset request received"); procE2ResetRequest(e2apMsg); break; } + case InitiatingMessageE2__value_PR_RICsubscriptionDeleteRequest: + { + DU_LOG("\nINFO --> E2AP : RIC Subscription Delete Request received"); + procRicSubscriptionDeleteRequest(e2apMsg); + break; + } + case InitiatingMessageE2__value_PR_E2RemovalRequest: + { + DU_LOG("\nINFO --> E2AP : E2 Removal request received"); + procE2RemovalRequest(e2apMsg); + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type of E2AP_PDU_PR_initiatingMessage [%d]",\