From b5a77f556b20a2acd7d653367fdcac030461f85b Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Thu, 31 Mar 2022 16:37:38 +0530 Subject: [PATCH] <[Epic-ID: ODUHIGH-406][Task-ID: ODUHIGH-421]Paging Message: CU_STUB Trigger and DUAPP Handling> Signed-off-by: lal.harshita Change-Id: Id12aa24f102fc617ba0d26effedb52828d6ae278 Signed-off-by: lal.harshita --- src/5gnrmac/mac_msg_router.c | 2 +- src/5gnrsch/sch.c | 7 +- src/cm/du_app_mac_inf.c | 2 +- src/cm/du_app_mac_inf.h | 15 -- src/codec_utils/common/odu_common_codec.c | 29 ++- src/codec_utils/common/odu_common_codec.h | 2 +- src/cu_stub/cu_f1ap_msg_hdl.c | 363 +++++++++++++++++++++++++++++- src/cu_stub/cu_f1ap_msg_hdl.h | 1 + src/cu_stub/cu_stub.c | 21 +- src/du_app/du_cell_mgr.c | 172 ++++++++++++-- src/du_app/du_cell_mgr.h | 1 + src/du_app/du_cfg.c | 35 ++- src/du_app/du_cfg.h | 38 +++- src/du_app/du_e2ap_msg_hdl.c | 12 +- src/du_app/du_f1ap_conversions.c | 142 ++++++++++-- src/du_app/du_f1ap_conversions.h | 21 +- src/du_app/du_f1ap_msg_hdl.c | 239 +++++++++++++++++++- src/du_app/du_mgr.h | 19 ++ src/du_app/du_sys_info_hdl.c | 9 +- src/ric_stub/ric_e2ap_msg_hdl.c | 4 +- src/ric_stub/ric_stub.c | 2 + 21 files changed, 1041 insertions(+), 95 deletions(-) diff --git a/src/5gnrmac/mac_msg_router.c b/src/5gnrmac/mac_msg_router.c index f3ef9b9c5..60be907c5 100755 --- a/src/5gnrmac/mac_msg_router.c +++ b/src/5gnrmac/mac_msg_router.c @@ -473,7 +473,7 @@ void callFlowRgActvTsk(Pst *pst) strcpy(message,"EVENT_MAC_SLICE_CFG_REQ"); break; case EVENT_MAC_SLICE_RECFG_REQ: - strcpy(message,"EVENT_MAC_SLICE_CFG_REQ"); + strcpy(message,"EVENT_MAC_SLICE_RECFG_REQ"); break; default: strcpy(message,"Invalid Event"); diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index 992485b4e..fe18fec2e 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -1762,7 +1762,9 @@ uint8_t addSliceCfgInSchDb(SchSliceCfg *storeSliceCfg, SchSliceCfgReq *cfgReq, S return RFAILED; } - memcpy(storeSliceCfg->listOfConfirguration[sliceIdx], cfgReq->listOfConfirguration[sliceIdx], sizeof(SchRrmPolicyOfSlice)); + memcpy(&storeSliceCfg->listOfConfirguration[sliceIdx]->snssai, &cfgReq->listOfConfirguration[sliceIdx]->snssai, sizeof(Snssai)); + memcpy(storeSliceCfg->listOfConfirguration[sliceIdx]->rrmPolicyRatioInfo, cfgReq->listOfConfirguration[sliceIdx]->rrmPolicyRatioInfo, + sizeof(SchRrmPolicyRatio)); sliceIdx++; } } @@ -1898,7 +1900,8 @@ uint8_t modifySliceCfgInSchDb(SchSliceCfg *storeSliceCfg, SchSliceCfgReq *cfgReq { if(!memcmp(&storeSliceCfg->listOfConfirguration[sliceIdx]->snssai, &cfgReq->listOfConfirguration[cfgIdx]->snssai, sizeof(Snssai))) { - storeSliceCfg->listOfConfirguration[sliceIdx]->rrmPolicyRatioInfo = cfgReq->listOfConfirguration[cfgIdx]->rrmPolicyRatioInfo; + memcpy(storeSliceCfg->listOfConfirguration[sliceIdx]->rrmPolicyRatioInfo, cfgReq->listOfConfirguration[cfgIdx]->rrmPolicyRatioInfo, + sizeof(SchRrmPolicyRatio)); break; } } diff --git a/src/cm/du_app_mac_inf.c b/src/cm/du_app_mac_inf.c index 21f2dfaa3..e0e75c52f 100644 --- a/src/cm/du_app_mac_inf.c +++ b/src/cm/du_app_mac_inf.c @@ -1505,7 +1505,7 @@ uint8_t unpackDuMacSliceReCfgRsp(MacDuSliceReCfgRspFunc func, Pst *pst, Buffer * * * @details * - * Function : packDuMacSliceReCfgRsp + * Function : packMacSlotInd * * Functionality: * Pack and send Slot ind from MAC to DU APP diff --git a/src/cm/du_app_mac_inf.h b/src/cm/du_app_mac_inf.h index afd6ca672..16763d9b2 100644 --- a/src/cm/du_app_mac_inf.h +++ b/src/cm/du_app_mac_inf.h @@ -85,21 +85,6 @@ #define BSR_RETX_TIMER_SF_320 320 #define BSR_SR_DELAY_TMR_2560 2560 -#define GET_PAGING_CYCLE(enmValue, T) { \ - if (enmValue == 0) T = 32; \ - else if (enmValue == 1) T = 64; \ - else if (enmValue == 2) T = 128; \ - else if (enmValue == 3) T = 256; \ - else T = 0; \ -} - -#define GET_NUM_PAGING_OCC(enmValue, PO) { \ - if (enmValue == 0) PO = 4; \ - else if (enmValue == 1) PO = 2; \ - else if (enmValue == 2) PO = 1; \ - else PO = 0; \ -} - #define PAGING_SCHED_DELTA 4 typedef enum diff --git a/src/codec_utils/common/odu_common_codec.c b/src/codec_utils/common/odu_common_codec.c index b3ba6bc3e..a65aefc9e 100644 --- a/src/codec_utils/common/odu_common_codec.c +++ b/src/codec_utils/common/odu_common_codec.c @@ -48,16 +48,29 @@ int PrepFinalEncBuf(const void *buffer, size_t size, void *encodedBuf) * * ****************************************************************/ -uint8_t fillBitString(BIT_STRING_t *id, uint8_t unusedBits, uint8_t byteSize, uint8_t val) +uint8_t fillBitString(BIT_STRING_t *id, uint8_t unusedBits, uint8_t byteSize, uint64_t data) { - uint8_t tmp; + uint64_t tmp = 0; + uint8_t byteIdx = 0; + if(id->buf == NULLP) { + DU_LOG("\nERROR --> DU_APP : Buffer allocation is empty"); return RFAILED; } - - memset(id->buf, 0, byteSize-1); - id->buf[byteSize-1] = val; + memset(id->buf, 0, byteSize); + data = data << unusedBits; + + /*Now, seggregate the value into 'byteSize' number of Octets in sequence: + * 1. Pull out a byte of value (Starting from MSB) and put in the 0th Octet + * 2. Fill the buffer/String Octet one by one until LSB is reached*/ + for(byteIdx = 1; byteIdx <= byteSize; byteIdx++) + { + tmp = (uint64_t)0xFF; + tmp = (tmp << (8 * (byteSize - byteIdx))); + tmp = (data & tmp) >> (8 * (byteSize - byteIdx)); + id->buf[byteIdx - 1] = tmp; + } id->bits_unused = unusedBits; return ROK; } @@ -81,16 +94,16 @@ uint8_t fillBitString(BIT_STRING_t *id, uint8_t unusedBits, uint8_t byteSize, ui uint8_t bitStringToInt(BIT_STRING_t *bitString, void *value) { uint16_t idx; - uint32_t *val = NULLP; + uint64_t *val = NULLP; if(bitString->buf == NULL || bitString->size <= 0) { - DU_LOG("\nDU_APP : Bit string is empty"); + DU_LOG("\nERROR --> DU_APP : Bit string is empty"); return RFAILED; } if(value) - val = (uint32_t *)value; + val = (uint64_t *)value; else return RFAILED; diff --git a/src/codec_utils/common/odu_common_codec.h b/src/codec_utils/common/odu_common_codec.h index 6edd2c28d..1c06c6565 100644 --- a/src/codec_utils/common/odu_common_codec.h +++ b/src/codec_utils/common/odu_common_codec.h @@ -28,7 +28,7 @@ char encBuf[ENC_BUF_MAX_LEN]; int encBufSize; int PrepFinalEncBuf(const void *buffer, size_t size, void *encodedBuf); -uint8_t fillBitString(BIT_STRING_t *id, uint8_t unusedBits, uint8_t byteSize, uint8_t val); +uint8_t fillBitString(BIT_STRING_t *id, uint8_t unusedBits, uint8_t byteSize, uint64_t val); uint8_t bitStringToInt(BIT_STRING_t *bitString, void *val); void fillTeIdString(uint8_t bufSize, uint32_t val, uint8_t *buf); void teIdStringToInt(uint8_t *buf, uint32_t *val); diff --git a/src/cu_stub/cu_f1ap_msg_hdl.c b/src/cu_stub/cu_f1ap_msg_hdl.c index 601e18efa..1349e086e 100644 --- a/src/cu_stub/cu_f1ap_msg_hdl.c +++ b/src/cu_stub/cu_f1ap_msg_hdl.c @@ -127,6 +127,8 @@ #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" @@ -2115,7 +2117,6 @@ uint8_t BuildNrcgi(NRCGI_t *nrcgi, uint32_t nrCellId) 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); @@ -2136,7 +2137,7 @@ uint8_t BuildNrcgi(NRCGI_t *nrcgi, uint32_t nrCellId) { return RFAILED; } - fillBitString(&nrcgi->nRCellIdentity, unused_bits, byteSize, val); + fillBitString(&nrcgi->nRCellIdentity, unused_bits, byteSize, nrCellId); return ROK; } @@ -7402,7 +7403,7 @@ void freeMeasIdToAddModList(MeasIdToAddModList_t *measIdList) * @return void * * ****************************************************************/ -uint8_t freeQuantityConfig(QuantityConfig_t *quantityCfg) +void freeQuantityConfig(QuantityConfig_t *quantityCfg) { uint8_t quanCfgIdx; QuantityConfigNR_t *quantityCfgNr; @@ -11480,6 +11481,362 @@ void procUeContextReleaseComplete(uint32_t duId, F1AP_PDU_t *f1apMsg) } } +/******************************************************************* + * + * @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 ; ieIdxprotocolIEs.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 ; ieIdxprotocolIEs.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 diff --git a/src/cu_stub/cu_f1ap_msg_hdl.h b/src/cu_stub/cu_f1ap_msg_hdl.h index 0ebc88d5f..51f8d9ae5 100644 --- a/src/cu_stub/cu_f1ap_msg_hdl.h +++ b/src/cu_stub/cu_f1ap_msg_hdl.h @@ -179,6 +179,7 @@ void F1APMsgHdlr(uint32_t *destDuId, Buffer *mBuf); uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *ueCb, UeCtxtModAction action); uint8_t BuildAndSendUeContextReleaseCommand(uint32_t duId, uint8_t cuUeF1apId, uint8_t duUeF1apId); uint8_t BuildAndSendF1ResetReq(); +uint8_t BuildAndSendPagingMsg(uint64_t gsTmsi, uint8_t duId); /********************************************************************** End of file diff --git a/src/cu_stub/cu_stub.c b/src/cu_stub/cu_stub.c index 31515a4c6..1a7fe9c57 100644 --- a/src/cu_stub/cu_stub.c +++ b/src/cu_stub/cu_stub.c @@ -285,11 +285,11 @@ void *cuConsoleHandler(void *args) if(ch == 'd') { - /* Change #if 0 to #if 1 to take input from user */ + /* Change #if 0 to #if 1 to take input from user */ #if 0 DU_LOG("\n EGTP --> : Enter TEID id(1..10) where DL Data to be sent\n"); scanf("%d",&teId); - + if(teId > MAX_TEID || teId < MIN_TEID) { DU_LOG("\nERROR --> EGTP : TEID(%x) OUT Of Range",teId); @@ -351,6 +351,23 @@ void *cuConsoleHandler(void *args) initiateInterDuHandover(sourceDuId, targetDuId, ueId); } + /* Start Idle mode paging when 'p' is received from console input */ + else if(ch == 'p') + { + uint64_t sTmsi = 0; + uint8_t duId = 0; + + DU_LOG("\nEnter DU ID on which this UE to be pagged"); + scanf("%d", &duId); + DU_LOG("\nEnter 5g-S-TMSI"); + scanf("%lu", &sTmsi); + + if(BuildAndSendPagingMsg(sTmsi, duId) != ROK) + { + DU_LOG("\nERROR --> EGTP: Failed to build and send paging message for 5gsTmsi[%lu]\n", sTmsi); + } + continue; + } } } /********************************************************************** diff --git a/src/du_app/du_cell_mgr.c b/src/du_app/du_cell_mgr.c index 635cda773..d40755b36 100644 --- a/src/du_app/du_cell_mgr.c +++ b/src/du_app/du_cell_mgr.c @@ -30,6 +30,7 @@ #include "du_mgr.h" #include "du_utils.h" #include "du_cell_mgr.h" +#include "PCCH-Config.h" #ifdef O1_ENABLE @@ -226,26 +227,6 @@ uint8_t duHandleCellUpInd(Pst *pst, OduCellId *cellId) { DuCellCb *cellCb = NULLP; -#ifndef O1_ENABLE - - /*Note: Static Configuration, when O1 is not configuring the RRM policy*/ - RrmPolicy *rrmPolicy; - DU_ALLOC(rrmPolicy, sizeof(RrmPolicy)); - rrmPolicy->rsrcType = RSRC_PRB; - rrmPolicy->numMemberList = 1; - DU_ALLOC(rrmPolicy->memberList, sizeof(PolicyMemberList *)); - DU_ALLOC(rrmPolicy->memberList[0], sizeof(PolicyMemberList)); - - memset(&rrmPolicy->memberList[0]->plmn, 0, sizeof(Plmn)); - rrmPolicy->memberList[0]->snssai.sst = 1; - rrmPolicy->memberList[0]->snssai.sd[0] = 2; - rrmPolicy->memberList[0]->snssai.sd[1] = 3; - rrmPolicy->memberList[0]->snssai.sd[2] = 4; - rrmPolicy->policyMinRatio = 30; - rrmPolicy->policyMaxRatio = 90; - rrmPolicy->policyDedicatedRatio = 10; -#endif - if(cellId->cellId <=0 || cellId->cellId > MAX_NUM_CELL) { DU_LOG("\nERROR --> DU APP : Invalid Cell Id %d in duHandleCellUpInd()", cellId->cellId); @@ -261,14 +242,12 @@ uint8_t duHandleCellUpInd(Pst *pst, OduCellId *cellId) cellCb->cellStatus = ACTIVATED; gCellStatus = CELL_UP; -#ifdef O1_ENABLE if(duCfgParam.tempSliceCfg.rrmPolicy) BuildAndSendSliceConfigReq(duCfgParam.tempSliceCfg.rrmPolicy, duCfgParam.tempSliceCfg.totalRrmPolicy, duCfgParam.tempSliceCfg.totalSliceCount); +#ifdef O1_ENABLE DU_LOG("\nINFO --> DU APP : Raise cell UP alarm for cell id=%d", cellId->cellId); raiseCellAlrm(CELL_UP_ALARM_ID, cellId->cellId); setCellOpState(cellId->cellId, ENABLED, ACTIVE); -#else - BuildAndSendSliceConfigReq(&rrmPolicy,1, rrmPolicy->numMemberList); #endif } @@ -442,6 +421,153 @@ uint8_t duSendCellDeletReq(uint16_t cellId) return ROK; } +/******************************************************************* + * @brief fill paging information of a UE belongs to a particular cell + * + * @details + * + * Function : FillPagingInfoInCellCb + * + * Functionality: fill paging information of a UE in DuCellCb + * + * @params[in] DuCellCb* cellCb, uint8_t ueId, + * DuPagingMsg rcvdF1apPagingParam + * + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t FillPagingInfoInCellCb(DuCellCb* cellCb, DuPagingMsg *rcvdF1apPagingParam) +{ + uint8_t ns = 0; + uint16_t T=0, N=0, pagingFrame = 0, n = 0; + uint16_t currentSfn = 0, sfn = 0, newSfn = 0; + PcchCfg duPcchCfg; + + DU_LOG("\nINFO --> DU APP : Start filling paging parameters in DuCellCb"); + if(cellCb) + { + /* calculate paging frame and paging offset */ + duPcchCfg = duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg; + rcvdF1apPagingParam->pagingFrameOffset = duPcchCfg.pageFrameOffset; + ns = duPcchCfg.ns; + + /* + * Fill the Value of T (DRX cycle of the UE) + * T = min(UE Specific DRX value allocated by upper layers, default DRX + * broadcast in System Information) */ + if((rcvdF1apPagingParam->pagingDrxPres) && (duPcchCfg.dfltPagingCycle > rcvdF1apPagingParam->pagingDrx)) + { + T = rcvdF1apPagingParam->pagingDrx; + } + else + { + T = duPcchCfg.dfltPagingCycle; + } + rcvdF1apPagingParam->T = T; + + /* N= number of total paging frames in T */ + + switch(duPcchCfg.nAndPagingFrmOffsetType) + { + case PCCH_Config__nAndPagingFrameOffset_PR_oneT: + N = T; + break; + case PCCH_Config__nAndPagingFrameOffset_PR_halfT: + N = T/2; + break; + case PCCH_Config__nAndPagingFrameOffset_PR_quarterT: + N = T/4; + break; + case PCCH_Config__nAndPagingFrameOffset_PR_oneEighthT: + N = T/8; + break; + case PCCH_Config__nAndPagingFrameOffset_PR_oneSixteenthT: + N = T/16; + break; + default: + N = T; + break; + } + + /* calculate the Value of pagingFrame */ + /*Refer: 38.304 Sec 7.1: (SFN + PF_offset) mod T = (T div N)*(UE_ID mod N)*/ + //RHS of above formula + pagingFrame = (T / N) * ((rcvdF1apPagingParam->ueId) % N); + + //LHS of above formula + if(pagingFrame) + { + pagingFrame = (pagingFrame - rcvdF1apPagingParam->pagingFrameOffset)%T; + } + else /*Paging Frame = 0 so thus PF will be calculated on Paging Cycle*/ + { + pagingFrame = (T - rcvdF1apPagingParam->pagingFrameOffset)%T; + } + + /*Paging Frame(SFN for Paging) has to be determined from current SFN. */ + /*For eg: If T =128, PF(Calculated above) = 20; SFN can be 20,148,276,... + * If currSFN is running as 200 then (newSFN % T) == (T/N)*(UE_ID%N) + *Thus SFN at which paging has to be sent needs to be delayed and newSFN = 276*/ + + currentSfn = cellCb->currSlotInfo.sfn; + + /*Multiplication Factor(x) to find the next best SFN to process paging*/ + + /*Below calculation will determine in which nth cycle of T (DRX cycle),new PF + * may fall(Delayed one)*/ + if(currentSfn > pagingFrame) + { + n = ((currentSfn - pagingFrame) / T) + 1; + } + else + { + n = ((pagingFrame - currentSfn) / T) + 1; + } + + newSfn = pagingFrame + T * n; + + /*When pagingFrame is future from currSFN then pagingFrame will be used + * else pagingFrame is delayed thus newSFN will be used.*/ + if(currentSfn <= pagingFrame) + { + if(pagingFrame > currentSfn + PAGING_SCHED_DELTA) + { + sfn = pagingFrame; + } + else + { + sfn = newSfn; + } + } + else + { + + if(newSfn > currentSfn + PAGING_SCHED_DELTA) + { + sfn = newSfn; + } + else /*If newSFN is near to currSFN then delay it more by T*/ + { + newSfn = newSfn + T; + sfn = newSfn; + } + } + rcvdF1apPagingParam->pagingFrame = (sfn % 1024); + rcvdF1apPagingParam->i_s = ((uint32_t)(floor(rcvdF1apPagingParam->ueId / N)) % ns); + + DU_LOG("\nINFO --> DU APP : Successfully filled paging parameter in DuCellCb"); + memcpy(&cellCb->tmpPagingInfoOfUe, rcvdF1apPagingParam, sizeof(DuPagingMsg)); + } + else + { + DU_LOG("\nINFO --> DU APP : FillPagingInfoInCellCb(): Received null pointer"); + return RFAILED; + } + return ROK; +} + + /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_cell_mgr.h b/src/du_app/du_cell_mgr.h index ee26fe4e5..5cd9c0d6a 100644 --- a/src/du_app/du_cell_mgr.h +++ b/src/du_app/du_cell_mgr.h @@ -26,6 +26,7 @@ void duProcF1SetupRsp(); uint8_t duGetCellCb(uint16_t cellId, DuCellCb **cellCb); uint8_t BuildAndSendSliceConfigReq(RrmPolicy *rrmPolicy[], uint8_t totalRrrmPolicy, uint8_t totalSliceCfgReq); uint8_t BuildAndSendSliceReCfgReq(RrmPolicy *rrmPolicy[], uint8_t totalRrmPolicy, uint8_t totalSliceReCfg); +uint8_t FillPagingInfoInCellCb(DuCellCb* cellCb, DuPagingMsg *rcvdF1apPagingParam); #endif /********************************************************************** End of file diff --git a/src/du_app/du_cfg.c b/src/du_app/du_cfg.c index d991cba15..1b3b6a0a3 100644 --- a/src/du_app/du_cfg.c +++ b/src/du_app/du_cfg.c @@ -27,6 +27,7 @@ #include "du_cfg.h" #include "du_mgr.h" #include "du_utils.h" +#include "du_f1ap_conversions.h" #include "OCTET_STRING.h" #include "BIT_STRING.h" #include "odu_common_codec.h" @@ -278,10 +279,9 @@ uint8_t readMacCfg() duCfgParam.macCellCfg.sib1Cfg.searchSpaceZeroIndex = SEARCHSPACE_0_INDEX; duCfgParam.macCellCfg.sib1Cfg.sib1Mcs = DEFAULT_MCS; - GET_NUM_PAGING_OCC(duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg.ns, - duCfgParam.macCellCfg.sib1Cfg.pagingCfg.numPO); - if(duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg.firstPDCCHMontioringType != \ - PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_NOTHING) + duCfgParam.macCellCfg.sib1Cfg.pagingCfg.numPO = duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg.ns; + if((duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg.firstPDCCHMontioringType != \ + PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_NOTHING) && (duCfgParam.macCellCfg.sib1Cfg.pagingCfg.numPO != 0)) { duCfgParam.macCellCfg.sib1Cfg.pagingCfg.poPresent = TRUE; memcpy(duCfgParam.macCellCfg.sib1Cfg.pagingCfg.pagingOcc, @@ -392,6 +392,27 @@ uint8_t readMacCfg() memcpy(duCfgParam.macCellCfg.plmnInfoList.snssai[sliceIdx], taiSliceSuppLst->snssai[sliceIdx], sizeof(Snssai)); } } + +#ifndef O1_ENABLE + + /*Note: Static Configuration, when O1 is not configuring the RRM policy*/ + RrmPolicyList rrmPolicy; + rrmPolicy.id[0] = 1; + rrmPolicy.resourceType = PRB; + rrmPolicy.rRMMemberNum = 1; + memcpy(rrmPolicy.rRMPolicyMemberList[0].mcc,duCfgParam.macCellCfg.plmnInfoList.plmn.mcc, 3*sizeof(uint8_t)); + memcpy(rrmPolicy.rRMPolicyMemberList[0].mnc,duCfgParam.macCellCfg.plmnInfoList.plmn.mnc, 3*sizeof(uint8_t)); + rrmPolicy.rRMPolicyMemberList[0].sst = 1; + rrmPolicy.rRMPolicyMemberList[0].sd[0] = 2; + rrmPolicy.rRMPolicyMemberList[0].sd[1] = 3; + rrmPolicy.rRMPolicyMemberList[0].sd[2] = 4; + rrmPolicy.rRMPolicyMaxRatio = 90; + rrmPolicy.rRMPolicyMinRatio = 30; + rrmPolicy.rRMPolicyDedicatedRatio = 10; + + cpyRrmPolicyInDuCfgParams(&rrmPolicy, 1, &duCfgParam.tempSliceCfg); + +#endif return ROK; } @@ -541,10 +562,10 @@ uint8_t fillServCellCfgCommSib(SrvCellCfgCommSib *srvCellCfgComm) BCCH_Config__modificationPeriodCoeff_n16; /* Configuring PCCH Config for SIB1 */ - pcchCfg.dfltPagingCycle = PagingCycle_rf256; + pcchCfg.dfltPagingCycle = convertPagingCycleEnumToValue(PagingCycle_rf256); pcchCfg.nAndPagingFrmOffsetType = PCCH_Config__nAndPagingFrameOffset_PR_oneT; pcchCfg.pageFrameOffset = 0; - pcchCfg.ns = PCCH_Config__ns_one; + pcchCfg.ns = convertNsEnumToValue(PCCH_Config__ns_one); pcchCfg.firstPDCCHMontioringType = PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_sCS30KHZoneT_SCS15KHZhalfT; memset(pcchCfg.firstPDCCHMontioringInfo, 0, sizeof(uint16_t)); pcchCfg.firstPDCCHMontioringInfo[0] = 44; @@ -1019,7 +1040,6 @@ uint8_t readCfg() * RFAILED - failure * * ****************************************************************/ -#ifdef O1_ENABLE uint8_t cpyRrmPolicyInDuCfgParams(RrmPolicyList rrmPolicy[], uint8_t policyNum, CopyOfRecvdSliceCfg *tempSliceCfg) { uint8_t policyIdx = 0, memberListIdx = 0, count = 0; @@ -1079,7 +1099,6 @@ uint8_t cpyRrmPolicyInDuCfgParams(RrmPolicyList rrmPolicy[], uint8_t policyNum, } return ROK; } -#endif /******************************************************************* * * @brief Reads config and posts message to du_app on completion diff --git a/src/du_app/du_cfg.h b/src/du_app/du_cfg.h index 709deeb0d..d48d77476 100644 --- a/src/du_app/du_cfg.h +++ b/src/du_app/du_cfg.h @@ -1109,7 +1109,7 @@ typedef struct bcchCfg typedef struct pcchCfg { - uint8_t dfltPagingCycle; /* Default paging cycle */ + uint16_t dfltPagingCycle; /* Default paging cycle */ uint8_t nAndPagingFrmOffsetType; /*Number of PagingFrames in PagingCycle defined in terms of T.*/ uint8_t pageFrameOffset; /* Paging Frame offset */ uint8_t ns; /* Number of paging occassions in paging frame */ @@ -1274,6 +1274,39 @@ typedef struct f1SetupMsg char *f1MsgRspBuf; }F1SetupMsg; + +#ifndef O1_ENABLE +//RRM POLICY STRUCT + +typedef struct rRMPolicyMemberList +{ + uint8_t mcc[3]; + uint8_t mnc[3]; + uint8_t sd[3]; + uint8_t sst; +}RRMPolicyMemberList; + +typedef enum +{ + PRB, + PRB_UL, + PRB_DL, + RRC, + DRB +}RrmResourceType; + +typedef struct rrmPolicyList +{ + char id[1]; + RrmResourceType resourceType; + uint8_t rRMMemberNum; + RRMPolicyMemberList rRMPolicyMemberList[2]; + uint8_t rRMPolicyMaxRatio; + uint8_t rRMPolicyMinRatio; + uint8_t rRMPolicyDedicatedRatio; +}RrmPolicyList; +#endif + DuCfgParams duCfgParam; /*function declarations */ @@ -1282,10 +1315,7 @@ uint8_t readClCfg(); uint8_t readCfg(); uint8_t duReadCfg(); uint16_t calcSliv(uint8_t startSymbol, uint8_t lengthSymbol); - -#ifdef O1_ENABLE uint8_t cpyRrmPolicyInDuCfgParams(RrmPolicyList rrmPolicy[], uint8_t policyNum, CopyOfRecvdSliceCfg *tempSliceCfg); -#endif #endif /* __DU_CONFIG_H__ */ diff --git a/src/du_app/du_e2ap_msg_hdl.c b/src/du_app/du_e2ap_msg_hdl.c index 6c18c3973..c45ed3be8 100644 --- a/src/du_app/du_e2ap_msg_hdl.c +++ b/src/du_app/du_e2ap_msg_hdl.c @@ -57,7 +57,7 @@ uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId) { uint8_t unused = 0; uint8_t byteSize = 4; - uint8_t val = 1; + uint8_t gnbId = 1; uint8_t ret = ROK; /* Allocate Buffer size */ @@ -72,22 +72,22 @@ uint8_t BuildGlobalgNBId(GlobalE2node_gNB_ID_t *gNbId) else { buildPlmnId(duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrCgi.plmn, \ - gNbId->global_gNB_ID.plmn_id.buf); + gNbId->global_gNB_ID.plmn_id.buf); /* fill gND Id */ gNbId->global_gNB_ID.gnb_id.present = GNB_ID_Choice_PR_gnb_ID; /* Allocate Buffer size */ gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size = byteSize * sizeof(uint8_t); gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf = NULLP; DU_ALLOC(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf, \ - gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size); + gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.size); if(gNbId->global_gNB_ID.gnb_id.choice.gnb_ID.buf == NULLP) { - DU_LOG("\nERROR --> E2AP: Memory allocation failed for gnb buffer"); - ret = RFAILED; + DU_LOG("\nERROR --> E2AP: Memory allocation failed for gnb buffer"); + ret = RFAILED; } else { - fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, val); + fillBitString(&gNbId->global_gNB_ID.gnb_id.choice.gnb_ID, unused, byteSize, gnbId); } } return ret; diff --git a/src/du_app/du_f1ap_conversions.c b/src/du_app/du_f1ap_conversions.c index cb2b9df8c..50fff853d 100644 --- a/src/du_app/du_f1ap_conversions.c +++ b/src/du_app/du_f1ap_conversions.c @@ -20,20 +20,8 @@ * its corresponding values used in DU and vice-versa */ #include "common_def.h" -#include "SN-FieldLengthUM.h" -#include "SN-FieldLengthAM.h" -#include "T-PollRetransmit.h" -#include "PollPDU.h" -#include "PollByte.h" -#include "UL-AM-RLC.h" -#include "T-Reassembly.h" -#include "T-StatusProhibit.h" -#include "DL-AM-RLC.h" -#include "RLC-Config.h" -#include "RLC-BearerConfig.h" #include "BSR-Config.h" -#include "PUCCH-Resource.h" -#include "du_app_rlc_inf.h" +#include "du_f1ap_conversions.h" /************************************************************************ * @@ -1182,6 +1170,134 @@ long convertLcSrDelayTmrValueToEnum(uint16_t delayTimer) } } +/************************************************************************ + * + * @brief Converts actual values into enum value of Paging DRX cycle + * + * @details + * + * Function : convertPagingCycleValueToEnum + * + * Functionality: As per Spec 38.331, + * Converts Actual values into enum value of Paging DRX cycle + * + * + * @params[in] Actual value of PagingDRX + * @return Enum value of DRX cycle + * + * **********************************************************************/ +e_PagingDRX convertPagingCycleValueToEnum(uint16_t pagingDrxCycle) +{ + switch(pagingDrxCycle) + { + case 32: + return PagingDRX_v32; + case 64: + return PagingDRX_v64; + case 128: + return PagingDRX_v128; + case 256: + return PagingDRX_v256; + default: + return PagingDRX_v32; + } +} + +/************************************************************************ + * + * @brief Converts enum values into actual value of Paging DRX cycle + * + * @details + * + * Function : convertPagingCycleEnumToValue + * + * Functionality: As per Spec 38.331, + * Converts enum values into actual value of Paging DRX cycle + * + * + * @params[in] Enum value of PagingDRX + * @return Actual value of DRX cycle + * Note: Returning the MAX value in case of Incorrect Enum Value as DRX + * cycle is MIN of Various DRX cycle + * + * **********************************************************************/ +uint16_t convertPagingCycleEnumToValue(e_PagingDRX pagingDrx) +{ + switch(pagingDrx) + { + case PagingDRX_v32: + return 32; + case PagingDRX_v64: + return 64; + case PagingDRX_v128: + return 128; + case PagingDRX_v256: + return 256; + default: + return 256; + } +} +/************************************************************************ + * + * @brief Converts enum values into actual value of Num of Paging Ocassions + * + * @details + * + * Function : convertPagingOccEnumToValue + * + * Functionality: As per Spec 38.331, + * Converts enum values into actual value of Num of Paging Ocassion + * + * + * @params[in] Enum value of Ns + * @return Actual value of Num of Paging Ocassions + * + * **********************************************************************/ +uint8_t convertNsEnumToValue(e_PCCH_Config__ns Ns) +{ + switch(Ns) + { + case PCCH_Config__ns_four: + return 4; + case PCCH_Config__ns_two: + return 2; + case PCCH_Config__ns_one: + return 1; + default: + return 0; + } +} + +/************************************************************************ + * + * @brief Converts actual values into enum value of Num of Paging Ocassions + * + * @details + * + * Function : convertNsValueToEnum + * + * Functionality: As per Spec 38.331, + * Converts actual values into enum value of Num of Paging Ocassions + * + * + * @params[in] Actual value of Num of Paging Ocassions + * @return Enum value of Ns + * + * **********************************************************************/ +e_PCCH_Config__ns convertNsValueToEnum(uint8_t numPO) +{ + switch(numPO) + { + case 1: + return PCCH_Config__ns_one; + case 2: + return PCCH_Config__ns_two; + case 4: + return PCCH_Config__ns_four; + default: + return PCCH_Config__ns_one; + } +} /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_f1ap_conversions.h b/src/du_app/du_f1ap_conversions.h index f42fe9ea5..508ffd5f4 100644 --- a/src/du_app/du_f1ap_conversions.h +++ b/src/du_app/du_f1ap_conversions.h @@ -18,6 +18,20 @@ /* This file contains definitions of F1AP conversion functions */ +#include "RLC-BearerConfig.h" +#include "RLC-Config.h" +#include "SN-FieldLengthAM.h" +#include "SN-FieldLengthUM.h" +#include "T-PollRetransmit.h" +#include "PollPDU.h" +#include "PollByte.h" +#include "T-Reassembly.h" +#include "T-StatusProhibit.h" +#include "PUCCH-Resource.h" +#include "PagingDRX.h" +#include "PCCH-Config.h" +#include "du_app_rlc_inf.h" + RLC_BearerConfig__servedRadioBearer_PR covertRbTypeFromIntEnumToRrcEnum(RlcRbType rbType); RLC_Config_PR covertRlcModeFromIntEnumToRrcEnum(RlcMode mode); SN_FieldLengthAM_t covertAmSnLenFromIntEnumToRrcEnum(SnLenAm snLen); @@ -26,7 +40,7 @@ SN_FieldLengthUM_t covertUmSnLenFromIntEnumToRrcEnum(SnLenUm snLen); SnLenUm covertUmSnLenFromRrcEnumToIntEnum(SN_FieldLengthUM_t snLen); T_PollRetransmit_t covertPollRetxTmrValueToEnum(uint16_t pollRetxTmr); uint16_t covertPollRetxTmrEnumToValue(uint8_t pollRetxTmrCfg); -PollPDU_t covertPollPduValueToEnum(int16_t pollPdu); +PollPDU_t covertPollPduValueToEnum(int32_t pollPdu); int32_t covertPollPduEnumToValue(uint8_t pollPduCfg); PollByte_t covertPollByteValueToEnum(int32_t pollByte); int32_t covertPollByteEnumToValue(uint16_t pollBytesCfg); @@ -41,6 +55,11 @@ long convertBsrPeriodicTmrValueToEnum(int16_t periodicTmr); long convertBsrRetxTmrValueToEnum(uint16_t retxTmr); long convertLcSrDelayTmrValueToEnum(uint16_t delayTimer); +e_PagingDRX convertPagingCycleValueToEnum(uint16_t pagingDrxCycle); +uint16_t convertPagingCycleEnumToValue(e_PagingDRX pagingDrx); +uint8_t convertNsEnumToValue(e_PCCH_Config__ns Ns); +e_PCCH_Config__ns convertNsValueToEnum(uint8_t numPO); + /********************************************************************** End of file **********************************************************************/ diff --git a/src/du_app/du_f1ap_msg_hdl.c b/src/du_app/du_f1ap_msg_hdl.c index 079b234cc..5c907be92 100644 --- a/src/du_app/du_f1ap_msg_hdl.c +++ b/src/du_app/du_f1ap_msg_hdl.c @@ -113,6 +113,8 @@ #include "du_sys_info_hdl.h" #include "du_e2ap_msg_hdl.h" #include "du_f1ap_conversions.h" +#include "CNUEPagingIdentity.h" +#include "PCCH-Config.h" #ifdef O1_ENABLE #include "CmInterface.h" @@ -5338,7 +5340,7 @@ uint8_t BuildBWPUlDedPucchCfg(PucchCfg *pucchCfgDb, PUCCH_Config_t *pucchCfg) /* Multi CSI */ if(multiCsiDb && (multiCsiDb->multiCsiResrcListCount != 0)) { - pucchCfg->multi_CSI_PUCCH_ResourceList == NULLP; + pucchCfg->multi_CSI_PUCCH_ResourceList = NULLP; DU_ALLOC(pucchCfg->multi_CSI_PUCCH_ResourceList, sizeof(struct PUCCH_Config__multi_CSI_PUCCH_ResourceList)); if(pucchCfg->multi_CSI_PUCCH_ResourceList == NULLP) { @@ -15308,6 +15310,236 @@ uint8_t procF1UeContextReleaseCommand(F1AP_PDU_t *f1apMsg) freeAperDecodeUeContextReleaseCommand(f1apMsg); return ret; } + +/************************************************************** + * + * @brief free the memory allocated by aper decoder for paging + * + * @details + * + * Function : freeAperDecodePagingMsg + * + * Functionality: + * - free the memory allocated by aper decoder for + * the paging f1ap msg + * + * @params[in] Paging_t *paging + * @return ROK - success + * RFAILED - failure + * + ****************************************************************/ +void freeAperDecodePagingMsg(Paging_t *paging) +{ + uint8_t ieIdx, cellIdx; + PagingCell_ItemIEs_t *pagingCellItemIes; + PagingCell_Item_t *pagingCellItem; + PagingCell_list_t *pagingCelllist; + + if(paging) + { + if(paging->protocolIEs.list.array) + { + for(ieIdx=0 ; ieIdxprotocolIEs.list.count; ieIdx++) + { + if(paging->protocolIEs.list.array[ieIdx]) + { + switch(paging->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_ID_id_UEIdentityIndexValue: + { + free(paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10.buf); + 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) + { + free(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity->choice.fiveG_S_TMSI.buf); + } + free(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.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; + free(pagingCellItem->nRCGI.pLMN_Identity.buf); + free(pagingCellItem->nRCGI.nRCellIdentity.buf); + } + free(pagingCelllist->list.array[cellIdx]); + } + } + free(pagingCelllist->list.array); + } + break; + } + } + free(paging->protocolIEs.list.array[ieIdx]); + } + } + free(paging->protocolIEs.list.array); + + } + } +} + +/************************************************************** + * + * @brief processing the paging f1ap msg received from CU + * + * @details + * + * Function : procPagingMsg + * + * Functionality: + * - processing the paging f1ap msg received from CU + * + * @params[in] F1AP_PDU_t *f1apMsg + * @return ROK - success + * RFAILED - failure + * + * + ****************************************************************/ +uint8_t procPagingMsg(F1AP_PDU_t *f1apMsg) +{ + uint8_t ieIdx = 0, cellListIdx = 0; + uint16_t cellId = 0, cellIdx = 0; + Paging_t *paging = NULLP; + PagingCell_list_t *pagingCelllist = NULLP; + PagingCell_ItemIEs_t *pagingCellItemIes = NULLP; + PagingCell_Item_t *pagingCellItem = NULLP; + DuPagingMsg *tmpPagingParam = NULLP; + + DU_LOG("\nINFO --> DU APP : Processing the Paging Message"); + paging = &f1apMsg->choice.initiatingMessage->value.choice.Paging; + if(paging) + { + if(paging->protocolIEs.list.array) + { + DU_ALLOC(tmpPagingParam, sizeof(DuPagingMsg)); + if(tmpPagingParam == NULLP) + { + DU_LOG("\nERROR --> DU APP : Memory Allocation Failure in procPagingMsg"); + freeAperDecodePagingMsg(paging); + return RFAILED; + } + for(ieIdx=0 ; ieIdxprotocolIEs.list.count; ieIdx++) + { + if(paging->protocolIEs.list.array[ieIdx]) + { + switch(paging->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_ID_id_UEIdentityIndexValue: + { + bitStringToInt(&paging->protocolIEs.list.array[ieIdx]->value.choice.UEIdentityIndexValue.choice.indexLength10,\ + &tmpPagingParam->ueId); + break; + } + + case ProtocolIE_ID_id_PagingIdentity: + { + switch(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.present) + { + case PagingIdentity_PR_cNUEPagingIdentity: + { + if(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.cNUEPagingIdentity) + { + bitStringToInt(&paging->protocolIEs.list.array[ieIdx]->value.choice.PagingIdentity.choice.\ + cNUEPagingIdentity->choice.fiveG_S_TMSI, &tmpPagingParam->sTmsi); + + } + break; + } + case PagingIdentity_PR_rANUEPagingIdentity: + { + /*TODO: This Identifier is specific to RAN Initiated Paging – Connected Mode Paging*/ + break; + } + default: + { + DU_LOG("ERROR --> DU APP: Invalid UE Paging Identity, Skipping this Paging Message:"); + continue; + } + } + } + + case ProtocolIE_ID_id_PagingDRX: + { + tmpPagingParam->pagingDrxPres = TRUE; + tmpPagingParam->pagingDrx = convertPagingCycleEnumToValue(paging->protocolIEs.list.array[ieIdx]->value.choice.PagingDRX); + break; + } + + case ProtocolIE_ID_id_PagingPriority: + { + tmpPagingParam->pagPriority = paging->protocolIEs.list.array[ieIdx]->value.choice.PagingPriority; + break; + } + + case ProtocolIE_ID_id_PagingCell_List: + { + pagingCelllist = &paging->protocolIEs.list.array[ieIdx]->value.choice.PagingCell_list; + if(pagingCelllist->list.array) + { + for(cellListIdx = 0; cellListIdx < pagingCelllist->list.count; cellListIdx++) + { + if(pagingCelllist->list.array[cellListIdx]) + { + pagingCellItemIes = (PagingCell_ItemIEs_t *)pagingCelllist->list.array[cellListIdx]; + pagingCellItem = &pagingCellItemIes->value.choice.PagingCell_Item; + bitStringToInt(&pagingCellItem->nRCGI.nRCellIdentity, &cellId); + GET_CELL_IDX(cellId, cellIdx); + if(duCb.actvCellLst[cellIdx]) + { + /* fill Ue Paging information*/ + if(FillPagingInfoInCellCb(duCb.actvCellLst[cellIdx], tmpPagingParam)!= ROK) + { + DU_LOG("\nERROR --> DU APP : CellCb:%d not present to fill UE Paging Information",cellIdx); + continue; + } + } + else + { + DU_LOG("\nERROR --> F1AP : CellId:%d Not in Activelist",cellId); + continue; + } + } + } + } + break; + } + default: + { + DU_LOG("\nERROR --> F1AP : Incorrect Paging IE option"); + break; + } + } + } + } + } + } + DU_FREE(tmpPagingParam, sizeof(DuPagingMsg)); + freeAperDecodePagingMsg(paging); + + return ROK; +} + /************************************************************** * * @brief Handles received F1AP message and sends back response @@ -15436,6 +15668,11 @@ void F1APMsgHdlr(Buffer *mBuf) procF1UeContextReleaseCommand(f1apMsg); break; } + case InitiatingMessage__value_PR_Paging: + { + procPagingMsg(f1apMsg); + break; + } default: { DU_LOG("\nERROR --> F1AP : Invalid type of F1AP_PDU_PR_initiatingMessage [%d]", diff --git a/src/du_app/du_mgr.h b/src/du_app/du_mgr.h index 7dad91b15..8678e1099 100644 --- a/src/du_app/du_mgr.h +++ b/src/du_app/du_mgr.h @@ -178,6 +178,24 @@ typedef struct slotInfo uint16_t slot; }SlotInfo; +typedef struct pagingMsg +{ + /*Note: Paging UEID is extracted from 5gSTMSI as per Spec 38.304, Sec 7.1. + *This is not same as DU-UE_F1AP_ID or CU_UE_F1AP_ID*/ + uint16_t ueId; /* UE Identifier from CU*/ + + /*TODO: When RAN Inititated Paging will be supported then I-RNTI will be + * added as a choice for UE Identity along with S-TMSI*/ + uint64_t sTmsi; /* UE Paging Identity: S-TMSI */ + bool pagingDrxPres; /* flag to indicate paging drx present or not */ + uint16_t pagingDrx; /* UE specific paging drx */ + uint8_t pagPriority; /* Paging priority */ + uint16_t pagingFrame; /* paging frame */ + uint16_t pagingFrameOffset; /* paging offset */ + uint8_t i_s; /* Index points to PO from the sub-frame pattern */ + uint16_t T; /* T is DRX cycle of the UE */ +}DuPagingMsg; + typedef struct duCellCb { uint16_t cellId; /* Internal cell Id */ @@ -188,6 +206,7 @@ typedef struct duCellCb uint32_t numActvUes; /* Total Active UEs */ DuUeCb ueCb[MAX_NUM_UE]; /* Stores UE context */ SlotInfo currSlotInfo; + DuPagingMsg tmpPagingInfoOfUe; /* UE paging information */ }DuCellCb; typedef struct duLSapCb diff --git a/src/du_app/du_sys_info_hdl.c b/src/du_app/du_sys_info_hdl.c index 3b3194782..9aeced60c 100644 --- a/src/du_app/du_sys_info_hdl.c +++ b/src/du_app/du_sys_info_hdl.c @@ -55,6 +55,7 @@ #include "SIB1.h" #include "odu_common_codec.h" #include "du_sys_info_hdl.h" +#include "du_f1ap_conversions.h" void FreeSib1Msg(SIB1_t *sib1Msg); uint8_t FreqInfoUlret = RFAILED; @@ -1309,8 +1310,8 @@ uint8_t fillFirstPdcchMonitoringOcc(struct PCCH_Config__firstPDCCH_MonitoringOcc firstPO->present = srcPcchCfg->firstPDCCHMontioringType; - GET_NUM_PAGING_OCC(srcPcchCfg->ns, numPO); - if(srcPcchCfg->ns == 0) + numPO = srcPcchCfg->ns; + if(numPO == 0) { DU_LOG("\nINFO --> DU APP : Paging Occasions is ZERO, no need to fill further"); return ROK; @@ -1441,7 +1442,7 @@ uint8_t BuildPcchConfig(PCCH_Config_t *pcchCfg) duPcchCfg = duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg; - pcchCfg->defaultPagingCycle = duPcchCfg.dfltPagingCycle; + pcchCfg->defaultPagingCycle = convertPagingCycleValueToEnum(duPcchCfg.dfltPagingCycle); pcchCfg->nAndPagingFrameOffset.present = duPcchCfg.nAndPagingFrmOffsetType; switch(pcchCfg->nAndPagingFrameOffset.present) { @@ -1507,7 +1508,7 @@ uint8_t BuildPcchConfig(PCCH_Config_t *pcchCfg) return RFAILED; } } - pcchCfg->ns = duPcchCfg.ns; + pcchCfg->ns = convertNsValueToEnum(duPcchCfg.ns); DU_ALLOC(pcchCfg->firstPDCCH_MonitoringOccasionOfPO, \ sizeof(struct PCCH_Config__firstPDCCH_MonitoringOccasionOfPO)); diff --git a/src/ric_stub/ric_e2ap_msg_hdl.c b/src/ric_stub/ric_e2ap_msg_hdl.c index 4bed18a7a..b810dda47 100644 --- a/src/ric_stub/ric_e2ap_msg_hdl.c +++ b/src/ric_stub/ric_e2ap_msg_hdl.c @@ -104,7 +104,7 @@ uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId) { uint8_t unused = 4; uint8_t byteSize = 3; - uint8_t val = 16; + uint8_t ricVal= 1; if(ricId != NULLP) { ricId->pLMN_Identity.size = byteSize * sizeof(uint8_t); @@ -113,7 +113,7 @@ uint8_t BuildGlobalRicId(GlobalRIC_ID_t *ricId) /* fill ric Id */ ricId->ric_ID.size = byteSize * sizeof(uint8_t); RIC_ALLOC(ricId->ric_ID.buf, ricId->ric_ID.size); - fillBitString(&ricId->ric_ID, unused, byteSize, val); + fillBitString(&ricId->ric_ID, unused, byteSize, ricVal); } return ROK; } diff --git a/src/ric_stub/ric_stub.c b/src/ric_stub/ric_stub.c index e27f2acb4..200e27d62 100644 --- a/src/ric_stub/ric_stub.c +++ b/src/ric_stub/ric_stub.c @@ -82,6 +82,8 @@ uint8_t tst() /* Start RIC-SCTP to listen on incoming connection */ sctpCfgReq(); + /*Sleep is introduced for GDB to increase the waiting time for RIC Configuration from DUAPP*/ + sleep(1); sctpStartReq(); return ROK; -- 2.16.6