#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
* 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;
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");
}
}
+ if(ret == RFAILED)
+ {
+ failureCause->causeType = E2_RIC_REQUEST;
+ failureCause->cause = E2_EVENT_TRIGGER_NOT_SUPPORTED;
+ }
/* Free E2SM_KPM_EventTriggerDefinition_t */
freeAperDecodingOfEventTriggerDef(eventTiggerDefPtr);
return ret;
* 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;
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");
}
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;
}
* 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;
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++;
if(ricSubscriptionInfo->numOfActions)
return ROK;
+ if(failureCause->causeType == E2_NOTHING)
+ {
+ failureCause->causeType = E2_RIC_REQUEST;
+ failureCause->cause = E2_ACTION_NOT_SUPPORTED;
+ }
return RFAILED;
}
*
* @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; idx<ricSubsReq->protocolIEs.list.count; idx++)
{
if(ricSubsReq->protocolIEs.list.array[idx])
{
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;
}
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;
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;
}
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
* 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;
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);
{
case InitiatingMessageE2__value_PR_RICsubscriptionRequest:
{
- procRicSubsReq(e2apMsg);
+ procRicSubscriptionRequest(e2apMsg);
break;
}
case InitiatingMessageE2__value_PR_RICserviceQuery:
#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"
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
* ****************************************************************/
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)
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
{
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++;
}
}
}
}
+/*******************************************************************
+ *
+ * @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; ieIdx<ricSubscriptionFailure->protocolIEs.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;
+}
/*******************************************************************
*
}
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 ");