+ CU_ALLOC(f1ResetAck->protocolIEs.list.array, f1ResetAck->protocolIEs.list.size );
+ if(f1ResetAck->protocolIEs.list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation for F1ResetAckIEs failed");
+ break;
+ }
+
+ for(idx=0; idx<elementCnt; idx++)
+ {
+ CU_ALLOC(f1ResetAck->protocolIEs.list.array[idx], sizeof(ResetAcknowledgeIEs_t));
+ if(f1ResetAck->protocolIEs.list.array[idx] == NULLP)
+ {
+ break;
+ }
+ }
+ /*TransactionID*/
+ idx = 0;
+ f1ResetAck->protocolIEs.list.array[idx]->id = ProtocolIE_ID_id_TransactionID;
+ f1ResetAck->protocolIEs.list.array[idx]->criticality = Criticality_reject;
+ f1ResetAck->protocolIEs.list.array[idx]->value.present = ResetAcknowledgeIEs__value_PR_TransactionID;
+ f1ResetAck->protocolIEs.list.array[idx]->value.choice.TransactionID = TRANS_ID;
+
+ xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
+
+ /* Encode the F1SetupRequest type as UPER */
+ memset(encBuf, 0, ENC_BUF_MAX_LEN);
+ encBufSize = 0;
+ encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf, encBuf);
+
+ /* Check encode results */
+ if(encRetVal.encoded == ENCODE_FAIL)
+ {
+ DU_LOG("\nERROR --> F1AP : Could not encode F1ResetAck structure (at %s)\n",\
+ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+ break;
+ }
+ else
+ {
+ DU_LOG("\nDEBUG --> F1AP : Created APER encodedbuffer for F1ResetAck \n");
+ for(int i=0; i< encBufSize; i++)
+ {
+ DU_LOG("%x",encBuf[i]);
+ }
+ }
+ /* Sending msg */
+ if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Sending F1 Reset Response failed");
+ break;
+ }
+
+ ret = ROK;
+ break;
+ }while(true);
+
+ FreeF1ResetAck(f1apMsg);
+ return ret;
+}
+void FreeUlTnlInfoforDrb2(ULUPTNLInformation_ToBeSetup_List_t *ulInfo)
+{
+ uint8_t arrIdx =0;
+
+ if(ulInfo->list.array)
+ {
+ for(arrIdx=0; arrIdx<ulInfo->list.count ; arrIdx++)
+ {
+ if(ulInfo->list.array[arrIdx])
+ {
+ if(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel )
+ {
+ if(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->transportLayerAddress.buf)
+ {
+ if(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf)
+ {
+ CU_FREE(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ gTP_TEID.buf,ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.\
+ gTPTunnel->gTP_TEID.size);
+ }
+ CU_FREE(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf,ulInfo->list.array[arrIdx]->\
+ uLUPTNLInformation.choice.gTPTunnel->transportLayerAddress.size);
+ }
+ CU_FREE(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel,\
+ sizeof(GTPTunnel_t));
+ }
+ CU_FREE(ulInfo->list.array[arrIdx],sizeof(ULUPTNLInformation_ToBeSetup_Item_t));
+ }
+ }
+ CU_FREE(ulInfo->list.array,ulInfo->list.size);
+ }
+}
+
+/*******************************************************************
+*
+* @brief Deletes the EGTP tunnel
+*
+* @details
+*
+* Function : deleteEgtpTunnel
+*
+* Functionality: Deletes the EGTP tunnel
+*
+* @params[in] uint8_t *buf
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+uint8_t deleteEgtpTunnel(uint8_t *buf)
+{
+ uint32_t teId = 0;
+ EgtpTnlEvt tnlEvt;
+
+ teIdStringToInt(buf, &teId);
+ if(teId > MAX_TEID || teId < MIN_TEID)
+ {
+ DU_LOG("\nERROR --> EGTP : TEID(%d) OUT Of Range", teId);
+ return RFAILED;
+ }
+ memset(&tnlEvt, 0, sizeof(EgtpTnlEvt));
+ tnlEvt.action = EGTP_TNL_MGMT_DEL;
+ tnlEvt.lclTeid = teId;
+ tnlEvt.remTeid = teId;
+ if((cuEgtpTnlMgmtReq(tnlEvt)) != ROK)
+ {
+ DU_LOG("\nERROR --> EGTP : Failed to delete tunnel Id %d", teId);
+ }
+ return ROK;
+}
+
+/*******************************************************************
+*
+* @brief Builds the Uplink Tunnel Info
+*
+* @details
+*
+* Function : BuildUlTnlInfoforSetupMod
+*
+* Functionality: Constructs the UL TnlInfo For DRB list
+*
+* @params[in] ULUPTNLInformation_ToBeSetup_List_t *ulInfo
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+uint8_t BuildUlTnlInfoforSetupMod(uint8_t ueId, uint8_t drbId, ULUPTNLInformation_ToBeSetup_List_t *ulInfo, uint8_t actionType)
+{
+ uint8_t arrIdx;
+ uint8_t ulCnt;
+
+ ulCnt = 1;
+ ulInfo->list.count = ulCnt;
+ ulInfo->list.size = ulCnt * sizeof(ULUPTNLInformation_ToBeSetup_Item_t *);
+ CU_ALLOC(ulInfo->list.array,ulInfo->list.size);
+ if(ulInfo->list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildUlTnlInfoforSetupMod");
+ return RFAILED;
+ }
+ for(arrIdx=0; arrIdx<ulCnt; arrIdx++)
+ {
+ CU_ALLOC(ulInfo->list.array[arrIdx],sizeof(ULUPTNLInformation_ToBeSetup_Item_t));
+ if(ulInfo->list.array[arrIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildUlTnlInfoforSetupMod");
+ return RFAILED;
+ }
+ }
+
+ arrIdx = 0;
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.present = \
+ UPTransportLayerInformation_PR_gTPTunnel;
+
+ /*GTP TUNNEL*/
+ CU_ALLOC(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel,\
+ sizeof(GTPTunnel_t));
+ if(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildUlTnlInfoforSetupMod");
+ return RFAILED;
+ }
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.size = 4*sizeof(uint8_t);
+ CU_ALLOC(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf,ulInfo->list.array[arrIdx]->\
+ uLUPTNLInformation.choice.gTPTunnel->transportLayerAddress.size);
+ if(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildUlTnlInfoforSetupMod");
+ return RFAILED;
+ }
+
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf[0] = 192;
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf[1] = 168;
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf[2] = 130;
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.buf[3] = 82;
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ transportLayerAddress.bits_unused = 0;
+
+ /*GTP TEID*/
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.size\
+ = 4 * sizeof(uint8_t);
+ CU_ALLOC(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ gTP_TEID.buf,ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.\
+ gTPTunnel->gTP_TEID.size);
+ if(ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf\
+ == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildUlTnlInfoforSetupMod");
+ return RFAILED;
+ }
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ gTP_TEID.buf[0] = 0;
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ gTP_TEID.buf[1] = 0;
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ gTP_TEID.buf[2] = 0;
+ if(actionType == ProtocolIE_ID_id_DRBs_ToBeModified_Item)
+ {
+ /*TODO: DRB context to be stored in CU STUB so that tunnel Id can be easily
+ * fetched based on the Drb Id */
+
+ /*For For UE Id=1, DRB=2 is modified. For UE Id = 2, DRB=5 is modified and so on.*/
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[3]=\
+ (MAX_NUM_DRB_ADDED_PER_UE *(ueId - 1)) + drbId;
+ }
+ else
+ {
+ ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
+ gTP_TEID.buf[3] = cuCfgParams.egtpParams.currTunnelId++;
+ }
+ return ROK;
+}/*End of BuildULTnlInfo*/
+
+/*******************************************************************
+*
+* @brief freeing the DRB item
+*
+* @details
+*
+* Function : FreeDrbItem
+*
+* Functionality: freeing the DRB item
+*
+* @params[in] DRBs_ToBeSetupMod_Item_t *drbItem
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+void FreeDrbItem(DRBs_ToBeSetupMod_Item_t *drbItem)
+{
+ uint8_t arrIdx =0;
+ SNSSAI_t *snssai =NULLP;
+ Flows_Mapped_To_DRB_List_t *flowMap = NULLP;
+
+ drbItem->qoSInformation.present = QoSInformation_PR_choice_extension;
+ switch(drbItem->qoSInformation.present)
+ {
+ case QoSInformation_PR_NOTHING:
+ break;
+ case QoSInformation_PR_eUTRANQoS:
+ {
+ if(drbItem->qoSInformation.choice.eUTRANQoS)
+ {
+ CU_FREE(drbItem->qoSInformation.choice.eUTRANQoS, sizeof(EUTRANQoS_t));
+ }
+ break;
+ }
+ case QoSInformation_PR_choice_extension:
+ {
+ if(drbItem->qoSInformation.choice.choice_extension)
+ {
+ FreeQOSInfo(&drbItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS);
+
+ snssai = &drbItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.sNSSAI;
+ if(snssai->sST.buf)
+ {
+ CU_FREE(snssai->sST.buf,snssai->sST.size);
+ }
+ if(snssai->sD)
+ {
+ if(snssai->sD->buf)
+ {
+ CU_FREE(snssai->sD->buf,snssai->sD->size);
+ }
+ CU_FREE(snssai->sD,sizeof(OCTET_STRING_t));
+ }
+
+ flowMap = &drbItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.flows_Mapped_To_DRB_List;
+ if(flowMap->list.array)
+ {
+ for(arrIdx=0; arrIdx<flowMap->list.count; arrIdx++)
+ {
+ if(flowMap->list.array[arrIdx] )
+ {
+ FreeQOSInfo(&flowMap->list.array[arrIdx]->qoSFlowLevelQoSParameters);
+ CU_FREE(flowMap->list.array[arrIdx],sizeof(Flows_Mapped_To_DRB_Item_t));
+ }
+ }
+ CU_FREE(flowMap->list.array,flowMap->list.size);
+ }
+
+ CU_FREE(drbItem->qoSInformation.choice.choice_extension,sizeof(QoSInformation_ExtIEs_t));
+ }
+ break;
+ }
+
+ }
+ FreeUlTnlInfoforDrb2(&drbItem->uLUPTNLInformation_ToBeSetup_List);
+ if(drbItem->uLConfiguration)
+ {
+ CU_FREE(drbItem->uLConfiguration,sizeof(ULConfiguration_t));
+ }
+}
+
+/*******************************************************************
+*
+* @brief filling the DRB setup Mod item
+*
+* @details
+*
+* Function : FillDrbItemToSetupMod
+*
+* Functionality: filling the DRB setup Mod item
+*
+*
+* @params[in] DRBs_ToBeSetupMod_Item_t *drbItem
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t FillDrbItemToSetupMod(uint8_t ueId, uint8_t arrIdx, DRBs_ToBeSetupMod_Item_t *drbItem)
+{
+ uint8_t ret = ROK;
+
+ /*Drb Id */
+ drbItem->dRBID = arrIdx + DRB_ID_TO_ADD_MOD;
+
+ /*qoSInformation*/
+ drbItem->qoSInformation.present = QoSInformation_PR_choice_extension;
+
+ switch(drbItem->qoSInformation.present)
+ {
+ case QoSInformation_PR_NOTHING:
+ {
+ break;
+ }
+ case QoSInformation_PR_eUTRANQoS:
+ {
+
+ CU_ALLOC(drbItem->qoSInformation.choice.eUTRANQoS, sizeof(EUTRANQoS_t));
+ if(drbItem->qoSInformation.choice.eUTRANQoS)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in FillDrbItemToSetupMod");
+ return RFAILED;
+ }
+ drbItem->qoSInformation.choice.eUTRANQoS->qCI = QCI;
+ drbItem->qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.priorityLevel =
+ PriorityLevel_no_priority;
+
+ drbItem->qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability =
+ Pre_emptionCapability_may_trigger_pre_emption;
+
+ drbItem->qoSInformation.choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability =
+ Pre_emptionVulnerability_pre_emptable;
+
+ break;
+ }
+ case QoSInformation_PR_choice_extension:
+ {
+ CU_ALLOC(drbItem->qoSInformation.choice.choice_extension,sizeof(QoSInformation_ExtIEs_t));
+ if(drbItem->qoSInformation.choice.choice_extension == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in FillDrbItemToSetupMod");
+ return RFAILED;
+ }
+
+ drbItem->qoSInformation.choice.choice_extension->id = ProtocolIE_ID_id_DRB_Information;
+ drbItem->qoSInformation.choice.choice_extension->criticality = Criticality_ignore;
+ drbItem->qoSInformation.choice.choice_extension->value.present = QoSInformation_ExtIEs__value_PR_DRB_Information;
+ ret = BuildQOSInfo(&drbItem->qoSInformation.choice.choice_extension->value.choice.DRB_Information.dRB_QoS,\
+ ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item, PDU_SESSION_ID_2);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildQOSInfo failed");
+ return RFAILED;
+ }
+
+ /*SNSSAI*/
+ ret = BuildSNSSAI(&drbItem->qoSInformation.choice.\
+ choice_extension->value.choice.DRB_Information.sNSSAI, cuCfgParams.snssaiList[1]);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildSNSSAI failed");
+ return RFAILED;
+ }
+
+ /*Flows mapped to DRB List*/
+ ret = BuildFlowsMap(&drbItem->qoSInformation.choice.\
+ choice_extension->value.choice.DRB_Information.flows_Mapped_To_DRB_List,\
+ ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildFlowsMap failed");
+ return RFAILED;
+ }
+ }
+ }
+
+ /*ULUPTNLInformation To Be Setup List*/
+ ret = BuildUlTnlInfoforSetupMod(ueId, drbItem->dRBID, &drbItem->uLUPTNLInformation_ToBeSetup_List, \
+ ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildUlTnlInfoforSetupMod failed");
+ return RFAILED;
+ }
+
+ /*RLCMode*/
+ drbItem->rLCMode = RLCMode_rlc_um_bidirectional;
+ return ROK;
+}
+
+/*******************************************************************
+*
+* @brief Builds the DRB to be Setup Mod ItemIes
+*
+* @details
+*
+* Function : FillDrbItemList
+*
+* Functionality: Constructs the DRB to be Setup Mod Item Ies
+*
+* @params[in] struct DRBs_ToBeSetupMod_ItemIEs *drbItemIe
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t FillDrbItemList(uint8_t ueId, uint8_t arrIdx, struct DRBs_ToBeSetupMod_ItemIEs *drbItemIe)
+{
+ drbItemIe->id = ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item;
+ drbItemIe->criticality = Criticality_reject;
+ drbItemIe->value.present = DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item;
+
+ if(FillDrbItemToSetupMod(ueId, arrIdx, (&(drbItemIe->value.choice.DRBs_ToBeSetupMod_Item))) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : FillDrbItemToSetupMod failed");
+ return RFAILED;
+ }
+ return ROK;
+}
+/*******************************************************************
+*
+* @brief free the DRB to be Setup Mod list
+*
+* @details
+*
+* Function : FreeDrbToBeSetupModList
+*
+* Functionality: free the DRB to be Setup Mod list
+*
+* @params[in] DRBs_ToBeSetupMod_List_t *drbSet
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+void FreeDrbToBeSetupModList(DRBs_ToBeSetupMod_List_t *drbSet)
+{
+ uint8_t arrIdx =0;
+ struct DRBs_ToBeSetupMod_ItemIEs *drbItemIe;
+
+ if(drbSet->list.array)
+ {
+ for(arrIdx=0; arrIdx<drbSet->list.count ; arrIdx++)
+ {
+ if(drbSet->list.array[arrIdx] != NULLP)
+ {
+ if(arrIdx == 0)
+ {
+ drbItemIe = (DRBs_ToBeSetupMod_ItemIEs_t *)drbSet->list.array[arrIdx];
+ FreeDrbItem(&(drbItemIe->value.choice.DRBs_ToBeSetupMod_Item));
+ }
+ CU_FREE(drbSet->list.array[arrIdx], sizeof(DRBs_ToBeSetupMod_ItemIEs_t));
+ }
+ }
+ CU_FREE(drbSet->list.array, drbSet->list.size);
+ }
+
+}
+
+/*******************************************************************
+*
+* @brief Builds the DRB to be Setup Mod list
+*
+* @details
+*
+* Function : BuildDrbToBeSetupList
+*
+* Functionality: Constructs the DRB to be Setup Mod list
+*
+* @params[in] DRBs_ToBeSetupMod_List_t *drbSet
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t BuildDrbToBeSetupList(uint8_t ueId, DRBs_ToBeSetupMod_List_t *drbSet)
+{
+ uint8_t ret = ROK;
+ uint8_t arrIdx =0;
+ uint8_t drbCnt =0;
+
+ drbCnt = MAX_DRB_SET_UE_CONTEXT_MOD_REQ;
+ drbSet->list.count = drbCnt;
+ drbSet->list.size = drbCnt * sizeof(DRBs_ToBeSetupMod_ItemIEs_t *);
+ CU_ALLOC(drbSet->list.array, drbSet->list.size);
+ if(drbSet->list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildDrbToBeSetupList");
+ return RFAILED;
+ }
+
+ for(arrIdx=0; arrIdx<drbCnt; arrIdx++)
+ {
+ CU_ALLOC(drbSet->list.array[arrIdx], sizeof(DRBs_ToBeSetupMod_ItemIEs_t));
+ if(drbSet->list.array[arrIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildDrbToBeSetupList for array idx [%d]", arrIdx);
+ return RFAILED;
+ }
+
+ ret = FillDrbItemList(ueId, arrIdx, (DRBs_ToBeSetupMod_ItemIEs_t *)drbSet->list.array[arrIdx]);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : FillDrbItemList failed");
+ }
+ }
+
+ return ret;
+}
+
+/*******************************************************************
+*
+* @brief Filling the DRB to be modified item
+*
+* @details
+*
+* Function : FillDrbToBeModItem
+*
+* Functionality: filling the DRB to be modified item
+*
+* @params[in] DRBs_ToBeModified_Item_t *drbItem
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t FillDrbToBeModItem(uint8_t ueId, uint8_t arrIdx, DRBs_ToBeModified_Item_t *drbItem)
+{
+ uint8_t ret = ROK;
+
+ /*Drb Id */
+ drbItem->dRBID = DRB2 + arrIdx;
+
+ /*qoSInformation*/
+ drbItem->qoSInformation = NULLP;
+ CU_ALLOC(drbItem->qoSInformation, sizeof(QoSInformation_t));
+ if(drbItem->qoSInformation != NULLP)
+ {
+ drbItem->qoSInformation->present = QoSInformation_PR_choice_extension;
+
+ switch(drbItem->qoSInformation->present)
+ {
+ case QoSInformation_PR_NOTHING:
+ {
+ break;
+ }
+ case QoSInformation_PR_eUTRANQoS:
+ {
+
+ CU_ALLOC(drbItem->qoSInformation->choice.eUTRANQoS, sizeof(EUTRANQoS_t));
+ if(drbItem->qoSInformation->choice.eUTRANQoS)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in FillDrbToBeModItem");
+ return RFAILED;
+ }
+ drbItem->qoSInformation->choice.eUTRANQoS->qCI = QCI;
+ drbItem->qoSInformation->choice.eUTRANQoS->allocationAndRetentionPriority.priorityLevel =
+ PriorityLevel_no_priority;
+
+ drbItem->qoSInformation->choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability =
+ Pre_emptionCapability_may_trigger_pre_emption;
+
+ drbItem->qoSInformation->choice.eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability =
+ Pre_emptionVulnerability_pre_emptable;
+
+ break;
+ }
+ case QoSInformation_PR_choice_extension:
+ {
+ CU_ALLOC(drbItem->qoSInformation->choice.choice_extension,sizeof(QoSInformation_ExtIEs_t));
+ if(drbItem->qoSInformation->choice.choice_extension == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in FillDrbItemToSetupMod");
+ return RFAILED;
+ }
+
+ drbItem->qoSInformation->choice.choice_extension->id = ProtocolIE_ID_id_DRB_Information;
+ drbItem->qoSInformation->choice.choice_extension->criticality = Criticality_ignore;
+ drbItem->qoSInformation->choice.choice_extension->value.present = QoSInformation_ExtIEs__value_PR_DRB_Information;
+ ret = BuildQOSInfo(&drbItem->qoSInformation->choice.choice_extension->value.choice.DRB_Information.dRB_QoS,\
+ ProtocolIE_ID_id_DRBs_ToBeModified_Item, INVALID_PDU_SESSION_ID);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildQOSInfo failed");
+ return RFAILED;
+ }
+
+ /*SNSSAI*/
+ ret = BuildSNSSAI(&drbItem->qoSInformation->choice.\
+ choice_extension->value.choice.DRB_Information.sNSSAI,cuCfgParams.snssaiList[0]);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildSNSSAI failed");
+ return RFAILED;
+ }
+
+ /*Flows mapped to DRB List*/
+ ret = BuildFlowsMap(&drbItem->qoSInformation->choice.\
+ choice_extension->value.choice.DRB_Information.flows_Mapped_To_DRB_List,\
+ ProtocolIE_ID_id_DRBs_ToBeModified_Item);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildFlowsMap failed");
+ return RFAILED;
+ }
+ }
+ }
+ }/* End of QoS */
+
+ /*ULUPTNLInformation To Be Setup List*/
+ ret = BuildUlTnlInfoforSetupMod(ueId, drbItem->dRBID, &drbItem->uLUPTNLInformation_ToBeSetup_List,\
+ ProtocolIE_ID_id_DRBs_ToBeModified_Item);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildUlTnlInfoforSetupMod failed");
+ return RFAILED;
+ }
+ return ROK;
+}
+
+/*******************************************************************
+*
+* @brief Builds the DRB to be modified Item IE
+*
+* @details
+*
+* Function : FillDrbToBeModItemList
+*
+* Functionality: Constructs the DRB to be modified Mod Item Ies
+*
+* @params[in] struct DRBs_ToBeModified_ItemIEs *drbItemIe
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t FillDrbToBeModItemList(uint8_t ueId, uint8_t arrIdx, struct DRBs_ToBeModified_ItemIEs *drbItemIe)
+{
+ drbItemIe->id = ProtocolIE_ID_id_DRBs_ToBeModified_Item;
+ drbItemIe->criticality = Criticality_reject;
+ drbItemIe->value.present = DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item;
+ if(FillDrbToBeModItem(ueId, arrIdx, &(drbItemIe->value.choice.DRBs_ToBeModified_Item)) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : FillDrbToBeModItem failed");
+ return RFAILED;
+ }
+
+ return ROK;
+}
+
+/*******************************************************************
+*
+* @brief Builds the DRB to be modified list
+*
+* @details
+*
+* Function : BuildDrbToBeModList
+*
+* Functionality: Constructs the DRB to be modified list
+*
+* @params[in] DRBs_ToBeModified_List_t *drbSet
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+uint8_t BuildDrbToBeModifiedList(uint8_t ueId, DRBs_ToBeModified_List_t *drbSet)
+{
+ uint8_t ret = ROK;
+ uint8_t arrIdx =0;
+ uint8_t drbCnt =0;
+
+ drbCnt = MAX_DRB_MODIFIED_UE_MOD_REQ;
+ drbSet->list.count = drbCnt;
+ drbSet->list.size = drbCnt * sizeof(DRBs_ToBeModified_ItemIEs_t *);
+ CU_ALLOC(drbSet->list.array, drbSet->list.size);
+ if(drbSet->list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildDrbToBeModifiedList");
+ return RFAILED;
+ }
+ for(arrIdx=0; arrIdx<drbCnt; arrIdx++)
+ {
+ CU_ALLOC(drbSet->list.array[arrIdx], sizeof(DRBs_ToBeModified_ItemIEs_t));
+ if(drbSet->list.array[arrIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed in BuildDrbToBeSetupList");
+ return RFAILED;
+ }
+
+ ret = FillDrbToBeModItemList(ueId, arrIdx, (DRBs_ToBeModified_ItemIEs_t *)drbSet->list.array[arrIdx]);
+ if(ret != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : FillDrbToBeModItemList failed");
+ }
+ }
+
+ return ret;
+}
+
+/*******************************************************************
+*
+* @brief freeing the DRB item
+*
+* @details
+*
+* Function : FreeModifiedDrbItem
+*
+* Functionality: freeing the DRB 2 item
+*
+* @params[in] DRBs_ToBeSetupMod_Item_t *drbItem
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+
+void FreeModifiedDrbItem(DRBs_ToBeModified_Item_t *drbItem)
+{
+ uint8_t arrIdx =0;
+ SNSSAI_t *snssai =NULLP;
+ Flows_Mapped_To_DRB_List_t *flowMap = NULLP;
+
+ if(drbItem->qoSInformation != NULLP)
+ {
+ switch(drbItem->qoSInformation->present)
+ {
+ case QoSInformation_PR_NOTHING:
+ break;
+ case QoSInformation_PR_eUTRANQoS:
+ {
+ if(drbItem->qoSInformation->choice.eUTRANQoS)
+ {
+ CU_FREE(drbItem->qoSInformation->choice.eUTRANQoS, sizeof(EUTRANQoS_t));
+ }
+ break;
+ }
+ case QoSInformation_PR_choice_extension:
+ {
+ if(drbItem->qoSInformation->choice.choice_extension)
+ {
+ FreeQOSInfo(&drbItem->qoSInformation->choice.choice_extension->value.choice.DRB_Information.dRB_QoS);
+
+ snssai = &drbItem->qoSInformation->choice.choice_extension->value.choice.DRB_Information.sNSSAI;
+ if(snssai->sST.buf)
+ {
+ CU_FREE(snssai->sST.buf,snssai->sST.size);
+ }
+ if(snssai->sD)
+ {
+ if(snssai->sD->buf)
+ {
+ CU_FREE(snssai->sD->buf,snssai->sD->size);
+ }
+ CU_FREE(snssai->sD,sizeof(OCTET_STRING_t));
+ }
+
+ flowMap = &drbItem->qoSInformation->choice.choice_extension->value.choice.DRB_Information.flows_Mapped_To_DRB_List;
+ if(flowMap->list.array)
+ {
+ for(arrIdx=0; arrIdx<flowMap->list.count; arrIdx++)
+ {
+ if(flowMap->list.array[arrIdx] )
+ {
+ FreeQOSInfo(&flowMap->list.array[arrIdx]->qoSFlowLevelQoSParameters);
+ CU_FREE(flowMap->list.array[arrIdx],sizeof(Flows_Mapped_To_DRB_Item_t));
+ }
+ }
+ CU_FREE(flowMap->list.array,flowMap->list.size);
+ }
+
+ CU_FREE(drbItem->qoSInformation->choice.choice_extension,sizeof(QoSInformation_ExtIEs_t));
+ }
+ break;
+ }
+ }
+ }
+ FreeUlTnlInfoforDrb2(&drbItem->uLUPTNLInformation_ToBeSetup_List);
+ if(drbItem->uLConfiguration)
+ {
+ CU_FREE(drbItem->uLConfiguration,sizeof(ULConfiguration_t));
+ }
+}
+
+/*******************************************************************
+*
+* @brief free the DRB to be modfified list
+*
+* @details
+*
+* Function : FreeDrbToBeModifiedList
+*
+* Functionality: free the DRB to be Setup Mod list
+*
+* @params[in] FreeDrbToBeModifiedList_t *drbSet
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+void FreeDrbToBeModifiedList(DRBs_ToBeModified_List_t *drbSet)
+{
+ uint8_t arrIdx =0;
+ struct DRBs_ToBeModified_ItemIEs *drbItemIe;
+
+ if(drbSet->list.array)
+ {
+ for(arrIdx=0; arrIdx<drbSet->list.count ; arrIdx++)
+ {
+ if(drbSet->list.array[arrIdx] != NULLP)
+ {
+ drbItemIe = (struct DRBs_ToBeModified_ItemIEs *)drbSet->list.array[arrIdx];
+ FreeModifiedDrbItem(&(drbItemIe->value.choice.DRBs_ToBeModified_Item));
+ CU_FREE(drbSet->list.array[arrIdx], sizeof(DRBs_ToBeModified_ItemIEs_t));
+ }
+ }
+ CU_FREE(drbSet->list.array, drbSet->list.size);
+ }
+
+}
+
+/*******************************************************************
+ *
+ * @brief free the UeContextModification Request
+ *
+ * @details
+ *
+ * Function : FreeUeContextModicationRequest
+ *
+ * Functionality : deallocation of memory allocated in UeContextModiification
+ request
+ *
+ * @params[in] F1AP_PDU_t *f1apMsg
+ *
+ * @return void
+*
+* ****************************************************************/
+void FreeUeContextModicationRequest(F1AP_PDU_t *f1apMsg)
+{
+ uint8_t arrIdx =0 , ieId=0;
+ UEContextModificationRequest_t *UeContextModifyReq = NULLP;
+
+ if(f1apMsg)
+ {
+ if(f1apMsg->choice.initiatingMessage)
+ {
+ UeContextModifyReq =&f1apMsg->choice.initiatingMessage->value.choice.UEContextModificationRequest;
+ if(UeContextModifyReq->protocolIEs.list.array)
+ {
+ for( arrIdx = 0 ; arrIdx<UeContextModifyReq->protocolIEs.list.count ; arrIdx++)
+ {
+ if(UeContextModifyReq->protocolIEs.list.array[arrIdx])
+ {
+ ieId = UeContextModifyReq->protocolIEs.list.array[arrIdx]->id;
+ switch(ieId)
+ {
+ case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+ break;
+ case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
+ break;
+ case ProtocolIE_ID_id_DRBs_ToBeSetupMod_List:
+ {
+ FreeDrbToBeSetupModList(&UeContextModifyReq->protocolIEs.list.array[arrIdx]->value.\
+ choice.DRBs_ToBeSetupMod_List);
+ break;
+ }
+ case ProtocolIE_ID_id_DRBs_ToBeModified_List:
+ {
+ FreeDrbToBeModifiedList(&UeContextModifyReq->protocolIEs.list.array[arrIdx]->value.\
+ choice.DRBs_ToBeSetupMod_List);
+ break;
+ }
+
+ }
+ CU_FREE(UeContextModifyReq->protocolIEs.list.array[arrIdx], sizeof(UEContextModificationRequest_t));
+ }
+ }
+ CU_FREE(UeContextModifyReq->protocolIEs.list.array, UeContextModifyReq->protocolIEs.list.size);
+ }
+ CU_FREE(f1apMsg->choice.initiatingMessage, sizeof(InitiatingMessage_t));
+ }
+ CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
+ }
+}
+/*******************************************************************
+ *
+ * @brief Builds the Ue Context Modification Req
+ *
+ * @details
+ *
+ * Function : BuildAndSendUeContextModificationReq
+ *
+ * Functionality: Constructs the Ue Context Modification Req
+ *
+ * @params[in]
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildAndSendUeContextModificationReq(uint8_t ueId)
+{
+ uint8_t ieIdx = 0;
+ uint8_t elementCnt = 0;
+ uint8_t ret = RFAILED;
+ F1AP_PDU_t *f1apMsg = NULLP;
+ UEContextModificationRequest_t *ueContextModifyReq = NULLP;
+
+ asn_enc_rval_t encRetVal;
+ DU_LOG("\nINFO --> F1AP : Building Ue context modification request\n");
+
+ while(1)
+ {
+ CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
+ if(f1apMsg == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation for F1AP-PDU failed Ue context modification");
+ break;
+ }
+
+ f1apMsg->present = F1AP_PDU_PR_initiatingMessage;
+
+ CU_ALLOC(f1apMsg->choice.initiatingMessage, sizeof(InitiatingMessage_t));
+ if(f1apMsg->choice.initiatingMessage == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation for F1AP-PDU failed Ue context modification");
+ break;
+ }
+ f1apMsg->choice.initiatingMessage->procedureCode = ProcedureCode_id_UEContextModification;
+ f1apMsg->choice.initiatingMessage->criticality = Criticality_reject;
+ f1apMsg->choice.initiatingMessage->value.present = InitiatingMessage__value_PR_UEContextModificationRequest;
+
+ ueContextModifyReq =&f1apMsg->choice.initiatingMessage->value.choice.UEContextModificationRequest;
+
+ elementCnt = 4;
+ ueContextModifyReq->protocolIEs.list.count = elementCnt;
+ ueContextModifyReq->protocolIEs.list.size = elementCnt*sizeof(UEContextModificationRequest_t *);
+
+ /* Initialize the UE context modification members */
+ CU_ALLOC(ueContextModifyReq->protocolIEs.list.array, ueContextModifyReq->protocolIEs.list.size);
+ if(ueContextModifyReq->protocolIEs.list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation for UE context modifcation Request failed");
+ break;
+ }
+
+ for(ieIdx=0 ; ieIdx<elementCnt; ieIdx++)
+ {
+ CU_ALLOC(ueContextModifyReq->protocolIEs.list.array[ieIdx], sizeof(UEContextModificationRequest_t));
+ if(ueContextModifyReq->protocolIEs.list.array[ieIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation for UE context modifcation Request failed");
+ break;
+ }
+ }
+
+
+ ieIdx=0;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = \
+ UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.GNB_CU_UE_F1AP_ID = ueId;
+
+ ieIdx++;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present=\
+ UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.GNB_DU_UE_F1AP_ID = ueId;
+
+ /* DRB to be setup list */
+ ieIdx++;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_DRBs_ToBeSetupMod_List;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present =\
+ UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List;
+ ret = BuildDrbToBeSetupList(ueId, &(ueContextModifyReq->protocolIEs.list.array[ieIdx]->\
+ value.choice.DRBs_ToBeSetupMod_List));
+
+ /* DRB to be modified list */
+ ieIdx++;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_DRBs_ToBeModified_List;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present =\
+ UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List;
+ ret = BuildDrbToBeModifiedList(ueId, &(ueContextModifyReq->protocolIEs.list.array[ieIdx]->\
+ value.choice.DRBs_ToBeModified_List));
+
+ /* TODO: DRB to be release list */
+
+ if(ret != ROK)
+ {
+ break;
+ }
+ xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
+
+ /* Encode the F1SetupRequest type as APER */
+ memset(encBuf, 0, ENC_BUF_MAX_LEN);
+ encBufSize = 0;
+ encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf,\
+ encBuf);
+
+ /* Encode results */
+ if(encRetVal.encoded == ENCODE_FAIL)
+ {
+ DU_LOG("\nERROR --> F1AP : Could not encode ueContextModifyReq structure (at %s)\n",\
+ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+ break;
+ }
+ else
+ {
+ DU_LOG("\nDEBUG --> F1AP : Created APER encodedbuffer for ueContextModifyReq\n");
+ for(ieIdx=0; ieIdx< encBufSize; ieIdx++)
+ {
+ DU_LOG("%x",encBuf[ieIdx]);
+ }
+ }
+
+ if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Sending Ue context modification request failed");
+ break;
+ }
+
+ ret = ROK;
+ break;
+
+ }
+ FreeUeContextModicationRequest(f1apMsg);
+ return ret;
+}
+/*****************************************************************i
+*
+* @brief Free memory allocated for UE Context Release Command
+*
+* @details
+*
+* Function : FreeUeContextReleaseCommand
+*
+* Functionality:
+* - Free memory allocated for UE Context Release Command
+*
+* @params[in] F1AP_PDU_t *f1apMsg
+* @return void
+*
+* *************************************************************/
+void FreeUeContextReleaseCommand(F1AP_PDU_t *f1apMsg)
+{
+ uint8_t ieIdx;
+ UEContextReleaseCommand_t *ueReleaseCommand = NULLP;
+
+ if(f1apMsg)
+ {
+ if(f1apMsg->choice.initiatingMessage)
+ {
+ ueReleaseCommand =&f1apMsg->choice.initiatingMessage->value.choice.UEContextReleaseCommand;
+ if(ueReleaseCommand->protocolIEs.list.array)
+ {
+ for(ieIdx=0 ; ieIdx<ueReleaseCommand->protocolIEs.list.count; ieIdx++)
+ {
+ CU_FREE(ueReleaseCommand->protocolIEs.list.array[ieIdx], sizeof(UEContextReleaseCommand_t));
+ }
+ CU_FREE(ueReleaseCommand->protocolIEs.list.array, ueReleaseCommand->protocolIEs.list.size);
+ }
+ CU_FREE(f1apMsg->choice.initiatingMessage, sizeof(InitiatingMessage_t));
+ }
+ CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
+ }
+}
+/*******************************************************************
+ *
+ * @brief Builds the Ue Context Release Command
+ *
+ * @details
+*
+* Function : BuildAndSendUeContextReleaseCommand
+*
+* Functionality: Constructs the Ue Context Release Command
+*
+* @params[in]
+*
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+uint8_t BuildAndSendUeContextReleaseCommand(uint8_t cuUeF1apId, uint8_t duUeF1apId)
+{
+ bool memAllocFailed = false;
+ uint8_t ieIdx = 0,elementCnt = 0, ret = RFAILED, bufLen=0;
+ F1AP_PDU_t *f1apMsg = NULLP;
+ UEContextReleaseCommand_t *ueContextReleaseCommand = NULLP;
+
+ asn_enc_rval_t encRetVal;
+ DU_LOG("\nINFO --> F1AP : Building Ue context release command\n");
+
+ while(true)
+ {
+ CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
+ if(f1apMsg == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendUeContextReleaseCommand(): Memory allocation for F1AP-PDU");
+ break;
+ }
+
+ f1apMsg->present = F1AP_PDU_PR_initiatingMessage;
+
+ CU_ALLOC(f1apMsg->choice.initiatingMessage, sizeof(InitiatingMessage_t));
+ if(f1apMsg->choice.initiatingMessage == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendUeContextReleaseCommand(): Memory allocation for F1AP-PDU failed ");
+ break;
+ }
+ f1apMsg->choice.initiatingMessage->procedureCode = ProcedureCode_id_UEContextRelease;
+ f1apMsg->choice.initiatingMessage->criticality = Criticality_reject;
+ f1apMsg->choice.initiatingMessage->value.present = InitiatingMessage__value_PR_UEContextReleaseCommand;
+
+ ueContextReleaseCommand =&f1apMsg->choice.initiatingMessage->value.choice.UEContextReleaseCommand;
+
+ elementCnt = 4;
+ ueContextReleaseCommand->protocolIEs.list.count = elementCnt;
+ ueContextReleaseCommand->protocolIEs.list.size = elementCnt*sizeof(UEContextReleaseCommand_t*);
+
+ /* Initialize the UE context modification members */
+ CU_ALLOC(ueContextReleaseCommand->protocolIEs.list.array, ueContextReleaseCommand->protocolIEs.list.size);
+ if(ueContextReleaseCommand->protocolIEs.list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendUeContextReleaseCommand():Memory allocation failed");
+ break;
+ }
+
+ for(ieIdx=0 ; ieIdx<elementCnt; ieIdx++)
+ {
+ CU_ALLOC(ueContextReleaseCommand->protocolIEs.list.array[ieIdx], sizeof(UEContextReleaseCommand_t));
+ if(ueContextReleaseCommand->protocolIEs.list.array[ieIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendUeContextReleaseCommand(): Memory allocation failed ");
+ memAllocFailed = true;
+ break;
+ }
+ }
+
+ if(memAllocFailed == true)
+ {
+ break;
+ }
+ ieIdx=0;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.present = \
+ UEContextReleaseCommandIEs__value_PR_GNB_CU_UE_F1AP_ID;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.GNB_CU_UE_F1AP_ID =cuUeF1apId;
+
+ ieIdx++;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.present=\
+ UEContextReleaseCommandIEs__value_PR_GNB_DU_UE_F1AP_ID;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.GNB_DU_UE_F1AP_ID =duUeF1apId;
+
+ ieIdx++;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_Cause;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.present=\
+ UEContextReleaseCommandIEs__value_PR_Cause;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.Cause.present = Cause_PR_radioNetwork;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.Cause.choice.radioNetwork=\
+ CauseRadioNetwork_normal_release;
+
+ /* RRC Container for RRC release */
+ ieIdx++;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_RRCContainer;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.present = \
+ UEContextReleaseCommandIEs__value_PR_RRCContainer;
+ char secModeBuf[7]={ 0x00, 0x05, 0x13, 0x00, 0x00, 0x00, 0x00};
+ bufLen =7;
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.size = bufLen;
+ CU_ALLOC(ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf,
+ ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.size);
+ if(!ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation for BuildAndSendUeContextReleaseCommand failed");
+ break;
+ }
+ memset(ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf, 0, bufLen);
+ memcpy(ueContextReleaseCommand->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf, secModeBuf, bufLen);
+
+ xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg);
+
+ /* Encode the UE Context Release Command type as APER */
+ memset(encBuf, 0, ENC_BUF_MAX_LEN);
+ encBufSize = 0;
+ encRetVal = aper_encode(&asn_DEF_F1AP_PDU, 0, f1apMsg, PrepFinalEncBuf,\
+ encBuf);
+
+ /* Encode results */
+ if(encRetVal.encoded == ENCODE_FAIL)
+ {
+ DU_LOG("\nERROR --> F1AP : Could not encode Release Command structure (at %s)\n",\
+ encRetVal.failed_type ? encRetVal.failed_type->name : "unknown");
+ break;
+ }
+ else
+ {
+ DU_LOG("\nDEBUG --> F1AP : Created APER encoded buffer for Ue Context Release Command\n");
+ for(ieIdx=0; ieIdx< encBufSize; ieIdx++)
+ {
+ DU_LOG("%x",encBuf[ieIdx]);
+ }
+ }
+
+ if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Sending Ue context Release Command failed");
+ break;
+ }
+
+ ret = ROK;
+ break;
+
+ }
+ FreeUeContextReleaseCommand(f1apMsg);
+ return ret;
+}
+/*******************************************************************
+*
+* @brief process Ue context release request
+*
+* @details
+*
+* Function : procUeContextReleaseReq
+*
+* Functionality:
+* - process Ue context release request
+*
+* @params[in] F1AP_PDU_t *f1apMsg
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+uint8_t procUeContextReleaseReq(F1AP_PDU_t *f1apMsg)
+{
+ uint8_t ieIdx=0, duUeF1apId=0,cuUeF1apId=0;
+
+ UEContextReleaseRequest_t *ueReleaseReq = NULLP;
+ ueReleaseReq = &f1apMsg->choice.initiatingMessage->value.choice.UEContextReleaseRequest;
+
+ for(ieIdx=0; ieIdx < ueReleaseReq->protocolIEs.list.count; ieIdx++)
+ {
+ switch(ueReleaseReq->protocolIEs.list.array[ieIdx]->id)
+ {
+ case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+ {
+ cuUeF1apId = ueReleaseReq->protocolIEs.list.array[ieIdx]->value.choice.GNB_CU_UE_F1AP_ID;
+ break;
+ }
+ case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
+ {
+ duUeF1apId = ueReleaseReq->protocolIEs.list.array[ieIdx]->value.choice.GNB_DU_UE_F1AP_ID;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if(BuildAndSendUeContextReleaseCommand(cuUeF1apId, duUeF1apId) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : procUeContextReleaseReq(): Failed to build Ue Context Release Command ");
+ return RFAILED;
+ }
+ return ROK;
+}
+/*******************************************************************
+*
+* @brief processing of Gnb-DU config update
+*
+* @details
+*
+* Function : procGnbDuUpdate
+*
+* Functionality:
+* - processing of Gnb-DU config update
+*
+* @params[in] F1AP_PDU_t *f1apMsg
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+uint8_t procGnbDuUpdate(F1AP_PDU_t *f1apMsg)
+{
+ bool cellToBeDelete = false;
+ uint8_t ieIdx = 0, ueIdx = 0;
+ GNBDUConfigurationUpdate_t *duCfgUpdate = NULLP;
+
+ duCfgUpdate = &f1apMsg->choice.initiatingMessage->value.choice.GNBDUConfigurationUpdate;
+ for(ieIdx=0; ieIdx < duCfgUpdate->protocolIEs.list.count; ieIdx++)
+ {
+ switch(duCfgUpdate->protocolIEs.list.array[ieIdx]->id)
+ {
+ case ProtocolIE_ID_id_TransactionID:
+ break;
+ case ProtocolIE_ID_id_Served_Cells_To_Modify_List:
+ break;
+ case ProtocolIE_ID_id_Served_Cells_To_Delete_List:
+ {
+ cellToBeDelete = true;
+ break;
+ }
+ case ProtocolIE_ID_id_gNB_DU_ID:
+ break;
+ }
+ }
+ if(BuildAndSendDUUpdateAck() != ROK)
+ {
+ DU_LOG("ERROR --> F1AP : Failed to build and send DUUpdateAck");
+ return RFAILED;
+ }
+#if 0
+ /* We don't require F1 Reset message in Cell Up and Broadcast Procedure flow, So that's why
+ * commented this trigger for now */
+
+ if(cellToBeDelete == false)
+ {
+ DU_LOG("\nINFO --> F1AP : Sending F1 reset request");
+ if(BuildAndSendF1ResetReq() != ROK)
+ {
+ DU_LOG("ERROR --> F1AP : Failed to build and send F1 reset request");
+ return RFAILED;
+ }
+ }
+#endif
+ if(cellToBeDelete == true)
+ {
+ for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+ {
+ CU_FREE(ueCb[ueIdx].f1apMsgDb.duToCuContainer.buf, ueCb[ueIdx].f1apMsgDb.duToCuContainer.size);
+ memset(&ueCb[ueIdx], 0, sizeof(UeCb));
+ }
+ }
+
+ return ROK;
+}
+
+/*******************************************************************
+*
+* @brief storing slice list in CU database
+*
+* @details
+*
+* Function : buildSliceList
+*
+* Functionality:
+* - storing slice list in CU database
+*
+* @params[in] SliceSupportList_t *sliceSupportList
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+uint8_t buildSliceList(SliceSupportList_t *sliceSupportList)
+{
+ uint8_t sliceListIdx = 0;
+
+ if(sliceSupportList)
+ {
+ if(sliceSupportList->list.array)
+ {
+ cuCfgParams.numSnssaiSupported = sliceSupportList->list.count;
+ for(sliceListIdx=0; sliceListIdx<sliceSupportList->list.count; sliceListIdx++)
+ {
+ if(sliceSupportList->list.array[sliceListIdx])
+ {
+ CU_ALLOC(cuCfgParams.snssaiList[sliceListIdx], sizeof(Snssai));
+ if(cuCfgParams.snssaiList[sliceListIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> CU_STUB: buildSliceList(): Memory allocation failed");
+ return RFAILED;
+ }
+ if(sliceSupportList->list.array[sliceListIdx]->sNSSAI.sST.buf)
+ {
+ memcpy(&cuCfgParams.snssaiList[sliceListIdx]->sst, sliceSupportList->list.array[sliceListIdx]->\
+ sNSSAI.sST.buf, sliceSupportList->list.array[sliceListIdx]->sNSSAI.sST.size);
+ }
+ if(sliceSupportList->list.array[sliceListIdx]->sNSSAI.sD->size)
+ {
+ memcpy(&cuCfgParams.snssaiList[sliceListIdx]->sd,\
+ sliceSupportList->list.array[sliceListIdx]->sNSSAI.sD->buf,\
+ sliceSupportList->list.array[sliceListIdx]->sNSSAI.sD->size);
+ }
+ }
+ }
+ }
+ }
+ return ROK;
+}
+
+/****************************************************************
+ * @brief Function to process Drb Setup Mod List
+ *
+ * @details
+ *
+ * Function : procDrbSetupModList
+ *
+ * Functionality:
+ * - Function to process DRB Setup Mod List
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t procDrbSetupModList(DRBs_SetupMod_List_t *drbSetupList)
+{
+ uint8_t arrIdx = 0;
+ uint32_t teId = 0;
+ struct DRBs_SetupMod_ItemIEs *drbItemIe = NULLP;
+
+ if(drbSetupList != NULLP)
+ {
+ for(arrIdx = 0; arrIdx < drbSetupList->list.count; arrIdx++)
+ {
+ drbItemIe = ((struct DRBs_SetupMod_ItemIEs *)drbSetupList->list.array[arrIdx]);
+ if(drbItemIe->value.present == DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item)
+ {
+ /* extracting teId */
+ teId = extractTeId(&drbItemIe->value.choice.DRBs_SetupMod_Item.dLUPTNLInformation_ToBeSetup_List);
+ if(teId > 0)
+ {
+ if(addDrbTunnels(teId)== ROK)
+ {
+ DU_LOG("\nDEBUG --> EGTP: Tunnel Added for TeId %d", teId);
+ }
+ }
+ else
+ return RFAILED;
+ }
+ }
+ }
+ return ROK;
+}
+
+/*******************************************************************
+*
+* @brief processing of GNB_DU_Served_Cells Plmn list information
+*
+* @details
+*
+* Function : procServedCellPlmnList
+*
+* Functionality:
+* - processing of GNB_DU_Served_Cells Plmn list information for storing
+* SNSSAI list
+*
+* @params[in] F1AP_PDU_t *f1apMsg
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+uint8_t procServedCellPlmnList(ServedPLMNs_List_t *srvPlmn)
+{
+ uint8_t srvPlmnIdx=0, ieExtensionsLstIdx=0;
+ ProtocolExtensionContainer_4624P3_t **ieExtend;
+
+ if(srvPlmn->list.array)
+ {
+ for(srvPlmnIdx=0; srvPlmnIdx<srvPlmn->list.count; srvPlmnIdx++)
+ {
+ if(srvPlmn->list.array[srvPlmnIdx])
+ {
+ ieExtend = &srvPlmn->list.array[srvPlmnIdx]->iE_Extensions;
+ if(*ieExtend)
+ {
+ if((*ieExtend)->list.array)
+ {
+ for(ieExtensionsLstIdx = 0; ieExtensionsLstIdx<(*ieExtend)->list.count; ieExtensionsLstIdx++)
+ {
+ if((*ieExtend)->list.array[ieExtensionsLstIdx])
+ {
+ switch((*ieExtend)->list.array[ieExtensionsLstIdx]->id )
+ {
+ case ProtocolIE_ID_id_TAISliceSupportList:
+ {
+ if(buildSliceList(&(*ieExtend)->list.array[ieExtensionsLstIdx]->\
+ extensionValue.choice.SliceSupportList) != ROK)
+ {
+ DU_LOG("\nERROR --> CU_STUB: procServedCellPlmnList(): Failed to build slice List");
+ return RFAILED;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return ROK;
+}
+
+/****************************************************************
+ * @brief Function to process Ue Context Modification Response
+ *
+ * @details
+ *
+ * Function : procUeContextModificationResponse
+ *
+ * Functionality:
+ * - Function to process Ue Context Modification Response
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t procUeContextModificationResponse(F1AP_PDU_t *f1apMsg)
+{
+ uint8_t idx, duUeF1apId;
+ UEContextModificationResponse_t *ueCtxtModRsp = NULLP;
+ ueCtxtModRsp = &f1apMsg->choice.successfulOutcome->value.choice.UEContextModificationResponse;
+
+ for(idx=0; idx < ueCtxtModRsp->protocolIEs.list.count; idx++)
+ {
+ switch(ueCtxtModRsp->protocolIEs.list.array[idx]->id)
+ {
+ case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
+ {
+ duUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID;
+ break;
+ }
+ case ProtocolIE_ID_id_DRBs_SetupMod_List:
+ {
+ /* Adding Tunnels for successful DRB */
+ procDrbSetupModList(&ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.DRBs_SetupMod_List);
+ break;
+
+ }
+ }
+ }
+ return ROK;
+}
+
+/*******************************************************************
+*
+* @brief processing of F1 setup request
+*
+* @details
+*
+* Function : procF1SetupReq
+*
+* Functionality:
+* - processing of F1 setup request
+*
+* @params[in] F1AP_PDU_t *f1apMsg
+* @return ROK - success
+* RFAILED - failure
+*
+* ****************************************************************/
+void procF1SetupReq(F1AP_PDU_t *f1apMsg)
+{
+ uint8_t ieIdx = 0, plmnidx=0, ret=ROK;
+ BIT_STRING_t nrcellIdentity;
+ F1SetupRequest_t *f1SetupReq = NULLP;
+ GNB_DU_Served_Cells_Item_t *srvCellItem = NULLP;
+ GNB_DU_Served_Cells_List_t *duServedCell = NULLP;
+
+ f1SetupReq = &f1apMsg->choice.initiatingMessage->value.choice.F1SetupRequest;
+ for(ieIdx=0; ieIdx < f1SetupReq->protocolIEs.list.count; ieIdx++)
+ {
+ switch(f1SetupReq->protocolIEs.list.array[ieIdx]->id)
+ {
+ case ProtocolIE_ID_id_gNB_DU_Served_Cells_List:
+ {
+ duServedCell = &f1SetupReq->protocolIEs.list.array[ieIdx]->value.choice.GNB_DU_Served_Cells_List;
+ if(duServedCell->list.array)
+ {
+ for(plmnidx=0; plmnidx<duServedCell->list.count; plmnidx++)
+ {
+ if(duServedCell->list.array[plmnidx])
+ {
+ switch(duServedCell->list.array[plmnidx]->id)
+ {
+ case ProtocolIE_ID_id_GNB_DU_Served_Cells_Item:
+ {
+ srvCellItem = &duServedCell->list.array[plmnidx]->value.choice.GNB_DU_Served_Cells_Item;
+ ret = procServedCellPlmnList(&srvCellItem->served_Cell_Information.servedPLMNs);
+ memcpy(&nrcellIdentity, &srvCellItem->served_Cell_Information.nRCGI.nRCellIdentity, sizeof(BIT_STRING_t));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if(ret == ROK)
+ {
+ BuildAndSendF1SetupRsp(&nrcellIdentity);
+ }
+ else
+ {
+ DU_LOG("\nERROR --> CU_STUB: procF1SetupReq(): Failed to process F1 setup request");
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Handles received F1AP message and sends back response
+ *
+ * @details
+ *
+ * Function : F1APMsgHdlr
+ *
+ * Functionality:
+ * - Decodes received F1AP control message
+ * - Prepares response message, encodes and sends to SCTP
+ *
+ * @params[in]
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+void F1APMsgHdlr(Buffer *mBuf)
+{
+ int i;
+ char *recvBuf;
+ MsgLen copyCnt;
+ MsgLen recvBufLen;
+ F1AP_PDU_t *f1apMsg = NULLP;
+ asn_dec_rval_t rval; /* Decoder return value */
+ F1AP_PDU_t f1apasnmsg ;
+
+ DU_LOG("\nINFO --> F1AP : Received F1AP message buffer");
+ ODU_PRINT_MSG(mBuf, 0,0);
+
+ /* Copy mBuf into char array to decode it */
+ ODU_GET_MSG_LEN(mBuf, &recvBufLen);
+ CU_ALLOC(recvBuf, (Size)recvBufLen);
+
+ if(recvBuf == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : Memory allocation failed");
+ return;
+ }
+ if(ODU_COPY_MSG_TO_FIX_BUF(mBuf, 0, recvBufLen, (Data *)recvBuf, ©Cnt) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Failed while copying %d", copyCnt);
+ return;
+ }
+
+ DU_LOG("\nDEBUG --> F1AP : Received flat buffer to be decoded : ");
+ for(i=0; i< recvBufLen; i++)
+ {
+ DU_LOG("%x",recvBuf[i]);
+ }
+
+ /* Decoding flat buffer into F1AP messsage */
+ f1apMsg = &f1apasnmsg;