From 47fcf084ca2e186a81772c24a3a213acb5ee71d0 Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Fri, 22 Sep 2023 00:11:52 +0530 Subject: [PATCH] [Epic-ID: ODUHIGH-516][Task-ID: ODUHIGH-528] RIC Subscription Failure Change-Id: I2a6e936d0fb0faa49e2156acd0c85faafe10d69e Signed-off-by: lal.harshita --- src/du_app/du_e2ap_mgr.c | 4 +- src/du_app/du_e2ap_mgr.h | 7 +- src/du_app/du_e2ap_msg_hdl.c | 344 ++++++++++++++++++++++++++++++++++------ src/du_app/du_e2ap_msg_hdl.h | 3 +- src/du_app/du_msg_hdl.c | 147 ++++++++++++++++- src/ric_stub/ric_e2ap_msg_hdl.c | 112 ++++++++++++- 6 files changed, 561 insertions(+), 56 deletions(-) diff --git a/src/du_app/du_e2ap_mgr.c b/src/du_app/du_e2ap_mgr.c index 7c834cd0a..104c69bd9 100644 --- a/src/du_app/du_e2ap_mgr.c +++ b/src/du_app/du_e2ap_mgr.c @@ -135,12 +135,12 @@ uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize) * RFAILED - failure * * ****************************************************************/ -uint8_t ResetE2Request(E2ProcedureDirection dir, E2CauseType type, E2Cause cause) +uint8_t ResetE2Request(E2ProcedureDirection dir, E2FailureCause resetCause) { /* Send Reset Request to RIC if DU detects any abnormal failure */ if(dir == E2_NODE_INITIATED) { - if(BuildAndSendE2ResetRequest(type, cause) != ROK) + if(BuildAndSendE2ResetRequest(resetCause) != ROK) { DU_LOG("\nERROR --> E2AP : BuildAndSendE2ResetRequest failed"); return RFAILED; diff --git a/src/du_app/du_e2ap_mgr.h b/src/du_app/du_e2ap_mgr.h index e337f80e9..1cdb2f410 100644 --- a/src/du_app/du_e2ap_mgr.h +++ b/src/du_app/du_e2ap_mgr.h @@ -423,9 +423,14 @@ typedef struct E2TimersInfo e2TimersInfo; }E2apDb; +typedef struct e2FailureCause +{ + E2CauseType causeType; + uint8_t cause; +}E2FailureCause; uint8_t assignTransactionId(); -uint8_t ResetE2Request(E2ProcedureDirection dir, E2CauseType type, E2Cause cause); +uint8_t ResetE2Request(E2ProcedureDirection dir, E2FailureCause resetCause); uint8_t SendE2APMsg(Region region, Pool pool, char *encBuf, int encBufSize); /********************************************************************** End of file diff --git a/src/du_app/du_e2ap_msg_hdl.c b/src/du_app/du_e2ap_msg_hdl.c index e952c5fbe..ac86380ee 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -52,6 +52,62 @@ #include "MeasurementInfoItem.h" #include "RANfunctionsIDcause-List.h" +/******************************************************************* + * + * @brief Fill E2 Failure Cause + * + * @details + * + * Function : fillE2Cause + * + * Functionality: Fill E2 Failure Cause + * + * @params[in] E2 Cause pointer to be filled in + * E2 Cause to be filled from + * @return void + * + ******************************************************************/ +void fillE2Cause(CauseE2_t *e2Cause, E2FailureCause failureCause) +{ + e2Cause->present = failureCause.causeType; + switch(e2Cause->present) + { + case CauseE2_PR_ricRequest: + { + e2Cause->choice.ricRequest = failureCause.cause; + break; + } + case CauseE2_PR_ricService: + { + e2Cause->choice.ricService = failureCause.cause; + break; + } + case CauseE2_PR_e2Node: + { + e2Cause->choice.e2Node = failureCause.cause; + break; + } + case CauseE2_PR_transport: + { + e2Cause->choice.transport = failureCause.cause; + break; + } + case CauseE2_PR_protocol: + { + e2Cause->choice.protocol = failureCause.cause; + break; + } + case CauseE2_PR_misc: + { + e2Cause->choice.misc = failureCause.cause; + break; + } + case CauseE2_PR_NOTHING: + default: + break; + } +} + /******************************************************************* * * @brief Builds Global gNodeB Params @@ -1737,7 +1793,8 @@ void freeAperDecodingOfEventTriggerDef(E2SM_KPM_EventTriggerDefinition_t *event * RFAILED - failure * ******************************************************************/ -uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, RICeventTriggerDefinition_t *ricEventTriggerDef) +uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ + RICeventTriggerDefinition_t *ricEventTriggerDef, E2FailureCause *failureCause) { uint8_t ret = RFAILED; uint8_t eventIdx = 0; @@ -1753,6 +1810,8 @@ uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubsc if(rval.code == RC_FAIL || rval.code == RC_WMORE) { DU_LOG("\nERROR --> E2AP : ASN decode failed for E2SM-KPM Event Trigger Definition"); + failureCause->causeType = E2_PROTOCOL; + failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE; return RFAILED; } printf("\n"); @@ -1774,6 +1833,11 @@ uint8_t extractEventTriggerDef(RanFunction *ranFuncDb, RicSubscription *ricSubsc } } + if(ret == RFAILED) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED; + } /* Free E2SM_KPM_EventTriggerDefinition_t */ freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr); return ret; @@ -1997,7 +2061,8 @@ uint8_t extractMeasInfoList(CmLListCp *measInfoSupportedList, MeasurementInfoLis * RFAILED - failure * ******************************************************************/ -uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef) +uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefDb, RICactionDefinition_t *ricActionDef,\ + E2FailureCause *failureCause) { bool memFailure = false; uint8_t styleIdx = 0; @@ -2017,6 +2082,8 @@ uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefD if(rval.code == RC_FAIL || rval.code == RC_WMORE) { DU_LOG("\nERROR --> E2AP : ASN decode failed for E2SM-KPM Action Definition"); + failureCause->causeType = E2_PROTOCOL; + failureCause->cause = E2_ABSTRACT_SYNTAX_ERROR_FALSELY_CONSTRUCTED_MESSAGE; return RFAILED; } printf("\n"); @@ -2069,12 +2136,22 @@ uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefD } if(memFailure) + { + failureCause->causeType = E2_MISCELLANEOUS; + failureCause->cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; break; + } } /* End of for loop, traversing Report-styles-supported list in E2 node */ /* Memset action Db and Free E2SM_KPM_ActionDefinition_t */ memset(actionDefDb, 0, sizeof(ActionDefinition)); freeAperDecodingOfRicActionDefinition(actionDefPtr); + + if(failureCause->causeType == E2_NOTHING) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + } return RFAILED; } @@ -2097,7 +2174,8 @@ uint8_t extractRicActionDef(RanFunction *ranFuncDb, ActionDefinition *actionDefD * RFAILED - failure * ******************************************************************/ -uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, RICactions_ToBeSetup_List_t *actionList) +uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSubscriptionInfo, \ + RICactions_ToBeSetup_List_t *actionList, E2FailureCause *failureCause) { uint8_t actionIdx = 0; uint8_t ricActionId = 0; @@ -2123,7 +2201,7 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu ricSubscriptionInfo->actionSequence[ricActionId-1].type = REPORT; if(extractRicActionDef(ranFuncDb, &ricSubscriptionInfo->actionSequence[ricActionId-1].definition, \ - actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition) == ROK) + actionItem->value.choice.RICaction_ToBeSetup_Item.ricActionDefinition, failureCause) == ROK) { ricSubscriptionInfo->actionSequence[ricActionId-1].action = CONFIG_ADD; ricSubscriptionInfo->numOfActions++; @@ -2148,6 +2226,11 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu if(ricSubscriptionInfo->numOfActions) return ROK; + if(failureCause->causeType == E2_NOTHING) + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + } return RFAILED; } @@ -2157,30 +2240,34 @@ uint8_t extractRicActionToBeSetup(RanFunction *ranFuncDb, RicSubscription *ricSu * * @details * - * Function : procRicSubsReq + * Function : procRicSubscriptionRequest * - * Functionality: Processes E2 Setup Response sent by CU + * Functionality: Processes RIC Subscription Request from RIC * * @params[in] E2AP_PDU_t ASN decoded E2AP message * @return ROK - success * RFAILED - failure * * ****************************************************************/ - -uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) +uint8_t procRicSubscriptionRequest(E2AP_PDU_t *e2apMsg) { uint8_t idx = 0; uint8_t ret = ROK; uint16_t ranFuncId = 0; + RicRequestId ricReqId; CmLList *ricSubscriptionNode = NULLP; RanFunction *ranFuncDb = NULLP; RICsubscriptionRequest_t *ricSubsReq = NULLP; RICsubscriptionDetails_t *subsDetails = NULLP; RicSubscription *ricSubscriptionInfo = NULLP; + E2FailureCause failureCause; DU_LOG("\nINFO --> E2AP : RIC Subscription request received"); - ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; + memset(&failureCause, 0, sizeof(E2FailureCause)); + memset(&ricReqId, 0, sizeof(RicRequestId)); + + ricSubsReq = &e2apMsg->choice.initiatingMessage->value.choice.RICsubscriptionRequest; for(idx=0; idxprotocolIEs.list.count; idx++) { if(ricSubsReq->protocolIEs.list.array[idx]) @@ -2189,15 +2276,8 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) { case ProtocolIE_IDE2_id_RICrequestID: { - DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription)); - if(!ricSubscriptionInfo) - { - DU_LOG("\nERROR --> E2AP : Memory allocation failed for ricSubscriptionInfo"); - ret = RFAILED; - break; - } - ricSubscriptionInfo->requestId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID; - ricSubscriptionInfo->requestId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID; + ricReqId.requestorId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICrequestID.ricInstanceID; break; } @@ -2210,10 +2290,23 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId) { ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1]; + + DU_ALLOC(ricSubscriptionInfo, sizeof(RicSubscription)); + if(!ricSubscriptionInfo) + { + DU_LOG("\nERROR --> E2AP : Memory allocation failed for ricSubscriptionInfo"); + failureCause.causeType = E2_MISCELLANEOUS; + failureCause.cause = E2_MISCELLANEOUS_CAUSE_UNSPECIFIED; + ret = RFAILED; + break; + } + ricSubscriptionInfo->requestId.requestorId = ricReqId.requestorId; + ricSubscriptionInfo->requestId.instanceId = ricReqId.instanceId; } else { - /* TODO : Send RAN Subcription Failure */ + failureCause.causeType = E2_RIC_REQUEST; + failureCause.cause = E2_RAN_FUNCTION_ID_INVALID; ret = RFAILED; } break; @@ -2224,17 +2317,17 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) subsDetails = &ricSubsReq->protocolIEs.list.array[idx]->value.choice.RICsubscriptionDetails; /* Decode, Validate and record Event Trigger Definition */ - if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition) != ROK) + if(extractEventTriggerDef(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricEventTriggerDefinition, \ + &failureCause) != ROK) { - /* TODO : Send RAN Subcription Failure */ ret = RFAILED; break; } /* Decode, Validate and record RIC actions */ - if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List) != ROK) + if(extractRicActionToBeSetup(ranFuncDb, ricSubscriptionInfo, &subsDetails->ricAction_ToBeSetup_List, \ + &failureCause) != ROK) { - /* TODO : Send RAN Subcription Failure */ ret = RFAILED; break; } @@ -2277,10 +2370,186 @@ uint8_t procRicSubsReq(E2AP_PDU_t *e2apMsg) BuildAndSendRicIndication(ricSubscriptionInfo); } } + else + { + DU_FREE(ricSubscriptionInfo, sizeof(RicSubscription)); + + /* Send RIC Subcription Failure */ + BuildAndSendRicSubscriptionFailure(ricReqId, ranFuncId, failureCause); + } return ret; } +/****************************************************************** + * + * @brief Free RIC Subscription Failure + * + * @details + * + * Function : FreeRicSubscriptionFailure + * + * Functionality: Free RIC Subscription Failure + * + * @params[in] E2AP PDU + * @return void + * + * ****************************************************************/ +void FreeRicSubscriptionFailure(E2AP_PDU_t *e2apMsg) +{ + uint8_t elemIdx = 0; + RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP; + + if(e2apMsg) + { + if(e2apMsg->choice.unsuccessfulOutcome) + { + ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure; + if(ricSubscriptionFailure->protocolIEs.list.array) + { + for(elemIdx = 0; elemIdx < ricSubscriptionFailure->protocolIEs.list.count; elemIdx++) + { + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t)); + } + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size); + } + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + } + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + } +} + +/****************************************************************** + * + * @brief Fill and Send RIC Subscription Failure to RIC + * + * @details + * + * Function : BuildAndSendRicSubscriptionFailure + * + * Functionality: Fill and Send RIC Subscription Failure to RIC + * + * @params[in] RIC Request ID + * RAN Function ID + * Cause of Failure + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause) +{ + uint8_t ret = RFAILED; + uint8_t elementCnt = 0, elemIdx = 0; + E2AP_PDU_t *e2apMsg = NULLP; + asn_enc_rval_t encRetVal; /* Encoder return value */ + RICsubscriptionFailure_t *ricSubscriptionFailure = NULLP; + RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP; + + while(true) + { + DU_LOG("\nINFO --> E2AP : Building RIC Subscription Failure\n"); + + DU_ALLOC(e2apMsg, sizeof(E2AP_PDU_t)); + if(e2apMsg == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); + break; + } + + e2apMsg->present = E2AP_PDU_PR_unsuccessfulOutcome; + DU_ALLOC(e2apMsg->choice.unsuccessfulOutcome, sizeof(UnsuccessfulOutcomeE2_t)); + if(e2apMsg->choice.unsuccessfulOutcome == NULLP) + { + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); + break; + } + e2apMsg->choice.unsuccessfulOutcome->procedureCode = ProcedureCodeE2_id_RICsubscription; + e2apMsg->choice.unsuccessfulOutcome->criticality = CriticalityE2_reject; + e2apMsg->choice.unsuccessfulOutcome->value.present = UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure; + + ricSubscriptionFailure = &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure; + + elementCnt = 3; + ricSubscriptionFailure->protocolIEs.list.count = elementCnt; + ricSubscriptionFailure->protocolIEs.list.size = elementCnt * sizeof(RICsubscriptionFailure_IEs_t *); + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array, ricSubscriptionFailure->protocolIEs.list.size); + if(!ricSubscriptionFailure->protocolIEs.list.array) + { + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d]", __func__, __LINE__); + break; + } + + for(elemIdx = 0; elemIdx < elementCnt; elemIdx++) + { + DU_ALLOC(ricSubscriptionFailure->protocolIEs.list.array[elemIdx], sizeof(RICsubscriptionFailure_IEs_t)); + if(!ricSubscriptionFailure->protocolIEs.list.array[elemIdx]) + { + DU_LOG("\nERROR --> E2AP : Memory allocation at [%s] : Line [%d] for IE at index [%d]", \ + __func__, __LINE__, elemIdx); + break; + } + } + if(elemIdx < elementCnt) + break; + + elemIdx = 0; + + /* RIC Request ID */ + ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++]; + ricSubsFailIe->id = ProtocolIE_IDE2_id_RICrequestID; + ricSubsFailIe->criticality = CriticalityE2_reject; + ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RICrequestID; + ricSubsFailIe->value.choice.RICrequestID.ricRequestorID = ricReqId.requestorId; + ricSubsFailIe->value.choice.RICrequestID.ricInstanceID = ricReqId.instanceId; + + /* RAN Function ID */ + ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++]; + ricSubsFailIe->id = ProtocolIE_IDE2_id_RANfunctionID; + ricSubsFailIe->criticality = CriticalityE2_reject; + ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_RANfunctionID; + ricSubsFailIe->value.choice.RANfunctionID = ranFuncId; + + /* Cause */ + ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[elemIdx++]; + ricSubsFailIe->id = ProtocolIE_IDE2_id_CauseE2; + ricSubsFailIe->criticality = CriticalityE2_reject; + ricSubsFailIe->value.present = RICsubscriptionFailure_IEs__value_PR_CauseE2; + fillE2Cause(&ricSubsFailIe->value.choice.CauseE2, failureCause); + + /* Prints the Msg formed */ + xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); + memset(encBuf, 0, ENC_BUF_MAX_LEN); + encBufSize = 0; + encRetVal = aper_encode(&asn_DEF_E2AP_PDU, 0, e2apMsg, PrepFinalEncBuf, encBuf); + if(encRetVal.encoded == ENCODE_FAIL) + { + DU_LOG("\nERROR --> E2AP : Could not encode RIC Subscription Failure Message (at %s)\n",\ + encRetVal.failed_type ? encRetVal.failed_type->name : "unknown"); + break; + } + else + { + DU_LOG("\nDEBUG --> E2AP : Created APER encoded buffer for RIC Subscription Failure Message \n"); +#ifdef DEBUG_ASN_PRINT + for(int i=0; i< encBufSize; i++) + { + printf("%x",encBuf[i]); + } +#endif + } + + if(SendE2APMsg(DU_APP_MEM_REGION, DU_POOL, encBuf, encBufSize) != ROK) + { + DU_LOG("\nINFO --> E2AP : Sending RIC Subscription Failure"); + + } + ret = ROK; + break; + } + FreeRicSubscriptionFailure(e2apMsg); + return ret; +} + /******************************************************************* * * @brief Free the RicIndication Message @@ -2771,7 +3040,7 @@ void FreeE2ResetRequest(E2AP_PDU_t *e2apMsg) * RFAILED - failure * * ****************************************************************/ -uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause) +uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause) { uint8_t ieIdx = 0, elementCnt = 0, transId = 0; uint8_t ret = RFAILED; @@ -2841,30 +3110,7 @@ uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause resetReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_IDE2_id_CauseE2; resetReq->protocolIEs.list.array[ieIdx]->criticality = CriticalityE2_ignore; resetReq->protocolIEs.list.array[ieIdx]->value.present = ResetRequestIEs__value_PR_CauseE2; - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present = failureType; - switch(resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.present) - { - case CauseE2_PR_NOTHING: - break; - case CauseE2_PR_ricRequest: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricRequest = failureCause; - break; - case CauseE2_PR_ricService: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.ricService = failureCause; - break; - case CauseE2_PR_e2Node: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.e2Node = failureCause; - break; - case CauseE2_PR_transport: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.transport = failureCause; - break; - case CauseE2_PR_protocol: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.protocol = failureCause; - break; - case CauseE2_PR_misc: - resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2.choice.misc = failureCause; - break; - } + fillE2Cause(&resetReq->protocolIEs.list.array[ieIdx]->value.choice.CauseE2, resetCause); /* Prints the Msg formed */ xer_fprint(stdout, &asn_DEF_E2AP_PDU, e2apMsg); @@ -3973,7 +4219,7 @@ void E2APMsgHdlr(Buffer *mBuf) { case InitiatingMessageE2__value_PR_RICsubscriptionRequest: { - procRicSubsReq(e2apMsg); + procRicSubscriptionRequest(e2apMsg); break; } case InitiatingMessageE2__value_PR_RICserviceQuery: diff --git a/src/du_app/du_e2ap_msg_hdl.h b/src/du_app/du_e2ap_msg_hdl.h index c5701c279..460355b9c 100644 --- a/src/du_app/du_e2ap_msg_hdl.h +++ b/src/du_app/du_e2ap_msg_hdl.h @@ -22,11 +22,12 @@ uint8_t BuildAndSendE2SetupReq(); uint8_t BuildAndSendE2NodeConfigUpdate(); -uint8_t BuildAndSendE2ResetRequest(E2CauseType failureType, E2Cause failureCause); +uint8_t BuildAndSendE2ResetRequest(E2FailureCause resetCause); void E2APMsgHdlr(Buffer *mBuf); uint8_t BuildAndSendRicIndication(RicSubscription *ricSubscriptionInfo); uint8_t BuildAndSendRicServiceUpdate(RicServiceUpdate serviceUpdate); uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo); +uint8_t BuildAndSendRicSubscriptionFailure(RicRequestId ricReqId, uint16_t ranFuncId, E2FailureCause failureCause); /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_msg_hdl.c b/src/du_app/du_msg_hdl.c index 650284089..079585045 100644 --- a/src/du_app/du_msg_hdl.c +++ b/src/du_app/du_msg_hdl.c @@ -29,6 +29,7 @@ #include "du_app_mac_inf.h" #include "du_app_rlc_inf.h" #include "du_e2ap_mgr.h" +#include "du_e2ap_msg_hdl.h" #include "du_cfg.h" #include "du_app_rlc_inf.h" #include "du_mgr.h" @@ -2272,6 +2273,90 @@ uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptio return ROK; } +/******************************************************************* + * + * @brief Converts DU specific failure cause to E2 interface + * failure cause + * + * @details + * + * Function : convertDuCauseToE2Cause + * + * Functionality: Converts DU specific failure cause to E2 + * interface failure cause + * + * @params[in] DU specific failure cause + * E2 specific failure cause + * + * @return void + * + * ****************************************************************/ +void convertDuCauseToE2Cause(CauseOfResult l2Cause, E2FailureCause *failureCause) +{ + switch(l2Cause) + { + case PARAM_INVALID: + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_ACTION_NOT_SUPPORTED; + break; + } + case RESOURCE_UNAVAILABLE: + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_FUNCTION_RESOURCE_LIMIT; + break; + } + default: + { + failureCause->causeType = E2_RIC_REQUEST; + failureCause->cause = E2_RIC_REQUEST_CAUSE_UNSPECIFIED; + break; + } + } +} + +/******************************************************************* + * + * @brief Rejects all actions received in a subscription request + * + * @details + * + * Function : duRejectAllStatsGroup + * + * Functionality: Rejects all actions received in a subscription + * request by : + * a. Removing the subscription entry from RAN function + * b. Sending RIC Subscription Failure to RIC with appropriate + * cause of failure + * + * @params[in] RAN Function DB + * Subscription entry in RAN Function subscription list + * Statistics Response from MAC + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t duRejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode, MacStatsRsp *statsRsp) +{ + uint8_t ret = ROK; + RicRequestId requestId; + E2FailureCause failureCause; + + /* Delete subcription from RAN Function */ + memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId)); + cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode); + DU_FREE(ricSubscriptionNode->node, sizeof(RicSubscription)); + DU_FREE(ricSubscriptionNode, sizeof(CmLList)); + + convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause); + + /* Send RIC subscription failure to RIC */ + ret = BuildAndSendRicSubscriptionFailure(requestId, ranFuncDb->id, failureCause); + return ret; +} + /******************************************************************* * * @brief Process statistics response from MAC @@ -2293,6 +2378,12 @@ uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptio * ****************************************************************/ uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp) { + uint16_t ranFuncId = 0; + RicRequestId ricReqId; + RanFunction *ranFuncDb = NULLP; + CmLList *ricSubscriptionNode = NULLP; + RicSubscription *ricSubscriptionInfo = NULLP; + DU_LOG("\nINFO --> DU_APP : DuProcMacStatsRsp: Received Statistics Response from MAC"); if(statsRsp) @@ -2313,8 +2404,62 @@ uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp) DU_LOG("\n Group Id [%d]", statsRsp->statsGrpRejectedList[idx]); } #endif - + + /* Extract following from 64 bit subscription-ID : + * First 16 MSB is unused + * Next 16 MSB = RAN-Function-ID + * Next 16 MSB = Requestor-ID in RIC-Request-ID + * Last 16 LSB = Instance-ID in RIC-Request-ID + */ + ricReqId.instanceId = statsRsp->subscriptionId & 0xFFFF; + ricReqId.requestorId = (statsRsp->subscriptionId >> 16) & 0xFFFF; + ranFuncId = (statsRsp->subscriptionId >> 32) & 0xFFFF; + + /* Fetch RAN Function DB */ + if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId) + { + ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1]; + } + else + { + DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Invalid RAN Function ID[%d] with Subscription ID [%ld]", \ + ranFuncId, statsRsp->subscriptionId); + DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp)); + return RFAILED; + } + + /* Fetch subscription detail in RAN Function DB */ + CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, ricSubscriptionNode); + while(ricSubscriptionNode) + { + ricSubscriptionInfo = (RicSubscription *)ricSubscriptionNode->node; + if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) && + (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId)) + { + break; + } + ricSubscriptionNode = ricSubscriptionNode->next; + } + + if(ricSubscriptionNode == NULLP) + { + DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Subscription not found for Requestor ID [%d] Instance ID [%d]",\ + ricReqId.requestorId, ricReqId.instanceId); + DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp)); + return RFAILED; + } + + /* If no action is accepted + * a. Remove subcription entry from RAN Function + * b. Send RIC subscription failure */ + if(statsRsp->numGrpAccepted == 0) + { + duRejectAllStatsGroup(ranFuncDb, ricSubscriptionNode, statsRsp); + } + /* TODO : + * If even 1 action is accepted : + * * For accepted groups: * Mark scubscrbed-action's -> action = CONFIG_UNKNOWN * Add action ID to accpeted-action-list in Subscription response diff --git a/src/ric_stub/ric_e2ap_msg_hdl.c b/src/ric_stub/ric_e2ap_msg_hdl.c index c399f896c..8cc3806d0 100644 --- a/src/ric_stub/ric_e2ap_msg_hdl.c +++ b/src/ric_stub/ric_e2ap_msg_hdl.c @@ -1493,8 +1493,8 @@ uint8_t ProcE2SetupReq(uint32_t *duId, E2setupRequest_t *e2SetupReq) { ranFuncItemIe = (RANfunction_ItemIEs_t *) ranFunctionsList->list.array[ranFuncIdx]; ranFunItem = &ranFuncItemIe->value.choice.RANfunction_Item; - duDb->ranFunction[duDb->numOfRanFunction].id = ranFunItem->ranFunctionID; - duDb->ranFunction[duDb->numOfRanFunction].revisionCounter = ranFunItem->ranFunctionRevision; + duDb->ranFunction[ranFunItem->ranFunctionID-1].id = ranFunItem->ranFunctionID; + duDb->ranFunction[ranFunItem->ranFunctionID-1].revisionCounter = ranFunItem->ranFunctionRevision; duDb->numOfRanFunction++; } } @@ -2779,6 +2779,95 @@ void ProcRicServiceUpdate(uint32_t duId, RICserviceUpdate_t *ricServiceUpdate) } } +/******************************************************************* + * + * @brief Processing RIC subscription failure from DU + * + * @details + * + * Function : ProcRicSubscriptionFailure + * + * Functionality: Processing RIC subscription failure from DU + * + * @param ID of DU from which message was sent + * RIC Subscription failure message + * @return ROK - success + * RFAILED - failure + * + ******************************************************************/ +uint8_t ProcRicSubscriptionFailure(uint32_t duId, RICsubscriptionFailure_t *ricSubscriptionFailure) +{ + uint8_t ieIdx = 0, duIdx = 0, subsIdx = 0; + uint8_t ranFuncId = 0; + bool ricReqIdDecoded = false; + DuDb *duDb = NULLP; + RanFunction *ranFuncDb = NULLP; + RicRequestId ricReqId; + RICsubscriptionFailure_IEs_t *ricSubsFailIe = NULLP; + + DU_LOG("\nINFO --> E2AP : Received RIC subscription failure"); + + SEARCH_DU_DB(duIdx, duId, duDb); + if(duDb == NULLP) + { + DU_LOG("\nERROR --> E2AP : duDb is not present for duId %d",duId); + return; + } + + memset(&ricReqId, 0, sizeof(RicRequestId)); + if(ricSubscriptionFailure) + { + if(ricSubscriptionFailure->protocolIEs.list.array) + { + for(ieIdx=0; ieIdxprotocolIEs.list.count; ieIdx++) + { + if(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]) + { + ricSubsFailIe = ricSubscriptionFailure->protocolIEs.list.array[ieIdx]; + switch(ricSubscriptionFailure->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_IDE2_id_RICrequestID: + { + ricReqId.requestorId = ricSubsFailIe->value.choice.RICrequestID.ricRequestorID; + ricReqId.instanceId = ricSubsFailIe->value.choice.RICrequestID.ricInstanceID; + ricReqIdDecoded = true; + break; + } + case ProtocolIE_IDE2_id_RANfunctionID: + { + ranFuncId = ricSubsFailIe->value.choice.RANfunctionID; + if(duDb->ranFunction[ranFuncId-1].id == ranFuncId) + { + ranFuncDb = &duDb->ranFunction[ranFuncId-1]; + } + break; + } + case ProtocolIE_IDE2_id_CauseE2: + default: + /* No handling required as of now since this is a stub */ + break; + + } + } + } + + /* Remove subscription entry from RAN Function */ + if(ranFuncDb && ricReqIdDecoded) + { + for(subsIdx = 0; subsIdx < ranFuncDb->numOfSubscription; subsIdx++) + { + if((ranFuncDb->subscriptionList[subsIdx].requestId.requestorId == ricReqId.requestorId) && + (ranFuncDb->subscriptionList[subsIdx].requestId.instanceId == ricReqId.instanceId)) + { + memset(&ranFuncDb->subscriptionList[subsIdx], 0, sizeof(RicSubscription)); + break; + } + } + } + } + } + return ROK; +} /******************************************************************* * @@ -2908,6 +2997,25 @@ void E2APMsgHdlr(uint32_t *duId, Buffer *mBuf) } break; } + case E2AP_PDU_PR_unsuccessfulOutcome: + { + switch(e2apMsg->choice.successfulOutcome->value.present) + { + case UnsuccessfulOutcomeE2__value_PR_RICsubscriptionFailure: + { + ProcRicSubscriptionFailure(*duId, \ + &e2apMsg->choice.unsuccessfulOutcome->value.choice.RICsubscriptionFailure); + break; + } + default: + { + DU_LOG("\nERROR --> E2AP : Invalid type of unsuccessfulOutcome message [%d]", \ + e2apMsg->choice.unsuccessfulOutcome->value.present); + return; + } + } + break; + } default: { DU_LOG("\nERROR --> E2AP : Invalid type message type "); -- 2.16.6