From 49dc0e36836dc940ec40dea3a475ff067177819a Mon Sep 17 00:00:00 2001 From: barveankit Date: Thu, 20 Jan 2022 17:02:27 +0530 Subject: [PATCH] [Epic-ID: ODUHIGH-406][Task-ID: ODUHIGH-415]: Paging Configuration Signed-off-by: barveankit Change-Id: I5b8e25415abfb7fcafbcd6c6512d566f941847c9 Signed-off-by: barveankit --- src/5gnrmac/mac_cfg_hdl.c | 8 ++ src/5gnrsch/sch.c | 115 +++++++++++++++++++++ src/5gnrsch/sch.h | 29 ++++++ src/5gnrsch/sch_common.c | 36 ++++++- src/5gnrsch/sch_utils.c | 1 - src/5gnrsch/sch_utils.h | 1 + src/cm/common_def.c | 28 ++++++ src/cm/common_def.h | 18 ++++ src/cm/du_app_mac_inf.h | 8 ++ src/cm/mac_sch_interface.h | 22 +++- src/du_app/du_cfg.c | 25 ++++- src/du_app/du_cfg.h | 10 +- src/du_app/du_sys_info_hdl.c | 232 +++++++++++++++++++++++++++++++++++++------ 13 files changed, 488 insertions(+), 45 deletions(-) diff --git a/src/5gnrmac/mac_cfg_hdl.c b/src/5gnrmac/mac_cfg_hdl.c index 6f193c0bb..6205e5ba3 100644 --- a/src/5gnrmac/mac_cfg_hdl.c +++ b/src/5gnrmac/mac_cfg_hdl.c @@ -263,6 +263,7 @@ uint8_t MacSchCellCfgReq(Pst *pst, MacCellCfg *macCellCfg) { schCellCfg.ssbSchCfg.nSSBMask[ssbMaskIdx] = macCellCfg->ssbCfg.ssbMask[ssbMaskIdx]; } + schCellCfg.ssbSchCfg.totNumSsb = countSetBits(schCellCfg.ssbSchCfg.nSSBMask[0]); /* fill SIB1 scheduler parameters */ schCellCfg.sib1SchCfg.sib1PduLen = macCellCfg->sib1Cfg.sib1PduLen; @@ -270,6 +271,13 @@ uint8_t MacSchCellCfgReq(Pst *pst, MacCellCfg *macCellCfg) schCellCfg.sib1SchCfg.coresetZeroIndex = macCellCfg->sib1Cfg.coresetZeroIndex; schCellCfg.sib1SchCfg.searchSpaceZeroIndex = macCellCfg->sib1Cfg.searchSpaceZeroIndex; schCellCfg.sib1SchCfg.sib1Mcs = macCellCfg->sib1Cfg.sib1Mcs; + schCellCfg.sib1SchCfg.pageCfg.numPO = macCellCfg->sib1Cfg.pagingCfg.numPO; + schCellCfg.sib1SchCfg.pageCfg.poPresent = macCellCfg->sib1Cfg.pagingCfg.poPresent; + + if(schCellCfg.sib1SchCfg.pageCfg.poPresent) + { + memcpy(schCellCfg.sib1SchCfg.pageCfg.pagingOcc, macCellCfg->sib1Cfg.pagingCfg.pagingOcc, MAX_PO_PER_PF); + } /* fill RACH config params */ schCellCfg.schRachCfg.prachCfgIdx = macCellCfg->prachCfg.prachCfgIdx; diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index fc845eb1d..a0ff77603 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -887,7 +887,10 @@ uint8_t SchHdlCellCfgReq(Pst *pst, SchCellCfg *schCellCfg) fillSchSib1Cfg(schCellCfg->numerology, schCellCfg->bandwidth, cellCb->numSlots, &(schCellCfg->sib1SchCfg), schCellCfg->phyCellId, schCellCfg->ssbSchCfg.ssbOffsetPointA); + + memcpy(&cellCb->cellCfg, schCellCfg, sizeof(SchCellCfg)); + schProcPagingCfg(cellCb); /* Fill coreset frequencyDomainResource bitmap */ coreset0Idx = cellCb->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.coresetId; @@ -1972,6 +1975,118 @@ uint8_t MacSchSliceReCfgReq(Pst *pst, SchSliceCfgReq *schSliceReCfgReq) return ROK; } +/**************************************************************************** + * + * @brief Stores the Paging Configuration from DU APP in CellCb + * + * @details + * + * Function : schProcPagingParam + * + * Functionality: + * Process the Paging Configuration when FirstPDCCHMonitoring for + * Paging Ocassion is not present. + * + * As per 38.304 Sec 7.1, + * "When firstPDCCH-MonitoringOccasionOfPO is present, the + * starting PDCCH monitoring occasion number of (i_s + 1)th PO is the + * (i_s + 1)th value of the firstPDCCHMonitoringOccasionOfPO + * parameter; otherwise, it is equal to i_s * S." + * "S = number of actual transmitted SSBs determined according + * to ssb-PositionsInBurst in SIB1" + * + * @params[in] SchCellCb *cell + * + * @return void + * + *************************************************************************/ +void schProcPagingCfg(SchCellCb *cell) +{ + PageCfg *pageCfgRcvd = NULL; + uint8_t i_sIdx = 0; + + pageCfgRcvd = &(cell->cellCfg.sib1SchCfg.pageCfg); + + if(pageCfgRcvd->poPresent == TRUE) + { + /*Fetching first Pdcch Monitoring Occasion for SFN (i_s + 1)th*/ + for(i_sIdx = 0; i_sIdx < pageCfgRcvd->numPO; i_sIdx++) + { + cell->pageCb.pagMonOcc[i_sIdx].pagingOccSlot = pageCfgRcvd->pagingOcc[i_sIdx] / MAX_SYMB_PER_SLOT ; + if ((pageCfgRcvd->pagingOcc[i_sIdx] % MAX_SYMB_PER_SLOT) != 0 ) + { + cell->pageCb.pagMonOcc[i_sIdx].pagingOccSlot++; + } + + cell->pageCb.pagMonOcc[i_sIdx].frameOffset = 0; + + } + } + else + { + schCfgPdcchMonOccOfPO(cell); + } +} + +/**************************************************************************** + * + * @brief Calculate PO if not present in Configuration + * + * @details + * + * Function : schCfgPdcchMonOccOfPO + * + * Functionality: In this function, PO are calculated i_s * S because + * FirstPDCCHMonitoring_ForPO is not present. + * + * @params[in] SchCellCb *cellCb + * + * @return void + * + *************************************************************************/ +void schCfgPdcchMonOccOfPO(SchCellCb *cell) +{ + uint8_t cnt = 0, incr = 1, i_sIdx = 0, frameOffSet = 0; + uint8_t nsValue = cell->cellCfg.sib1SchCfg.pageCfg.numPO; + uint8_t totalNumSsb = cell->cellCfg.ssbSchCfg.totNumSsb; + SlotTimingInfo tmpTimingInfo, pdcchTime; + + /*Starting with First Sfn and slot*/ + tmpTimingInfo.sfn = 0; + tmpTimingInfo.slot = 0; + + pdcchTime = tmpTimingInfo; + + while(i_sIdx < nsValue) + { + /*Increment frame Offset if PO falls on next SFN*/ + if(pdcchTime.sfn != tmpTimingInfo.sfn) + { + frameOffSet++; + } + pdcchTime = tmpTimingInfo; + schIncrSlot(&(tmpTimingInfo), incr, cell->numSlots); + + if (i_sIdx == 0) + { + cell->pageCb.pagMonOcc[i_sIdx].pagingOccSlot = pdcchTime.slot; + cell->pageCb.pagMonOcc[i_sIdx].frameOffset = frameOffSet; + i_sIdx++; + } + else + { + cnt++; + if((cnt == totalNumSsb) && (i_sIdx < MAX_PO_PER_PF)) + { + cell->pageCb.pagMonOcc[i_sIdx].pagingOccSlot = pdcchTime.slot; + cell->pageCb.pagMonOcc[i_sIdx].frameOffset = frameOffSet; + cnt = 0; + i_sIdx++; + } + } + } +} + /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch.h b/src/5gnrsch/sch.h index 0c0b7abd9..5c46b6e51 100644 --- a/src/5gnrsch/sch.h +++ b/src/5gnrsch/sch.h @@ -293,6 +293,31 @@ typedef struct schRaReq SlotTimingInfo winEndTime; }SchRaReq; +typedef struct schPageInfo +{ + uint8_t pf; /*Value of Paging Frame received from DUAPP*/ + uint8_t i_s; /*Value of Paging Occ Index received from DUAPP*/ + SlotTimingInfo TxTime; /*Start Paging window*/ + uint8_t crntSsbIdx; /*Counts the slot till totalSSB is receached*/ + uint8_t mcs; + uint8_t nPRB; + uint16_t msgLen; + uint8_t *pagePdu; +}SchPageInfo; + +typedef struct schPagingOcc +{ + uint8_t frameOffset; + uint8_t pagingOccSlot; +}SchPagingOcc; + +typedef struct schPageCb +{ + CmLListCp pageReqInfoRecord[MAX_SFN]; /*List of Page Records received which are stored per sfn*/ + SchPagingOcc pagMonOcc[MAX_PO_PER_PF]; /*Paging Occasion Slot/FrameOffset are stored*/ + SchPageInfo currPageInfo; /*Page Req which is being currently processed */ +}SchPageCb; + /** * @brief * Cell Control block per cell. @@ -317,6 +342,7 @@ typedef struct schCellCb uint32_t boIndBitMap; /*!slot += incr; + if(timingInfo->slot >= numSlotsPerRF) + { + timingInfo->sfn += timingInfo->slot/numSlotsPerRF; + timingInfo->slot %= numSlotsPerRF; + if(timingInfo->sfn > MAX_SFN) + { + timingInfo->sfn %= MAX_SFN; + } + } +} /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_utils.c b/src/5gnrsch/sch_utils.c index 90b979d87..b960586ea 100644 --- a/src/5gnrsch/sch_utils.c +++ b/src/5gnrsch/sch_utils.c @@ -1757,7 +1757,6 @@ void covertFreqDomRsrcMapToIAPIFormat(uint8_t *sourceBitMap, uint8_t *destBitMap numBitsToShift += 8; } } - /********************************************************************** End of file **********************************************************************/ diff --git a/src/5gnrsch/sch_utils.h b/src/5gnrsch/sch_utils.h index 78a0400c4..44a14727b 100644 --- a/src/5gnrsch/sch_utils.h +++ b/src/5gnrsch/sch_utils.h @@ -137,6 +137,7 @@ void deleteLcLL(CmLListCp *lcLL); /*Will be enabled for debugging*/ void printLcLL(CmLListCp *lcLL); #endif + /********************************************************************** End of file **********************************************************************/ diff --git a/src/cm/common_def.c b/src/cm/common_def.c index 897360df4..cfe9cf7ab 100644 --- a/src/cm/common_def.c +++ b/src/cm/common_def.c @@ -388,6 +388,34 @@ Region region, Pool pool, Data *ptr, Size size, uint8_t memType) else return RFAILED; } + + +/******************************************************************* +* +* @brief countSetBits in an integer +* +* @details +* +* Function : countSetBits +* +* Functionality: countSetBits in unsigned integer +* +* @params[in] uint32_t number/Bitmask +* +* @return [out] uint8_t count of Set Bits +* +* ****************************************************************/ +uint8_t countSetBits(uint32_t num) +{ + uint8_t count = 0; + + while(num) + { + count += num & 1; + num >>= 1; + } + return(count); +} /********************************************************************** End of file **********************************************************************/ diff --git a/src/cm/common_def.h b/src/cm/common_def.h index c70920486..fc51869d2 100644 --- a/src/cm/common_def.h +++ b/src/cm/common_def.h @@ -107,6 +107,9 @@ #define ODU_UE_THROUGHPUT_PRINT_TIME_INTERVAL 5 /* in milliseconds */ #define ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL 60000 /* in milliseconds */ +/*Spec 38.331 Sec 6.4: Maximum number of paging occasion per paging frame*/ +#define MAX_PO_PER_PF 4 + /* Defining macros for common utility functions */ #define ODU_GET_MSG_BUF SGetMsg #define ODU_PUT_MSG_BUF SPutMsg @@ -201,6 +204,20 @@ _isLcidValid = ((_lcId >= SRB0_LCID && _lcId <= MAX_DRB_LCID) ? 1 : 0);\ } +#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; \ +} typedef enum { UE_CFG_INACTIVE, @@ -321,6 +338,7 @@ uint8_t SGetStaticBufNewForDebug(char *file, char *func, char *line, \ Region region, Pool pool, Data **ptr, Size size, uint8_t memType); uint8_t SPutStaticBufNewForDebug(char *file, char *func, char *line, \ Region region, Pool pool, Data *ptr, Size size, uint8_t memType); +uint8_t countSetBits(uint32_t num); #endif diff --git a/src/cm/du_app_mac_inf.h b/src/cm/du_app_mac_inf.h index a0d81ec0f..985f29e9d 100644 --- a/src/cm/du_app_mac_inf.h +++ b/src/cm/du_app_mac_inf.h @@ -570,6 +570,13 @@ typedef struct prachCfg uint8_t raRspWindow; /* RA Response Window */ }PrachCfg; +typedef struct schPageCfg +{ + uint8_t numPO; /*Derived from Ns*/ + bool poPresent; /*Whether FirstPDCCH-MonitoringPO is present or not*/ + uint16_t pagingOcc[MAX_PO_PER_PF]; /*FirstPDCCH-Monitoring Paging Occasion*/ +}SchPageCfg; + typedef struct sib1CellCfg { uint8_t *sib1Pdu; @@ -578,6 +585,7 @@ typedef struct sib1CellCfg uint8_t coresetZeroIndex; /* derived from 4 LSB of pdcchSib1 present in MIB */ uint8_t searchSpaceZeroIndex; /* derived from 4 MSB of pdcchSib1 present in MIB */ uint16_t sib1Mcs; + SchPageCfg pagingCfg; } Sib1CellCfg; typedef struct bwpParams diff --git a/src/cm/mac_sch_interface.h b/src/cm/mac_sch_interface.h index 2f1e83db0..3424bfd8a 100644 --- a/src/cm/mac_sch_interface.h +++ b/src/cm/mac_sch_interface.h @@ -449,6 +449,10 @@ typedef struct SchSSBPeriod ssbPeriod; /* SSB Periodicity in msec */ uint8_t ssbSubcOffset; /* Subcarrier Offset(Kssb) */ uint32_t nSSBMask[SCH_SSB_MASK_SIZE]; /* Bitmap for actually transmitted SSB. */ + + /*Ref:Spec 38.331 "ssb-PositionsInBurst", Value 0 in Bitmap => corresponding SS/PBCH block is not transmitted + *value 1 => corresponding SS/PBCH block is transmitted*/ + uint8_t totNumSsb; /*S = Total Number of Actual SSB transmitted*/ }SchSsbCfg; typedef struct bwpCfg @@ -582,6 +586,13 @@ typedef struct pdcchCfg } PdcchCfg; /* end of SIB1 PDCCH structures */ +typedef struct pageCfg +{ + uint8_t numPO; /*Derived from Ns*/ + bool poPresent; /*FirstPDCCH-MonitoringPO is present or not*/ + uint16_t pagingOcc[MAX_PO_PER_PF]; /*FirstPDCCH-Monitoring Paging Occasion*/ +}PageCfg; + typedef struct { /* parameters recieved from DU-APP */ @@ -592,10 +603,11 @@ typedef struct uint16_t sib1Mcs; /* parameters derived in scheduler */ - uint8_t n0; - BwpCfg bwp; - PdcchCfg sib1PdcchCfg; - PdschCfg sib1PdschCfg; + uint8_t n0; + BwpCfg bwp; + PdcchCfg sib1PdcchCfg; + PdschCfg sib1PdschCfg; + PageCfg pageCfg; /*Config of Paging*/ }SchSib1Cfg; typedef struct schRachCfg @@ -760,7 +772,7 @@ typedef struct schCellCfg SchPlmnInfoList plmnInfoList; /* Consits of PlmnId and Snssai list */ #ifdef NR_TDD TDDCfg tddCfg; /* TDD Cfg */ -#endif +#endif }SchCellCfg; typedef struct schCellCfgCfm diff --git a/src/du_app/du_cfg.c b/src/du_app/du_cfg.c index 5576e9555..9b5db13b0 100644 --- a/src/du_app/du_cfg.c +++ b/src/du_app/du_cfg.c @@ -214,7 +214,6 @@ uint8_t readMacCfg() duCfgParam.macCellCfg.ssbCfg.ssbScOffset = SSB_SUBCARRIER_OFFSET; #endif duCfgParam.macCellCfg.ssbCfg.ssbMask[0] = 1; /* only one SSB is transmitted */ - duCfgParam.macCellCfg.ssbCfg.ssbMask[1] = 0; if(BuildMibPdu() != ROK) { DU_LOG("\nERROR --> Failed to build MIB PDU"); @@ -278,7 +277,20 @@ uint8_t readMacCfg() duCfgParam.macCellCfg.sib1Cfg.coresetZeroIndex = CORESET_0_INDEX; 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.poPresent = TRUE; + memcpy(duCfgParam.macCellCfg.sib1Cfg.pagingCfg.pagingOcc, + duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg.firstPDCCHMontioringInfo,MAX_PO_PER_PF); + } + else + { + duCfgParam.macCellCfg.sib1Cfg.pagingCfg.poPresent = FALSE; + } /* fill Intial DL BWP */ duCfgParam.macCellCfg.initialDlBwp.bwp.firstPrb = 0; @@ -530,8 +542,13 @@ uint8_t fillServCellCfgCommSib(SrvCellCfgCommSib *srvCellCfgComm) /* Configuring PCCH Config for SIB1 */ pcchCfg.dfltPagingCycle = PagingCycle_rf256; - pcchCfg.nAndPagingFrmOffPresent = PCCH_Config__nAndPagingFrameOffset_PR_oneT; - pcchCfg.numPagingOcc = PCCH_Config__ns_four; + pcchCfg.nAndPagingFrmOffsetType = PCCH_Config__nAndPagingFrameOffset_PR_oneT; + pcchCfg.pageFrameOffset = 0; + pcchCfg.ns = PCCH_Config__ns_one; + pcchCfg.firstPDCCHMontioringType = PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_sCS30KHZoneT_SCS15KHZhalfT; + memset(pcchCfg.firstPDCCHMontioringInfo, 0, sizeof(uint16_t)); + pcchCfg.firstPDCCHMontioringInfo[0] = 44; + srvCellCfgComm->dlCfg.pcchCfg = pcchCfg; diff --git a/src/du_app/du_cfg.h b/src/du_app/du_cfg.h index 80cd078b8..5fbbd325a 100644 --- a/src/du_app/du_cfg.h +++ b/src/du_app/du_cfg.h @@ -1107,10 +1107,12 @@ typedef struct bcchCfg typedef struct pcchCfg { - long dfltPagingCycle; /* Default paging cycle */ - long nAndPagingFrmOffPresent; - long nAndPagingFrmOff; /* n and Paging Frame offset */ - long numPagingOcc; /* Number of paging occassions in paging frame */ + uint8_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 */ + uint8_t firstPDCCHMontioringType; /* First PDCCH Monitoring Paging Occasion Presence Type*/ + uint16_t firstPDCCHMontioringInfo[MAX_PO_PER_PF];/*Indicates the first PDCCH monitoring occasion of each PO of the PF*/ }PcchCfg; typedef struct scsSpecCarrier diff --git a/src/du_app/du_sys_info_hdl.c b/src/du_app/du_sys_info_hdl.c index ecf04e73f..edc240de9 100644 --- a/src/du_app/du_sys_info_hdl.c +++ b/src/du_app/du_sys_info_hdl.c @@ -1286,6 +1286,139 @@ uint8_t BuildBcchConfig(BCCH_Config_t *bcchCfg) return ROK; }/* BuildBcchConfig */ +/******************************************************************* + * + * @brief fills First PDCCH monitoring Paging occasions + * + * @details + * + * Function : fillFirstPdcchMonitoringOcc + * + * Functionality: + * Fills PDCCH Monitoring PO in PCCH configuration + * + * @params[in] + * @return ROK - success + * RFAILED - failure + * + * ****************************************************************/ +uint8_t fillFirstPdcchMonitoringOcc(struct PCCH_Config__firstPDCCH_MonitoringOccasionOfPO *firstPO,\ + PcchCfg *srcPcchCfg) +{ + uint8_t numPO = 0, poIdx = 0; + + firstPO->present = srcPcchCfg->firstPDCCHMontioringType; + + GET_NUM_PAGING_OCC(srcPcchCfg->ns, numPO); + if(srcPcchCfg->ns == 0) + { + DU_LOG("\nINFO --> DU APP : Paging Occasions is ZERO, no need to fill further"); + return ROK; + } + + /*Note: Valid values for each number of PO is from Spec 36.331: PCCH-COnfig*/ + switch(firstPO->present) + { + case PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_NOTHING: + { + break; + } + case PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_sCS15KHZoneT: + { + DU_ALLOC(firstPO->choice.sCS15KHZoneT, \ + sizeof(struct PCCH_Config__firstPDCCH_MonitoringOccasionOfPO__sCS15KHZoneT)); + + if(firstPO->choice.sCS15KHZoneT == NULLP) + { + DU_LOG("\nERROR --> DU APP : FirstPdcchMonitoringPO Memory allocation failure"); + return RFAILED; + } + firstPO->choice.sCS15KHZoneT->list.count = numPO; + firstPO->choice.sCS15KHZoneT->list.size = numPO * sizeof(long *); + + DU_ALLOC(firstPO->choice.sCS15KHZoneT->list.array, firstPO->choice.sCS15KHZoneT->list.size); + if(!firstPO->choice.sCS15KHZoneT->list.array) + { + DU_LOG("\nERROR --> DU APP : FirstPdcchMonitoringPO Memory allocation failure"); + return RFAILED; + } + + for(poIdx = 0; poIdx < numPO; poIdx++) + { + /* Spec 36.331: PCCH-Config: firstPDCCH-MonitoringOccasionOfPO [MAX of sCS15KHZoneT] + * Since FirstPDCCHMonitoring_PO is not valid thus no need to continue further*/ + if(srcPcchCfg->firstPDCCHMontioringInfo[poIdx] > 139) + { + DU_LOG("\nERROR --> DU APP : Invalid Paging Ocassion value for 15kHz"); + return RFAILED; + } + DU_ALLOC(firstPO->choice.sCS15KHZoneT->list.array[poIdx], sizeof(long)); + if(!firstPO->choice.sCS15KHZoneT->list.array[poIdx]) + { + DU_LOG("\nERROR --> DU APP : FirstPdcchMonitoringPO Memory allocation failure"); + return RFAILED; + } + } + + poIdx = 0; + *firstPO->choice.sCS15KHZoneT->list.array[poIdx] = srcPcchCfg->firstPDCCHMontioringInfo[poIdx]; + + break; + } + case PCCH_Config__firstPDCCH_MonitoringOccasionOfPO_PR_sCS30KHZoneT_SCS15KHZhalfT: + { + DU_ALLOC(firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT, \ + sizeof(struct PCCH_Config__firstPDCCH_MonitoringOccasionOfPO__sCS30KHZoneT_SCS15KHZhalfT)); + + if(firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT == NULLP) + { + DU_LOG("\nERROR --> DU APP : FirstPdcchMonitoringPO Memory allocation failure"); + return RFAILED; + } + firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.count = numPO; + firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.size = numPO * sizeof(long *); + + DU_ALLOC(firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.array, \ + firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.size); + + if(!firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.array) + { + DU_LOG("\nERROR --> DU APP : FirstPdcchMonitoringPO Memory allocation failure"); + return RFAILED; + } + + for(poIdx = 0; poIdx < numPO; poIdx++) + { + /* Spec 36.331: PCCH-Config:firstPDCCH-MonitoringOccasionOfPO [MAX of sCS30KHZoneT-SCS15KHZhalfT] + * Since FirstPDCCHMonitoring_PO is not valid thus no need to continue further*/ + if(srcPcchCfg->firstPDCCHMontioringInfo[poIdx] > 279) + { + DU_LOG("\nERROR --> DU APP : Invalid Paging Ocassion value for 30kHz or 15kHz HAlFT"); + return RFAILED; + } + DU_ALLOC(firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.array[poIdx], sizeof(long)); + if(!firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.array[poIdx]) + { + DU_LOG("\nERROR --> DU APP : FirstPdcchMonitoringPO Memory allocation failure"); + return RFAILED; + } + } + + poIdx = 0; + *firstPO->choice.sCS30KHZoneT_SCS15KHZhalfT->list.array[poIdx] = srcPcchCfg->firstPDCCHMontioringInfo[poIdx]; + break; + } + //TODO for other cases + default: + { + DU_LOG("\nERROR --> DU APP : Invalid firstPDCCH-MonitoringOccasionOfPO"); + return RFAILED; + + break; + } + } + return ROK; +} /******************************************************************* * * @brief Builds PCCH configuration @@ -1309,47 +1442,86 @@ uint8_t BuildPcchConfig(PCCH_Config_t *pcchCfg) duPcchCfg = duCfgParam.sib1Params.srvCellCfgCommSib.dlCfg.pcchCfg; pcchCfg->defaultPagingCycle = duPcchCfg.dfltPagingCycle; - pcchCfg->nAndPagingFrameOffset.present = duPcchCfg.nAndPagingFrmOffPresent; + pcchCfg->nAndPagingFrameOffset.present = duPcchCfg.nAndPagingFrmOffsetType; switch(pcchCfg->nAndPagingFrameOffset.present) { + /**Note: PagingFrame Offset Value differs for each Paging Duration + *(oneT, halfT,...). The Range of Offset given in Spec 38.331,Pcch-Config*/ case PCCH_Config__nAndPagingFrameOffset_PR_NOTHING: - { - //TODO - break; - } + { + //TODO + break; + } case PCCH_Config__nAndPagingFrameOffset_PR_oneT: - { - //TODO - break; - } + { + pcchCfg->nAndPagingFrameOffset.choice.oneT = NULLD; + break; + } case PCCH_Config__nAndPagingFrameOffset_PR_halfT: - { - //TODO - break; - } + { + /*Spec 38.331: PCCH_Config: nAndPagingFrameOffset [MAX value of halfT] */ + if(duPcchCfg.pageFrameOffset > 1) + { + DU_LOG("\nERROR --> DU APP : Invalid PagingFrameOffset for HALF_T"); + return RFAILED; + } + pcchCfg->nAndPagingFrameOffset.choice.halfT = duPcchCfg.pageFrameOffset; + break; + } case PCCH_Config__nAndPagingFrameOffset_PR_quarterT: - { - //TODO - break; - } + { + /*Spec 38.331: PCCH_Config: nAndPagingFrameOffset [MAX value of quarterT] */ + if(duPcchCfg.pageFrameOffset > 3) + { + DU_LOG("\nERROR --> DU APP : Invalid PagingFrameOffset for QUARTER_T"); + return RFAILED; + } + pcchCfg->nAndPagingFrameOffset.choice.quarterT = duPcchCfg.pageFrameOffset; + break; + } case PCCH_Config__nAndPagingFrameOffset_PR_oneEighthT: - { - //TODO - break; - } + { + /*Spec 38.331: PCCH_Config: nAndPagingFrameOffset [MAX value of oneEighthT] */ + if(duPcchCfg.pageFrameOffset > 7) + { + DU_LOG("\nERROR --> DU APP : Invalid PagingFrameOffset for ONE_EIGHTH_T"); + return RFAILED; + } + pcchCfg->nAndPagingFrameOffset.choice.oneEighthT = duPcchCfg.pageFrameOffset; + break; + } case PCCH_Config__nAndPagingFrameOffset_PR_oneSixteenthT: - { - //TODO - break; - } + { + /*Spec 38.331: PCCH_Config: nAndPagingFrameOffset [MAX value of oneSixteenthT] */ + if(duPcchCfg.pageFrameOffset > 15) + { + DU_LOG("\nERROR --> DU APP : Invalid PagingFrameOffset for ONE_SIXTEENTH_T"); + return RFAILED; + } + pcchCfg->nAndPagingFrameOffset.choice.oneSixteenthT = duPcchCfg.pageFrameOffset; + break; + } default: - { - DU_LOG("\nERROR --> DU APP : Invalid nAndPagingFrameOffset configuration"); - return RFAILED; - } + { + DU_LOG("\nERROR --> DU APP : Invalid nAndPagingFrameOffset configuration"); + return RFAILED; + } } - pcchCfg->ns = duPcchCfg.numPagingOcc; + pcchCfg->ns = duPcchCfg.ns; + DU_ALLOC(pcchCfg->firstPDCCH_MonitoringOccasionOfPO, \ + sizeof(struct PCCH_Config__firstPDCCH_MonitoringOccasionOfPO)); + if(pcchCfg->firstPDCCH_MonitoringOccasionOfPO == NULLP) + { + DU_LOG("\nERROR --> DU APP : BuildPcchConfig >> Memory Allocation fails"); + return RFAILED; + } + + if(fillFirstPdcchMonitoringOcc(pcchCfg->firstPDCCH_MonitoringOccasionOfPO, &duPcchCfg) == RFAILED) + { + DU_LOG("\nERROR --> DU APP : BuildPcchConfig >> Filling of Paging Occ failed"); + return RFAILED; + } return ROK; }/* BuildPcchConfig */ -- 2.16.6