#include "MeasConfigRrc.h"
#include "AS-Config.h"
#include "RRCReconfiguration-v1530-IEs.h"
+#include "CNUEPagingIdentity.h"
+#include "PagingCell-Item.h"
#include "cu_stub_sctp.h"
#include "cu_stub_egtp.h"
uint8_t ret;
uint8_t unused_bits = 4;
uint8_t byteSize = 5;
- uint8_t val = nrCellId << unused_bits;
/* Allocate Buffer Memory */
nrcgi->pLMN_Identity.size = 3 * sizeof(uint8_t);
{
return RFAILED;
}
- fillBitString(&nrcgi->nRCellIdentity, unused_bits, byteSize, val);
+ fillBitString(&nrcgi->nRCellIdentity, unused_bits, byteSize, nrCellId);
return ROK;
}
ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[0] = 0;
ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[1] = 0;
ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[2] = 0;
- ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[3] = cuCb.cuCfgParams.egtpParams.egtpAssoc[duId-1].currTunnelId++;
+ ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[3] = cuCb.cuCfgParams.egtpParams.currTunnelId++;
ulUpTnlInfo->teId[0] = ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[0];
ulUpTnlInfo->teId[1] = ulInfo->list.array[idx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[1];
* @return void
*
* ****************************************************************/
-uint8_t freeQuantityConfig(QuantityConfig_t *quantityCfg)
+void freeQuantityConfig(QuantityConfig_t *quantityCfg)
{
uint8_t quanCfgIdx;
QuantityConfigNR_t *quantityCfgNr;
* ****************************************************************/
uint8_t procUeContextSetupResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
{
- uint8_t duIdx=0, idx, duUeF1apId;
- DuDb *duDb;
- CuUeCb *ueCb;
+ uint8_t duIdx = 0, idx = 0, ueIdx = 0;
+ uint8_t duUeF1apId = 0, cuUeF1apId = 0;
+ DuDb *duDb = NULLP;
+ CuUeCb *ueCb = NULLP;
UEContextSetupResponse_t *ueCtxtSetupRsp = NULLP;
SEARCH_DU_DB(duIdx, duId, duDb);
{
switch(ueCtxtSetupRsp->protocolIEs.list.array[idx]->id)
{
+ case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+ {
+ cuUeF1apId = ueCtxtSetupRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID;
+ break;
+ }
case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
{
duUeF1apId = ueCtxtSetupRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID;
ueCb = &duDb->ueCb[duUeF1apId-1];
+ /* If ue context is not present in du db, then create UE context
+ * here. This flow is hit in case of UE handover where UE
+ * context is created before UE performs RACH on target DU */
+ if(ueCb->gnbDuUeF1apId == 0)
+ {
+ /* Creating UE context in target DU */
+ memset(ueCb, 0, sizeof(CuUeCb));
+ ueCb->cellCb = &duDb->cellCb[0];
+ ueCb->gnbDuUeF1apId = duUeF1apId;
+ ueCb->gnbCuUeF1apId = cuUeF1apId;
+ ueCb->state = UE_HANDOVER_IN_PROGRESS;
+ ueCb->hoInfo.targetDuId = duId;
+ (duDb->numUe)++;
+
+ ueCb->cellCb->ueCb[ueCb->cellCb->numUe] = ueCb;
+ ueCb->cellCb->numUe++;
+ }
+ break;
+ }
+ case ProtocolIE_ID_id_C_RNTI:
+ {
+ ueCb->crnti = ueCtxtSetupRsp->protocolIEs.list.array[idx]->value.choice.C_RNTI;
break;
}
case ProtocolIE_ID_id_DRBs_Setup_List:
}
}
}
+
ueCb->f1apMsgDb.dlRrcMsgCount++; /* keeping DL RRC Msg Count */
+
+ /* If the UE is in handover, UE context modification request is to be sent to
+ * source DU once UE context setup response is received from target DU */
+ if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
+ {
+ DuDb *srcDuDb = NULLP;
+ CuUeCb *ueCbInSrcDu = NULLP;
+
+ /* Since Source DU Id and DU UE F1AP ID assigned to UE by source DU is not known here, we
+ * need to find Source DU and UE CB in source DU using CU UE F1AP ID */
+ for(duIdx=0; duIdx < cuCb.numDu; duIdx++)
+ {
+ /* UE context setup response is received from target DU. Search all
+ * DUs to find source DU except this target DU Id.*/
+ if(cuCb.duInfo[duIdx].duId != duId)
+ {
+ for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+ {
+ /* Check following:
+ * 1. CU UE F1AP ID in srcDU->ueCb should be same as cuUeF1apId
+ * received in UE context setup response since CU UE F1AP ID does not
+ * change for UE in handover.
+ * 2. srcDU->UeCb->uestate should be UE_HANDOVER_IN_PROGRESS
+ */
+ if((cuCb.duInfo[duIdx].ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId) &&
+ (cuCb.duInfo[duIdx].ueCb[ueIdx].state == UE_HANDOVER_IN_PROGRESS))
+ {
+ srcDuDb = &cuCb.duInfo[duIdx];
+ ueCbInSrcDu = &cuCb.duInfo[duIdx].ueCb[ueIdx];
+
+ /* Store source DU info in the new UE context created in
+ * tareget DU */
+ ueCb->hoInfo.sourceDuId = srcDuDb->duId;
+ if(BuildAndSendUeContextModificationReq(srcDuDb->duId, ueCbInSrcDu, STOP_DATA_TX) != ROK)
+ {
+ DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextModificationReq()");
+ return RFAILED;
+ }
+ break;
+ }
+ }
+ }
+ if(srcDuDb && ueCbInSrcDu)
+ break;
+ }
+ }
return ROK;
}
else
{
ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->\
- gTP_TEID.buf[3] = cuCb.cuCfgParams.egtpParams.egtpAssoc[duId-1].currTunnelId++;
+ gTP_TEID.buf[3] = cuCb.cuCfgParams.egtpParams.currTunnelId++;
}
ulTnlInfo->teId[0] = ulInfo->list.array[arrIdx]->uLUPTNLInformation.choice.gTPTunnel->gTP_TEID.buf[0];
CuUeCb *ueCb = (CuUeCb *)cuUeCb;
F1AP_PDU_t *f1apMsg = NULLP;
UEContextModificationRequest_t *ueContextModifyReq = NULLP;
- action =RESTART_DATA_TX;
asn_enc_rval_t encRetVal;
DU_LOG("\nINFO --> F1AP : Building Ue context modification request\n");
while(1)
{
SEARCH_DU_DB(duIdx, duId, duDb);
SEARCH_CELL_DB(cellIdx, duDb, nrCellId, cellCb);
- for(ueIdx = 0; ueIdx < cellCb->numUe; ueIdx++)
+ if(cellCb->numUe == 0)
{
- CU_FREE(cellCb->ueCb[ueIdx]->f1apMsgDb.duToCuContainer.buf, cellCb->ueCb[ueIdx]->f1apMsgDb.duToCuContainer.size);
- memset(cellCb->ueCb[ueIdx], 0, sizeof(CuUeCb));
+ memset(cellCb, 0, sizeof(CuCellCb));
+ duDb->numCells--;
}
+ else
+ cellCb->cellStatus = CELL_DELETION_IN_PROGRESS;
}
-
return ROK;
}
* ****************************************************************/
uint8_t procUeContextModificationResponse(uint32_t duId, F1AP_PDU_t *f1apMsg)
{
- uint8_t idx=0, duIdx=0, duUeF1apId;
- DuDb *duDb;
- CuUeCb *ueCb;
+ uint8_t idx=0, duIdx=0;
+ uint8_t duUeF1apId = 0, cuUeF1apId = 0;
+ DuDb *duDb = NULLP;
+ CuUeCb *ueCb = NULLP;
UEContextModificationResponse_t *ueCtxtModRsp = NULLP;
SEARCH_DU_DB(duIdx, duId, duDb);
{
switch(ueCtxtModRsp->protocolIEs.list.array[idx]->id)
{
+ case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID:
+ {
+ cuUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_CU_UE_F1AP_ID;
+ break;
+ }
case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID:
{
duUeF1apId = ueCtxtModRsp->protocolIEs.list.array[idx]->value.choice.GNB_DU_UE_F1AP_ID;
}
}
+
+ /* If UE is in handover and UE context is not yet created at target DU, then send
+ * UE context setup request to target DU */
if(ueCb->state == UE_HANDOVER_IN_PROGRESS)
{
- BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetDuId, ueCb, 0, NULLP);
- return ROK;
+ uint8_t ueIdx = 0;
+ DuDb *tgtDuDb = NULLP;
+ CuUeCb *ueCbInTgtDu = NULLP;
+
+ SEARCH_DU_DB(duIdx, ueCb->hoInfo.targetDuId, tgtDuDb);
+ if(tgtDuDb)
+ {
+ /* Since DU UE F1AP ID assigned by target DU to this UE in handover is
+ * not known here, using CU UE F1AP ID to search for UE Cb in target DU
+ * DB */
+ for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
+ {
+ if(tgtDuDb->ueCb[ueIdx].gnbCuUeF1apId == cuUeF1apId)
+ {
+ ueCbInTgtDu = &tgtDuDb->ueCb[ueIdx];
+ break;
+ }
+ }
+
+ /* If UE context is not found in Target DU DU, send UE context setup
+ * request */
+ if(ueCbInTgtDu == NULLP)
+ {
+ if((BuildAndSendUeContextSetupReq(ueCb->hoInfo.targetDuId, ueCb, 0, NULLP)) != ROK)
+ {
+ DU_LOG("\nERROR -> F1AP : Failed at BuildAndSendUeContextSetupReq");
+ return RFAILED;
+ }
+ }
+ }
}
return ROK;
cellCb = &duDb->cellCb[duDb->numCells];
memset(cellCb, 0, sizeof(CuCellCb));
cellCb->nrCellId = nrCellId;
+ cellCb->cellStatus = CELL_ACTIVE;
duDb->numCells++;
}
}
{
gnbDuUeF1apId = ueReleaseComplete->protocolIEs.list.array[ieIdx]->value.choice.GNB_DU_UE_F1AP_ID;
ueCb = &duDb->ueCb[gnbDuUeF1apId-1];
-
- for(ueIdx = 0; ueIdx < ueCb->cellCb->numUe; ueIdx++)
+ for(ueIdx = 0; ueIdx <MAX_NUM_UE; ueIdx++)
{
- if((ueCb->cellCb->ueCb[ueIdx]->gnbCuUeF1apId == gnbCuUeF1apId) &&
- (ueCb->cellCb->ueCb[ueIdx]->gnbDuUeF1apId == gnbDuUeF1apId))
+ if(ueCb->cellCb && ueCb->cellCb->ueCb[ueIdx])
{
- ueCb->cellCb->ueCb[ueIdx] = NULLP;
- ueCb->cellCb->numUe--;
- break;
-
+ if((ueCb->cellCb->ueCb[ueIdx]->gnbCuUeF1apId == gnbCuUeF1apId) &&
+ (ueCb->cellCb->ueCb[ueIdx]->gnbDuUeF1apId == gnbDuUeF1apId))
+ {
+ ueCb->cellCb->ueCb[ueIdx] = NULLP;
+ ueCb->cellCb->numUe--;
+ if((ueCb->cellCb->numUe == 0) && (ueCb->cellCb->cellStatus = CELL_DELETION_IN_PROGRESS))
+ {
+ memset(ueCb->cellCb, 0, sizeof(CuCellCb));
+ duDb->numCells--;
+ }
+ break;
+ }
}
}
memset(ueCb, 0, sizeof(CuUeCb));
}
}
+/*******************************************************************
+ *
+ * @brief Builds the Paging cell list
+ *
+ * @details
+ *
+ * Function : BuildPagingCellList
+ *
+ * Functionality: Build the paging cell list
+ *
+ * @params[in] PagingCell_list_t *pagingCelllist,
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildPagingCellList(PagingCell_list_t *pagingCelllist, uint8_t numCells, CuCellCb *cellCb)
+{
+ uint8_t cellIdx =0;
+ PagingCell_ItemIEs_t *pagingCellItemIes;
+ PagingCell_Item_t *pagingCellItem;
+
+ pagingCelllist->list.count = numCells;
+ pagingCelllist->list.size = pagingCelllist->list.count * (sizeof(PagingCell_ItemIEs_t*));
+ CU_ALLOC(pagingCelllist->list.array, pagingCelllist->list.size);
+ if(pagingCelllist->list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildPagingCellList(): Memory allocation failed ");
+ return RFAILED;
+ }
+
+ for(cellIdx = 0; cellIdx < pagingCelllist->list.count; cellIdx++)
+ {
+ CU_ALLOC(pagingCelllist->list.array[cellIdx], sizeof(PagingCell_ItemIEs_t));
+ if(pagingCelllist->list.array[cellIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildPagingCellList(): Memory allocation failed ");
+ return RFAILED;
+ }
+ }
+
+ for(cellIdx = 0; cellIdx < pagingCelllist->list.count; cellIdx++)
+ {
+ pagingCellItemIes = (PagingCell_ItemIEs_t *)pagingCelllist->list.array[cellIdx];
+ pagingCellItemIes->id = ProtocolIE_ID_id_PagingCell_Item;
+ pagingCellItemIes->criticality = Criticality_ignore;
+ pagingCellItemIes->value.present = PagingCell_ItemIEs__value_PR_PagingCell_Item;
+ pagingCellItem = &pagingCellItemIes->value.choice.PagingCell_Item;
+
+ /* Fill NrCgi Information */
+ BuildNrcgi(&pagingCellItem->nRCGI, cellCb[cellIdx].nrCellId);
+ }
+
+ return ROK;
+}
+
+/*******************************************************************
+ *
+ * @brief Deallocation of memory allocated in paging msg
+ *
+ * @details
+ *
+ * Function :FreePagingMsg
+ *
+ * Functionality: Deallocation of memory allocated in paging msg
+ *
+ * @params[in] F1AP_PDU_t *f1apMsg
+ *
+ * @return void
+ *
+ * ****************************************************************/
+void FreePagingMsg(F1AP_PDU_t *f1apMsg)
+{
+ uint8_t ieIdx, cellIdx;
+ Paging_t *paging;
+ PagingCell_ItemIEs_t *pagingCellItemIes;
+ PagingCell_Item_t *pagingCellItem;
+ PagingCell_list_t *pagingCelllist;
+
+ if(f1apMsg)
+ {
+ if(f1apMsg->choice.initiatingMessage)
+ {
+ paging = &f1apMsg->choice.initiatingMessage->value.choice.Paging;
+ if(paging->protocolIEs.list.array)
+ {
+ for(ieIdx=0 ; ieIdx<paging->protocolIEs.list.count; ieIdx++)
+ {
+ if(paging->protocolIEs.list.array[ieIdx])
+ {
+ switch(paging->protocolIEs.list.array[ieIdx]->id)
+ {
+ case ProtocolIE_ID_id_UEIdentityIndexValue:
+ {
+ CU_FREE(paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10.buf,\
+ paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10.size);
+ break;
+ }
+
+ case ProtocolIE_ID_id_PagingIdentity:
+ {
+ if(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.present == PagingIdentity_PR_cNUEPagingIdentity)
+ {
+ if(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity)
+ {
+ if(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->present == CNUEPagingIdentity_PR_fiveG_S_TMSI)
+ {
+ CU_FREE(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf,\
+ paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.size);
+ }
+ CU_FREE(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity,\
+ sizeof(struct CNUEPagingIdentity));
+ }
+ }
+ break;
+ }
+
+ case ProtocolIE_ID_id_PagingCell_List:
+ {
+ pagingCelllist = &paging->protocolIEs.list.array[ieIdx]->value.choice.PagingCell_list;
+ if(pagingCelllist->list.array)
+ {
+ for(cellIdx = 0; cellIdx < pagingCelllist->list.count; cellIdx++)
+ {
+ if(pagingCelllist->list.array[cellIdx])
+ {
+ pagingCellItemIes = (PagingCell_ItemIEs_t *)pagingCelllist->list.array[cellIdx];
+ if(pagingCellItemIes->id == ProtocolIE_ID_id_PagingCell_Item)
+ {
+ pagingCellItem = &pagingCellItemIes->value.choice.PagingCell_Item;
+ CU_FREE(pagingCellItem->nRCGI.pLMN_Identity.buf, pagingCellItem->nRCGI.pLMN_Identity.size);
+ CU_FREE(pagingCellItem->nRCGI.nRCellIdentity.buf, pagingCellItem->nRCGI.nRCellIdentity.size);
+ }
+ CU_FREE(pagingCelllist->list.array[cellIdx], sizeof(PagingCell_ItemIEs_t));
+ }
+ }
+ CU_FREE(pagingCelllist->list.array, pagingCelllist->list.size);
+ }
+ break;
+ }
+ }
+ CU_FREE(paging->protocolIEs.list.array[ieIdx], sizeof(Paging_t));
+ }
+ }
+ CU_FREE(paging->protocolIEs.list.array, paging->protocolIEs.list.size);
+ }
+ CU_FREE(f1apMsg->choice.initiatingMessage, sizeof(InitiatingMessage_t));
+ }
+ CU_FREE(f1apMsg, sizeof(F1AP_PDU_t));
+ }
+}
+/*******************************************************************
+ *
+ * @brief Builds and sends the paging message if UE is in idle mode
+ *
+ * @details
+ *
+ * Function : BuildAndSendPagingMsg
+ *
+ * Functionality: Builds and sends the paging message
+ *
+ * @params[in] uint32_t duId, uint8_t gsTmsi
+ *
+ * @return ROK - success
+ * RFAILED - failure
+ *
+ * ****************************************************************/
+uint8_t BuildAndSendPagingMsg(uint64_t gsTmsi, uint8_t duId)
+{
+ bool memAllocFailed = false;
+ uint8_t ieIdx = 0, elementCnt = 0, ret = RFAILED;
+ uint16_t ueId = 0, duIdx = 0;
+
+ /*As per 38.473 Sec 9.3.1.39, UE Identity Index Value (10bits) > 2 Bytes + 6 Unused Bits
+ *5G-S-TMSI :48 Bits >> 6 Bytes and 0 UnusedBits */
+ uint8_t totalByteInUeId = 2, totalByteInTmsi = 6;
+ uint8_t unusedBitsInUeId = 6, unusedBitsInTmsi = 0;
+
+ F1AP_PDU_t *f1apMsg = NULLP;
+ Paging_t *paging = NULLP;
+ DuDb *duDb;
+ asn_enc_rval_t encRetVal;
+
+ DU_LOG("\nINFO --> F1AP : Building PAGING Message command\n");
+
+ SEARCH_DU_DB(duIdx, duId, duDb);
+ if(duDb == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): DuDb is empty");
+ return ret;
+ }
+
+ while(true)
+ {
+ CU_ALLOC(f1apMsg, sizeof(F1AP_PDU_t));
+ if(f1apMsg == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): 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 : BuildAndSendPagingMsg(): Memory allocation for F1AP-PDU failed ");
+ break;
+ }
+ f1apMsg->choice.initiatingMessage->procedureCode = ProcedureCode_id_Paging;
+ f1apMsg->choice.initiatingMessage->criticality = Criticality_reject;
+ f1apMsg->choice.initiatingMessage->value.present = InitiatingMessage__value_PR_Paging;
+
+ paging = &f1apMsg->choice.initiatingMessage->value.choice.Paging;
+
+ elementCnt = 5;
+ paging->protocolIEs.list.count = elementCnt;
+ paging->protocolIEs.list.size = elementCnt * sizeof(Paging_t*);
+
+ /* Initialize the Paging Message members */
+ CU_ALLOC(paging->protocolIEs.list.array, paging->protocolIEs.list.size);
+ if(paging->protocolIEs.list.array == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg():Memory allocation failed");
+ break;
+ }
+
+ for(ieIdx=0 ; ieIdx<elementCnt; ieIdx++)
+ {
+ CU_ALLOC(paging->protocolIEs.list.array[ieIdx], sizeof(Paging_t));
+ if(paging->protocolIEs.list.array[ieIdx] == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): Memory allocation failed ");
+ memAllocFailed = true;
+ break;
+ }
+ }
+
+ if(memAllocFailed == true)
+ {
+ break;
+ }
+
+ /* UE Identity Index Value */
+ ieIdx=0;
+ paging->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_UEIdentityIndexValue;
+ paging->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ paging->protocolIEs.list.array[ieIdx]->value.present = PagingIEs__value_PR_UEIdentityIndexValue;
+ paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.present = UEIdentityIndexValue_PR_indexLength10;
+ paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10.size = totalByteInUeId*sizeof(uint8_t);
+ CU_ALLOC(paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10.buf,\
+ paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10.size);
+ if(paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10.buf == NULLP)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): Memory allocation failed ");
+ break;
+ }
+
+ /*As per 3gpp Spec 38.304 Sec 7.1: UE_ID: 5G-S-TMSI mod 1024*/
+ ueId = gsTmsi % 1024;
+ fillBitString(&paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10, unusedBitsInUeId, totalByteInUeId, ueId);
+
+ /* Paging Identity */
+ ieIdx++;
+ paging->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_PagingIdentity;
+ paging->protocolIEs.list.array[ieIdx]->criticality = Criticality_reject;
+ paging->protocolIEs.list.array[ieIdx]->value.present = PagingIEs__value_PR_PagingIdentity;
+ paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.present = \
+ PagingIdentity_PR_cNUEPagingIdentity;
+ CU_ALLOC(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity, \
+ sizeof(struct CNUEPagingIdentity));
+ if(!paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): Memory allocation failed ");
+ break;
+ }
+
+ paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->present = \
+ CNUEPagingIdentity_PR_fiveG_S_TMSI;
+
+ paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.size = totalByteInTmsi*sizeof(uint8_t);
+ CU_ALLOC(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf,\
+ paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.size);
+ if(!paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): Memory allocation failed ");
+ break;
+ }
+
+ fillBitString(&paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI,\
+ unusedBitsInTmsi, totalByteInTmsi, gsTmsi);
+
+ /* Paging Drx */
+ ieIdx++;
+ paging->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_PagingDRX;
+ paging->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
+ paging->protocolIEs.list.array[ieIdx]->value.present = PagingIEs__value_PR_PagingDRX;
+ paging->protocolIEs.list.array[ieIdx]->value.choice.PagingDRX = PagingDRX_v32;
+
+ /* Paging Priority */
+ ieIdx++;
+ paging->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_PagingPriority;
+ paging->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
+ paging->protocolIEs.list.array[ieIdx]->value.present = PagingIEs__value_PR_PagingPriority;
+ paging->protocolIEs.list.array[ieIdx]->value.choice.PagingPriority = PagingPriority_priolevel2;
+
+ /* Paging Cell List */
+ ieIdx++;
+ paging->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_PagingCell_List;
+ paging->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore;
+ paging->protocolIEs.list.array[ieIdx]->value.present = PagingIEs__value_PR_PagingCell_list;
+ if(BuildPagingCellList(&paging->protocolIEs.list.array[ieIdx]->value.choice.PagingCell_list, duDb->numCells, duDb->cellCb) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : BuildAndSendPagingMsg(): Failed to build Paging cell list ");
+ break;
+ }
+
+ 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 Paging\n");
+ for(ieIdx=0; ieIdx< encBufSize; ieIdx++)
+ {
+ DU_LOG("%x",encBuf[ieIdx]);
+ }
+ }
+
+ if(SendF1APMsg(CU_APP_MEM_REG, CU_POOL, duId) != ROK)
+ {
+ DU_LOG("\nERROR --> F1AP : Sending Ue context Release Command failed");
+ break;
+ }
+
+ ret = ROK;
+ break;
+
+ }
+
+ FreePagingMsg(f1apMsg);
+ return ret;
+}
+
/*******************************************************************
*
* @brief Handles received F1AP message and sends back response