From 41eaaec52d3fe0d5c003e6c0676e9a18fc8ba37a Mon Sep 17 00:00:00 2001 From: "lal.harshita" Date: Tue, 8 Nov 2022 19:15:54 +0530 Subject: [PATCH] [Epic-ID: ODUHIGH-462][Task-ID: ODUHIGH-472] Handling of drx timer in SCH [storing configuration] Signed-off-by: lal.harshita Change-Id: I8f24fb565665f55d3e81a480f657bbf31e09693c Signed-off-by: lal.harshita --- src/5gnrmac/lwr_mac_fsm.c | 8 +- src/5gnrmac/mac.h | 1 + src/5gnrmac/mac_cfg_hdl.c | 1 + src/5gnrmac/mac_rach.c | 2 +- src/5gnrmac/mac_slot_ind.c | 2 +- src/5gnrmac/mac_ue_mgr.c | 7 +- src/5gnrsch/sch.c | 4 + src/5gnrsch/sch.h | 81 ++++++- src/5gnrsch/sch_common.c | 8 +- src/5gnrsch/sch_drx.c | 524 ++++++++++++++++++++++++++++++++++++++++ src/5gnrsch/sch_drx.h | 61 +++++ src/5gnrsch/sch_rach.c | 10 +- src/5gnrsch/sch_rr.c | 6 +- src/5gnrsch/sch_slot_ind.c | 32 +-- src/5gnrsch/sch_ue_mgr.c | 60 ++++- src/cm/du_app_mac_inf.h | 4 + src/cm/mac_sch_interface.h | 10 +- src/cu_stub/cu_f1ap_msg_hdl.c | 57 +++-- src/cu_stub/cu_stub.h | 7 + src/du_app/du_f1ap_msg_hdl.c | 203 +++++++++------- src/du_app/du_mgr.h | 1 + src/du_app/du_mgr_main.c | 12 +- src/du_app/du_ue_mgr.c | 3 + src/phy_stub/phy_stub_msg_hdl.c | 2 +- 24 files changed, 948 insertions(+), 158 deletions(-) create mode 100644 src/5gnrsch/sch_drx.c create mode 100644 src/5gnrsch/sch_drx.h diff --git a/src/5gnrmac/lwr_mac_fsm.c b/src/5gnrmac/lwr_mac_fsm.c index d384c3d6a..cdf66a7f9 100644 --- a/src/5gnrmac/lwr_mac_fsm.c +++ b/src/5gnrmac/lwr_mac_fsm.c @@ -3664,7 +3664,7 @@ uint16_t fillDlTtiReq(SlotTimingInfo currTimingInfo) { GET_CELL_IDX(currTimingInfo.cellId, cellIdx); /* consider phy delay */ - ADD_DELTA_TO_TIME(currTimingInfo,dlTtiReqTimingInfo,PHY_DELTA_DL); + ADD_DELTA_TO_TIME(currTimingInfo,dlTtiReqTimingInfo,PHY_DELTA_DL, macCb.macCell[cellIdx]->numOfSlots); dlTtiReqTimingInfo.cellId = currTimingInfo.cellId; macCellCfg = macCb.macCell[cellIdx]->macCellCfg; @@ -4378,8 +4378,8 @@ uint16_t fillUlTtiReq(SlotTimingInfo currTimingInfo, p_fapi_api_queue_elem_t pre macCellCfg = macCb.macCell[cellIdx]->macCellCfg; /* add PHY delta */ - ADD_DELTA_TO_TIME(currTimingInfo,ulTtiReqTimingInfo,PHY_DELTA_UL); - currUlSlot = &macCb.macCell[cellIdx]->ulSlot[ulTtiReqTimingInfo.slot % MAX_SLOTS]; + ADD_DELTA_TO_TIME(currTimingInfo,ulTtiReqTimingInfo,PHY_DELTA_UL, macCb.macCell[cellIdx]->numOfSlots); + currUlSlot = &macCb.macCell[cellIdx]->ulSlot[ulTtiReqTimingInfo.slot % macCb.macCell[cellIdx]->numOfSlots]; LWR_MAC_ALLOC(ulTtiElem, (sizeof(fapi_api_queue_elem_t) + sizeof(fapi_ul_tti_req_t))); if(ulTtiElem) @@ -4679,7 +4679,7 @@ uint16_t fillUlDciReq(SlotTimingInfo currTimingInfo, p_fapi_api_queue_elem_t pre { GET_CELL_IDX(currTimingInfo.cellId, cellIdx); memcpy(&ulDciReqTimingInfo, &currTimingInfo, sizeof(SlotTimingInfo)); - currDlSlot = &macCb.macCell[cellIdx]->dlSlot[ulDciReqTimingInfo.slot % MAX_SLOTS]; + currDlSlot = &macCb.macCell[cellIdx]->dlSlot[ulDciReqTimingInfo.slot % macCb.macCell[cellIdx]->numOfSlots]; LWR_MAC_ALLOC(ulDciElem, (sizeof(fapi_api_queue_elem_t) + sizeof(fapi_ul_dci_req_t))); if(ulDciElem) diff --git a/src/5gnrmac/mac.h b/src/5gnrmac/mac.h index 6115c67dc..534b80eb2 100644 --- a/src/5gnrmac/mac.h +++ b/src/5gnrmac/mac.h @@ -229,6 +229,7 @@ typedef struct macUeCb struct macCellCb { uint16_t cellId; + uint16_t numOfSlots; CellState state; uint16_t crntiMap; MacRaCbInfo macRaCb[MAX_NUM_UE]; diff --git a/src/5gnrmac/mac_cfg_hdl.c b/src/5gnrmac/mac_cfg_hdl.c index f354fa430..6d94f0e2f 100644 --- a/src/5gnrmac/mac_cfg_hdl.c +++ b/src/5gnrmac/mac_cfg_hdl.c @@ -174,6 +174,7 @@ uint8_t MacProcCellCfgReq(Pst *pst, MacCellCfg *macCellCfg) GET_CELL_IDX(macCellCfg->cellId, cellIdx); macCb.macCell[cellIdx] = macCellCb; macCb.macCell[cellIdx]->cellId = macCellCfg->cellId; + macCb.macCell[cellIdx]->numOfSlots = 10 * (1 << macCellCfg->numerology); memcpy(&macCb.macCell[cellIdx]->macCellCfg, macCellCfg, sizeof(MacCellCfg)); MAC_ALLOC(macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1Pdu, \ diff --git a/src/5gnrmac/mac_rach.c b/src/5gnrmac/mac_rach.c index cc59d5c93..5190ea874 100644 --- a/src/5gnrmac/mac_rach.c +++ b/src/5gnrmac/mac_rach.c @@ -498,7 +498,7 @@ uint8_t MacProcUlSchInfo(Pst *pst, UlSchedInfo *ulSchedInfo) if(ulSchedInfo != NULLP) { MacUlSlot *currUlSlot = - &macCb.macCell[cellIdx]->ulSlot[ulSchedInfo->slotIndInfo.slot % MAX_SLOTS]; + &macCb.macCell[cellIdx]->ulSlot[ulSchedInfo->slotIndInfo.slot % macCb.macCell[cellIdx]->numOfSlots]; memcpy(&currUlSlot->ulInfo, ulSchedInfo, sizeof(UlSchedInfo)); } return ROK; diff --git a/src/5gnrmac/mac_slot_ind.c b/src/5gnrmac/mac_slot_ind.c index 2492f2a73..7c42b1030 100644 --- a/src/5gnrmac/mac_slot_ind.c +++ b/src/5gnrmac/mac_slot_ind.c @@ -347,7 +347,7 @@ void buildAndSendMuxPdu(SlotTimingInfo currTimingInfo) GET_CELL_IDX(currTimingInfo.cellId, cellIdx); - ADD_DELTA_TO_TIME(currTimingInfo, muxTimingInfo, PHY_DELTA_DL); + ADD_DELTA_TO_TIME(currTimingInfo, muxTimingInfo, PHY_DELTA_DL, macCb.macCell[cellIdx]->numOfSlots); currDlSlot = &macCb.macCell[cellIdx]->dlSlot[muxTimingInfo.slot]; for(ueIdx=0; ueIdxdrxCfgPresent = true; macCellGrpCfg->drxCfg.drxOnDurationTimer.onDurationTimerValInMs = macCellGrp.drxCfg.drxOnDurationTimer.onDurationTimerValInMs; if(!macCellGrp.drxCfg.drxOnDurationTimer.onDurationTimerValInMs) macCellGrpCfg->drxCfg.drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = \ @@ -1710,6 +1710,11 @@ uint8_t fillSchUeCfg(Pst *pst, SchUeCfg *schUeCfg, MacUeCfg *ueCfg) DU_LOG("\nERROR --> MAC : Failed to copy LCs at fillSchUeCfg()"); return ret; } + +#ifdef NR_DRX + schUeCfg->drxConfigIndicatorRelease = ueCfg->drxConfigIndicatorRelease;; +#endif + return ret; } diff --git a/src/5gnrsch/sch.c b/src/5gnrsch/sch.c index 3e485c4a5..1bd9343a7 100644 --- a/src/5gnrsch/sch.c +++ b/src/5gnrsch/sch.c @@ -666,6 +666,10 @@ uint8_t schInitCellCb(Inst inst, SchCellCfg *schCellCfg) cell->firstSib1Transmitted = false; fillSsbStartSymb(cell); cmLListInit(&cell->ueToBeScheduled); + +#ifdef NR_DRX + memset(cell->drxCb, 0, MAX_DRX_SIZE*sizeof(SchDrxCb)); +#endif schCb[inst].cells[inst] = cell; DU_LOG("\nINFO --> SCH : Cell init completed for cellId:%d", cell->cellId); diff --git a/src/5gnrsch/sch.h b/src/5gnrsch/sch.h index 4281ef808..89eb270dc 100644 --- a/src/5gnrsch/sch.h +++ b/src/5gnrsch/sch.h @@ -69,6 +69,13 @@ #define HQ_NACK 1 #define HQ_DTX 2 +#ifdef NR_DRX +/* As per 38.331 the largest offset which can be used in of size 10240. + * But using this much size of array can cause memory related issue so thats why + * taking this size which are a multiple of the larger size */ +#define MAX_DRX_SIZE 512 +#endif + typedef struct schDlHqProcCb SchDlHqProcCb; typedef struct schUlHqEnt SchUlHqEnt; typedef struct schRaReq SchRaReq; @@ -178,6 +185,17 @@ typedef struct schDlHqTbCb uint8_t statsBitmap; }SchDlHqTbCb; +#ifdef NR_DRX +typedef struct schDrxHarqCb +{ + uint32_t retxStrtIndex; + uint32_t rttIndex; + uint32_t retxIndex; + int16_t retxExpDistance; + uint8_t retxTmrReduction; +}SchDrxHarqCb; +#endif + typedef struct schUlHqProcCb { uint8_t procId; /*!< HARQ Process ID */ @@ -196,6 +214,9 @@ typedef struct schUlHqProcCb uint8_t dmrsMappingType; uint8_t nrOfDmrsSymbols; uint8_t dmrsAddPos; +#ifdef NR_DRX + SchDrxHarqCb ulDrxHarqCb; +#endif }SchUlHqProcCb; struct schDlHqProcCb @@ -209,6 +230,9 @@ struct schDlHqProcCb uint8_t k1; SchLcPrbEstimate dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/ CmLList dlHqProcLink; +#ifdef NR_DRX + SchDrxHarqCb dlDrxHarqCb; +#endif }; struct schUlHqEnt { @@ -385,6 +409,38 @@ typedef struct schHqUlMap CmLListCp hqList; }SchHqUlMap; +#ifdef NR_DRX +typedef struct schDrxUeCb +{ + bool drxDlUeActiveStatus; /* variable is used to store the status about downlink active status */ + bool drxUlUeActiveStatus; /* variable is used to store the status about uplink active status */ + uint32_t onDurationLen; /* length of on duration which is received from ue cfg/recfg in form of ms and subms, informs about after how many slots on duration gets expire */ + uint32_t inActvTimerLen; /* length of inActvTimer value received from ue cfg/recfg in form of ms, informs about after how many slots in active gets expire */ + uint8_t harqRttDlTimerLen; /* length of harqRttDlTimer received from ue cfg/recfg in form of symbols, inform about after how many slots on the harq drx-HARQ-RTT-TimerDL expire */ + uint8_t harqRttUlTimerLen; /* length of harqRttUlTimer received from ue cfg/recfg in form of symbols,informs about after how many slots on harq drx-HARQ-RTT-TimerUL expire*/ + uint32_t retransDlTimerLen; /* length of retransDlTimer received from ue cfg/recfg in form of slot, informs about after how many slots on harq RetransmissionTimer dl timer expire*/ + uint32_t retransUlTimerLen; /* length of retransUlTimer received from ue cfg/recfg in form of slot, informs about after how many slots on harq RetransmissionTimer ul timer expire*/ + uint32_t longCycleLen; /* length of long Cycle value received from ue cfg/recfg in form of ms*/ + bool longCycleToBeUsed; /* long cycle should be used once the short cycle gets expires */ + uint32_t drxStartOffset; /* length of drxStartOffset value received from ue cfg/recfg in form of ms, which helps in getting on duration start point*/ + bool shortCyclePresent; /* set this value if shortCycle is Present */ + uint32_t shortCycleLen; /* length of short Cycle value received from ue cfg/recfg in form of ms*/ + uint32_t shortCycleTmrLen; /* value shortCycleTmr is the multiple of shortCycle which is received from ue cfg/recfg in form of integer*/ + uint32_t drxSlotOffset; /* drxSlotOffset value received from ue cfg/recfg which is used to delay before starting the drx-onDuration*/ + uint32_t onDurationStartIndex; /* Index at which UE is stored in onDuration starts list */ + uint32_t onDurationExpiryIndex; /* Index at which UE is stored in onDuration expires in the list */ + uint32_t inActvExpiryIndex; /* Index at which UE is stored in inActvTimer expires in the list */ + uint32_t shortCycleExpiryIndex; /* Index at which UE is stored in shortCycle expires in the list */ + int32_t shortCycleDistance; /* Distance after how many slot short cycle tmr gets expire */ + int32_t onDurationStartDistance;/* Distance after how many slot on Duration Start tmr gets expire */ + int32_t onDurationExpiryDistance;/* Distance after how many slot on Duration tmr gets expire */ + int32_t inActiveTmrExpiryDistance;/* Distance after how many slot inActive tmr gets expire */ + CmLList *onDurationStartNodeInfo; /* Node present in on duration start list*/ + CmLList *onDurationExpiryNodeInfo;/* Node present in on duration exp list*/ + CmLList *inActvTimerExpiryNodeInfo; /* Node present in in active exp list*/ + CmLList *shortCycleTmrExpiryNodeInfo; /* Node present in short cycle exp list*/ +}SchDrxUeCb; +#endif /** * @brief * UE control block @@ -410,6 +466,10 @@ typedef struct schUeCb SchHqUlMap **hqUlmap; CmLListCp ulRetxHqList; CmLListCp dlRetxHqList; +#ifdef NR_DRX + bool ueDrxInfoPres; + SchDrxUeCb drxUeCb; +#endif }SchUeCb; /** @@ -448,6 +508,22 @@ typedef struct schPageCb SchPagingOcc pagMonOcc[MAX_PO_PER_PF]; /*Paging Occasion Slot/FrameOffset are stored*/ }SchPageCb; +#ifdef NR_DRX +typedef struct schDrxCb +{ + CmLListCp onDurationStartList; /*!< Tracks the start of onDuration Timer. */ + CmLListCp onDurationExpiryList; /*!< Tracks the Expiry of onDuration Timer. */ + CmLListCp inActvTmrExpiryList; /*!< Tracks the Expiry of drx-InactivityTimer. */ + CmLListCp shortCycleExpiryList; /*!< Tracks the Expiry of DRX Short Cycle. */ + CmLListCp dlHarqRttExpiryList; /*!< Tracks the Expiry of DL HARQ RTT timer. */ + CmLListCp dlRetransExpiryList; /*!< Tracks the Expiry of DL Re-Transmission timer. */ + CmLListCp ulHarqRttExpiryList; /*!< Tracks the Expiry of UL HARQ RTT timer. */ + CmLListCp ulRetransExpiryList; /*!< Tracks the Expiry of UL Re-Transmission timer. */ + CmLListCp dlRetransTmrStartList; /*!< It has list of DL harq procs for */ + CmLListCp ulRetransTmrStartList; /*!< It has list of UL harq procs for */ +}SchDrxCb; +#endif + /** * @brief * Cell Control block per cell. @@ -457,7 +533,7 @@ typedef struct schCellCb uint16_t cellId; /*!< Cell ID */ Inst instIdx; /*!< Index of the scheduler instance */ Inst macInst; /*!< Index of the MAC instance */ - uint8_t numSlots; /*!< Number of slots in current frame */ + uint16_t numSlots; /*!< Number of slots in current frame */ SlotTimingInfo slotInfo; /*!< SFN, Slot info being processed*/ SchDlSlotInfo **schDlSlotInfo; /*!< SCH resource allocations in DL */ SchUlSlotInfo **schUlSlotInfo; /*!< SCH resource allocations in UL */ @@ -479,6 +555,9 @@ typedef struct schCellCb uint32_t slotFrmtBitMap; /*!< 2 bits must be read together to determine D/U/S slots. 00-D, 01-U, 10-S */ uint32_t symbFrmtBitMap; /*!< 2 bits must be read together to determine D/U/S symbols. 00-D, 01-U, 10-S */ #endif +#ifdef NR_DRX + SchDrxCb drxCb[MAX_DRX_SIZE]; /*!< Drx cb*/ +#endif }SchCellCb; diff --git a/src/5gnrsch/sch_common.c b/src/5gnrsch/sch_common.c index bc5ca0f15..c441a0c8c 100644 --- a/src/5gnrsch/sch_common.c +++ b/src/5gnrsch/sch_common.c @@ -476,7 +476,7 @@ uint8_t schUlResAlloc(SchCellCb *cell, Inst schInst) memset(&ulSchedInfo, 0, sizeof(UlSchedInfo)); /* add PHY delta */ - ADD_DELTA_TO_TIME(cell->slotInfo,ulTimingInfo,PHY_DELTA_UL+SCHED_DELTA); + ADD_DELTA_TO_TIME(cell->slotInfo,ulTimingInfo,PHY_DELTA_UL+SCHED_DELTA, cell->numSlots); ulSchedInfo.cellId = cell->cellId; ulSchedInfo.slotIndInfo.cellId = ulSchedInfo.cellId; @@ -744,7 +744,7 @@ uint16_t schAllocPucchResource(SchCellCb *cell, SlotTimingInfo pucchTime, uint16 /* set HARQ flag to true */ schUlSlotInfo->schPucchInfo.harqFlag = true; schUlSlotInfo->schPucchInfo.numHarqBits = 1; /* 1 bit for HARQ */ - ADD_DELTA_TO_TIME(pucchTime, pucchTime, 3); /* SLOT_DELAY=3 */ + ADD_DELTA_TO_TIME(pucchTime, pucchTime, 3, cell->numSlots); /* SLOT_DELAY=3 */ cmLListAdd2Tail(&(ueCb->hqDlmap[pucchTime.slot]->hqList), &hqP->ulSlotLnk); } return ROK; @@ -2007,7 +2007,7 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId } /* Calculating time frame to send DCI for SR */ - ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA); + ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(dciTime.slot, cell->slotFrmtBitMap) == DL_SLOT) #endif @@ -2035,7 +2035,7 @@ bool schProcessSrOrBsrReq(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId } /* Check for number of Symbol of PUSCH should be same as original in case of transmisson*/ /* Calculating time frame to send PUSCH for SR */ - ADD_DELTA_TO_TIME(dciTime, puschTime, k2Val); + ADD_DELTA_TO_TIME(dciTime, puschTime, k2Val, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(puschTime.slot, cell->slotFrmtBitMap) == DL_SLOT) continue; diff --git a/src/5gnrsch/sch_drx.c b/src/5gnrsch/sch_drx.c new file mode 100644 index 000000000..ff0844df7 --- /dev/null +++ b/src/5gnrsch/sch_drx.c @@ -0,0 +1,524 @@ + +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ + *******************************************************************************/ +#ifdef NR_DRX +#include "common_def.h" +#include "tfu.h" +#include "lrg.h" +#include "tfu.x" +#include "lrg.x" +#include "du_log.h" +#include "du_app_mac_inf.h" +#include "mac_sch_interface.h" +#include "sch.h" +#include "sch_utils.h" +#include "sch_drx.h" + +/** + * @brief intialize the SchDrxHarqCb structre + * + * @details + * + * Function :schInitDrxHarqCb + * + * intialize the SchDrxHarqCb structre + * + * @param[in] SchDrxHarqCb *hqCb + * @return + * -# ROK + * -# RFAILED + **/ + +void schInitDrxHarqCb(SchDrxHarqCb *hqDrxCb) +{ + memset(hqDrxCb, 0, sizeof(SchDrxHarqCb)); + hqDrxCb->retxExpDistance = SCH_DRX_INVALID_DISTANCE; + hqDrxCb->retxStrtIndex = SCH_DRX_INVALID_INDEX; + hqDrxCb->rttIndex = SCH_DRX_INVALID_INDEX; + hqDrxCb->retxIndex = SCH_DRX_INVALID_INDEX; +} + +/** + * @brief intialize the SchDrxUeCb structre + * + * @details + * + * Function : schInitDrxUeCb + * + * intialize the SchDrxUeCb structre + * + * @param[in] SchUeCb *ueCb + * @return + * -# ROK + * -# RFAILED + **/ + +void schInitDrxUeCb(SchUeCb *ueCb) +{ + memset(&ueCb->drxUeCb, 0, sizeof(SchDrxUeCb)); + ueCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX; + ueCb->drxUeCb.onDurationExpiryIndex = SCH_DRX_INVALID_INDEX; + ueCb->drxUeCb.inActvExpiryIndex = SCH_DRX_INVALID_INDEX; + ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX; + ueCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE; + ueCb->drxUeCb.onDurationExpiryDistance = SCH_DRX_INVALID_DISTANCE; + ueCb->drxUeCb.inActiveTmrExpiryDistance = SCH_DRX_INVALID_DISTANCE; + ueCb->drxUeCb.drxDlUeActiveStatus = false; + ueCb->drxUeCb.drxUlUeActiveStatus = false; +} + +/* will uncomment this function in next gerrit */ +#if 0 +/** + * @brief delete Dl harq drx timers and information + * + * @details + * + * Function : schDeleteDlHarqDrxTimer + * + * delete Dl harq drx timers and information + * + * @param[in] SchCellCb *cell, SchUeCb *ueCb + * @return + * -# ROK + * -# RFAILED + **/ + void schDeleteDlHarqDrxTimer(SchCellCb *cell, SchDlHqEnt *dlHqEnt) + { + uint8_t idx, numHqPrcs; + uint16_t tmrIdx = 0; + SchDlHqProcCb *procs; + CmLList *node = NULLP; + + numHqPrcs = dlHqEnt->numHqPrcs; + for(idx =0; idxprocs[idx]; + tmrIdx = procs->dlDrxHarqCb.retxStrtIndex; + CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node); + if(node) + { + cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransTmrStartList, node); + SCH_FREE(node, sizeof(CmLList)); + } + + tmrIdx = procs->dlDrxHarqCb.rttIndex; + CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node); + if(node) + { + cmLListDelFrm(&cell->drxCb[tmrIdx].dlHarqRttExpiryList, node); + SCH_FREE(node, sizeof(CmLList)); + } + + tmrIdx = procs->dlDrxHarqCb.retxIndex; + CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].dlRetransExpiryList, node); + if(node) + { + cmLListDelFrm(&cell->drxCb[tmrIdx].dlRetransExpiryList, node); + SCH_FREE(node, sizeof(CmLList)); + } + schInitDrxHarqCb(&procs->dlDrxHarqCb); + } + } + +/** + * @brief delete UL harq drx timers and information + * + * @details + * + * Function : schDeleteUlHarqDrxTimer + * + * delete Ul harq drx timers and information + * + * @param[in] SchCellCb *cell, SchUeCb *ueCb + * @return + * -# ROK + * -# RFAILED + **/ + void schDeleteUlHarqDrxTimer(SchCellCb *cell, SchUlHqEnt *ulHqEnt) + { + uint8_t idx, numHqPrcs; + uint16_t tmrIdx = 0; + CmLList *node = NULLP; + SchUlHqProcCb *procs; + + numHqPrcs = ulHqEnt->numHqPrcs; + for(idx =0; idxprocs[idx]; + tmrIdx = procs->ulDrxHarqCb.retxStrtIndex; + CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node); + if(node) + { + cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransTmrStartList, node); + SCH_FREE(node, sizeof(CmLList)); + } + + tmrIdx = procs->ulDrxHarqCb.rttIndex; + CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node); + if(node) + { + cmLListDelFrm(&cell->drxCb[tmrIdx].ulHarqRttExpiryList, node); + SCH_FREE(node, sizeof(CmLList)); + } + + tmrIdx = procs->ulDrxHarqCb.retxIndex; + CM_LLIST_FIRST_NODE(&cell->drxCb[tmrIdx].ulRetransExpiryList, node); + if(node) + { + cmLListDelFrm(&cell->drxCb[tmrIdx].ulRetransExpiryList, node); + SCH_FREE(node, sizeof(CmLList)); + } + schInitDrxHarqCb(&procs->ulDrxHarqCb); + } + } +#endif + +/** + * @brief delete UE drx timers and information + * + * @details + * + * Function : schDeleteUeDrxInfo + * + * delete UE drx timers and information + * + * @param[in] SchCellCb *cell, SchUeCb *ueCb + * @return void + * + **/ + +void schDeleteUeDrxInfo(SchCellCb *cell, SchUeCb *ueCb) +{ + SchDrxUeCb *drxUeCb; + + if(ueCb->ueDrxInfoPres == true) + { + drxUeCb = &ueCb->drxUeCb; + + /* delete on duration start timer from ueCb */ + if(drxUeCb->onDurationStartIndex != SCH_DRX_INVALID_INDEX) + { + cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationStartIndex].onDurationStartList, drxUeCb->onDurationStartNodeInfo); + SCH_FREE(drxUeCb->onDurationStartNodeInfo, sizeof(CmLList)); + } + + /* delete on duration expiry timer from ueCb */ + if(drxUeCb->onDurationExpiryIndex != SCH_DRX_INVALID_INDEX) + { + cmLListDelFrm(&cell->drxCb[drxUeCb->onDurationExpiryIndex].onDurationExpiryList, drxUeCb->onDurationExpiryNodeInfo); + SCH_FREE(drxUeCb->onDurationExpiryNodeInfo, sizeof(CmLList)); + } + + /* delete inActv Expiry Index timer from ueCb */ + if(drxUeCb->inActvExpiryIndex != SCH_DRX_INVALID_INDEX) + { + cmLListDelFrm(&cell->drxCb[drxUeCb->inActvExpiryIndex].inActvTmrExpiryList, drxUeCb->inActvTimerExpiryNodeInfo); + SCH_FREE(drxUeCb->inActvTimerExpiryNodeInfo, sizeof(CmLList)); + } + + /* delete short cycle expiry timer from ueCb */ + if(drxUeCb->shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX) + { + cmLListDelFrm(&cell->drxCb[drxUeCb->shortCycleExpiryIndex].shortCycleExpiryList, drxUeCb->shortCycleTmrExpiryNodeInfo); + SCH_FREE(drxUeCb->shortCycleTmrExpiryNodeInfo, sizeof(CmLList)); + } + /* TODO - will uncomment this function in next gerrit */ + //schDeleteDlHarqDrxTimer(cell, &ueCb->dlHqEnt); + //schDeleteUlHarqDrxTimer(cell, &ueCb->ulHqEnt); + schInitDrxUeCb(ueCb); + } +} + +/** + * @brief fill drxUeCb structure with the help of ue cfg/recfg information + * + * @details + * + * Function : schFillDrxUeCb + * + * fill drxUeCb structure with the help of ue cfg/recfg information + * + * @param[in] SchDrxCfg drxCfg ->configuration received from ue cfg/recfg api + * SchDrxUeCb *drxUeCb -> structure that need to be fill + * @return + * -# ROK + * -# RFAILED + **/ + +void schFillDrxUeCb(uint8_t numerology, SchDrxCfg drxCfg, SchDrxUeCb *drxUeCb) +{ + if(drxCfg.drxOnDurationTimer.onDurationTimerValInMs) + { + SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.milliSeconds, numerology); + } + else + { + SCH_CNVRT_MS_TO_SLOT(drxUeCb->onDurationLen, drxCfg.drxOnDurationTimer.onDurationtimerValue.subMilliSeconds, numerology); + drxUeCb->onDurationLen = drxUeCb->onDurationLen >> 5; + } + SCH_CNVRT_MS_TO_SLOT(drxUeCb->inActvTimerLen, drxCfg.drxInactivityTimer, numerology); + SCH_CNVRT_SYMBL_TO_SLOT(drxUeCb->harqRttDlTimerLen, drxCfg.drxHarqRttTimerDl); + SCH_CNVRT_SYMBL_TO_SLOT(drxUeCb->harqRttUlTimerLen, drxCfg.drxHarqRttTimerUl); + drxUeCb->retransDlTimerLen = drxCfg.drxRetransmissionTimerDl; + drxUeCb->retransUlTimerLen = drxCfg.drxRetransmissionTimerUl; + SCH_CNVRT_MS_TO_SLOT(drxUeCb->longCycleLen, drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetChoice, numerology); + SCH_CNVRT_MS_TO_SLOT(drxUeCb->drxStartOffset, drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetVal, numerology); + if(drxCfg.shortDrxPres) + { + drxUeCb->shortCyclePresent = true; + SCH_CNVRT_MS_TO_SLOT(drxUeCb->shortCycleLen, drxCfg.shortDrx.drxShortCycle, numerology); + drxUeCb->shortCycleTmrLen = drxUeCb->shortCycleLen*drxCfg.shortDrx.drxShortCycleTimer; + } + drxUeCb->longCycleToBeUsed = true; + SCH_CNVRT_MS_TO_SLOT(drxUeCb->drxSlotOffset, drxCfg.drxSlotOffset, numerology); + drxUeCb->drxSlotOffset = drxUeCb->drxSlotOffset>>5; +} + +/** + * @brief Add new entry into the drx timer list + * + * @details + * + * Function : schAddDrxTimerIntoList + * + * Add new entry into the drx timer list + * + * @param[in] CmLListCp *drxTimerList -> List in which new entery have to add + * void * ueInfo -> ue information which is need to the added into list + * @return + * -# ROK + * -# RFAILED + **/ + +uint8_t schAddDrxTimerIntoList(CmLListCp *drxTimerList,void * nodeInfo, CmLList *drxNodeInfo) +{ + CmLList *currentNodeInfo = NULLP; + + SCH_ALLOC(currentNodeInfo, sizeof(CmLList)); + if(!currentNodeInfo) + { + DU_LOG("\nERROR --> SCH : schAddDrxTimerIntoList() : Memory allocation failed"); + return RFAILED; + } + + currentNodeInfo->node = (PTR)nodeInfo; + + cmLListAdd2Tail(drxTimerList, currentNodeInfo); + drxNodeInfo = currentNodeInfo; + DU_LOG("\nINFO --> SCH : Drx node added into the list"); + return ROK; +} + +/** + * @brief This function is used to find the next onduration start timing + * + * @details + * + * Function : findNextOndurationOccurance + * + * This function is used to find the next onduration start timing + * + * @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo *nxtOnDur, + * uint8_t delta + * + * @return + * -# void + **/ + +void findNextOndurationOccurance(SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo *nxtOnDur, uint8_t delta) +{ + uint16_t tmpDistance, numOfCycles; + uint32_t curTime, cycleLen, nxtDist; + SlotTimingInfo tmpTime; + + if (ueDrxCb->longCycleToBeUsed == true) + { + cycleLen = ueDrxCb->longCycleLen; + } + else + { + cycleLen = ueDrxCb->shortCycleLen; + } + + /* Add delta to current time */ + ADD_DELTA_TO_TIME(cell->slotInfo, tmpTime, delta, cell->numSlots); + + /* Convert tmpTime to number of slots */ + curTime = ((tmpTime.sfn * cell->numSlots) + tmpTime.slot); + + /* as per 38.321, if the criterion below is satisfied, then that sfn and + * slot are the correct ones for the on-duration timer. + * if the Short DRX Cycle is used, and [(SFN × 10) + subframe number] modulo + * (drx-ShortCycle) = (drxStartOffset) modulo (drx-ShortCycle); or + * if the Long DRX Cycle is used, and [(SFN × 10) + subframe number] modulo + * (drx-LongCycle) = drxStartOffset */ + if ( curTime <= ueDrxCb->drxStartOffset) + { + /* offset is the nextOnDur */ + nxtDist = ((((ueDrxCb->drxStartOffset / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (ueDrxCb->drxStartOffset % cell->numSlots); + } + else + { + tmpDistance = curTime - ueDrxCb->drxStartOffset; + numOfCycles = tmpDistance / cycleLen; + + if (0 == (tmpDistance % cycleLen)) + { + /* Perfect match pick up the current time */ + nxtDist = ((((curTime / cell->numSlots)) & (MAX_SFN - 1)) * cell->numSlots) + (curTime % cell->numSlots); + } + else + { + nxtDist = ueDrxCb->drxStartOffset + (numOfCycles + 1) * cycleLen; + } + } + + /* If slot offset is non-zero then Add slot offset to the calculated onDur + * distance */ + if(ueDrxCb->drxSlotOffset) + { + nxtDist = nxtDist + ueDrxCb->drxSlotOffset; + } + /*If next On Duration is less than DL DELTA ahead, we will miss it and + * hence need to move to the On-Duration after that.*/ + if((nxtDist - (curTime - delta)) <= SCH_DRX_MAX_DELTA) + { + nxtDist = nxtDist + cycleLen; + } + + nxtOnDur->sfn = ((nxtDist / cell->numSlots) & (MAX_SFN - 1)); + nxtOnDur->slot = (nxtDist % cell->numSlots); +} + +/** + * @brief Add entry into the on duration list and short cycle list + * + * @details + * + * Function : schDrxUeReCfgTimer + * + * This function is used to Add entry into the on duration list and short + * cycle list + * + * @param[in] SchCellCb *cell, SchUeCb *ueCb + * uint8_t delta + * + * @return void + **/ + +void schDrxUeReCfgTimer(SchCellCb *cell, SchUeCb *ueCb) +{ + uint8_t currentSlotIndx; + uint32_t onDurTime, onDurExpSlotTime, currentSlotTime; + uint32_t cycleLen; + SlotTimingInfo onDurationOccurance; + + if(ueCb->drxUeCb.shortCyclePresent == false) + { + /* if short cycle configuration are not recived as a part of UE Recfg then if there is any entry present in short cycle timer list + * remove the entry from the list */ + if(ueCb->drxUeCb.shortCycleExpiryIndex != SCH_DRX_INVALID_INDEX) + { + cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.shortCycleExpiryIndex ].shortCycleExpiryList, ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo); + SCH_FREE(ueCb->drxUeCb.shortCycleTmrExpiryNodeInfo, sizeof(CmLList)); + ueCb->drxUeCb.shortCycleExpiryIndex = SCH_DRX_INVALID_INDEX; + ueCb->drxUeCb.shortCycleDistance = SCH_DRX_INVALID_DISTANCE; + } + } + /* If there is any entry present in on duration start list then remove the + * entry from the list and recaluate the nect onduration cucurance */ + if(ueCb->drxUeCb.onDurationStartIndex != SCH_DRX_INVALID_INDEX) + { + cmLListDelFrm(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb->drxUeCb.onDurationStartNodeInfo); + SCH_FREE(ueCb->drxUeCb.onDurationStartNodeInfo, sizeof(CmLList)); + ueCb->drxUeCb.onDurationStartIndex = SCH_DRX_INVALID_INDEX; + ueCb->drxUeCb.onDurationStartDistance = SCH_DRX_INVALID_DISTANCE; + } + + findNextOndurationOccurance(cell, &ueCb->drxUeCb, &onDurationOccurance, 0); + onDurTime = onDurationOccurance.sfn*cell->numSlots+onDurationOccurance.slot; + + /* If Onduration timer of old configuration is already running then next onduration + * starts once it expires*/ + if((ueCb->drxUeCb.onDurationExpiryDistance != SCH_DRX_INVALID_DISTANCE) && (ueCb->drxUeCb.onDurationExpiryIndex != SCH_DRX_INVALID_INDEX)) + { + currentSlotTime = cell->slotInfo.sfn * cell->numSlots + cell->slotInfo.slot; + currentSlotIndx = (currentSlotTime + PHY_DELTA_DL + SCHED_DELTA)%MAX_DRX_SIZE; + if(currentSlotIndx >= ueCb->drxUeCb.onDurationExpiryIndex ) + { + onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance +1) * MAX_DRX_SIZE) +\ + (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA); + } + else + { + + onDurExpSlotTime = currentSlotTime + ((ueCb->drxUeCb.onDurationExpiryDistance) * MAX_DRX_SIZE) +\ + (ueCb->drxUeCb.onDurationExpiryIndex - currentSlotIndx + PHY_DELTA_DL + SCHED_DELTA); + } + if(onDurTime <= onDurExpSlotTime) + { + if(ueCb->drxUeCb.longCycleToBeUsed == true) + cycleLen = ueCb->drxUeCb.longCycleLen; + else + cycleLen = ueCb->drxUeCb.shortCycleLen; + + onDurTime = onDurTime + ((onDurExpSlotTime - onDurTime)/cycleLen + 1) * cycleLen; + } + } + SCH_CALCULATE_TIMER_INDEX(onDurTime, ueCb->drxUeCb.onDurationStartIndex); + ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, cell->numSlots)/MAX_DRX_SIZE; + schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo); +} + +/** + * @brief Add entry into the on duration list + * + * @details + * + * Function : schAddUeInOndurationList + * + * This function is used to Add entry into the on duration list + * + * @param[in] SchCellCb *cell, SchDrxUeCb *ueDrxCb, SlotTimingInfo *nxtOnDur, + * uint8_t delta + * + * @return + * -# void + **/ + +void schAddUeInOndurationList(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta) +{ + uint32_t onDurTime; + SlotTimingInfo onDurationOccurance; + + if(ueCb->ueDrxInfoPres) + { + findNextOndurationOccurance(cell, &ueCb->drxUeCb, &onDurationOccurance, delta); + onDurTime = onDurationOccurance.sfn*cell->numSlots+onDurationOccurance.slot; + SCH_CALCULATE_TIMER_INDEX(onDurTime, ueCb->drxUeCb.onDurationStartIndex); + ueCb->drxUeCb.onDurationStartDistance = SCH_CALC_SLOT_DIFF(onDurationOccurance, cell->slotInfo, cell->numSlots)/MAX_DRX_SIZE; + schAddDrxTimerIntoList(&cell->drxCb[ueCb->drxUeCb.onDurationStartIndex].onDurationStartList, ueCb, ueCb->drxUeCb.onDurationStartNodeInfo); + + } +} + +#endif +/********************************************************************** + End of file + **********************************************************************/ diff --git a/src/5gnrsch/sch_drx.h b/src/5gnrsch/sch_drx.h new file mode 100644 index 000000000..c19b710fd --- /dev/null +++ b/src/5gnrsch/sch_drx.h @@ -0,0 +1,61 @@ +/******************************************************************************* +################################################################################ +# Copyright (c) [2017-2019] [Radisys] # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +################################################################################ +*******************************************************************************/ + +#define SCH_DRX_INVALID_DISTANCE -1 +#define SCH_DRX_INVALID_INDEX 0xFFFFFF +#define SCH_DRX_MAX_DELTA 1 +#define SCH_DRX_TMRS_EXP_DELTA 1 + +/** @brief Macro to convert milli second to slots */ +#define SCH_CNVRT_MS_TO_SLOT(_numSlot, _timeInMs, _mu)\ +{\ + _numSlot = _timeInMs * (1 << _mu);\ +} + +/** @brief Macro to convert number symbols to slots */ +#define SCH_CNVRT_SYMBL_TO_SLOT(_numSlot, _numSymbl)\ +{\ + _numSlot = _numSymbl/MAX_SYMB_PER_SLOT; \ +} + +/** @brief Macro to find the slot difference */ +#define SCH_CALC_SLOT_DIFF(_newTime, _oldTime, _numOfSlotsPerRadioFrame)\ +((_newTime.sfn*_numOfSlotsPerRadioFrame+_newTime.slot) >= (_oldTime.sfn*_numOfSlotsPerRadioFrame+_oldTime.slot)?\ +(_newTime.sfn*_numOfSlotsPerRadioFrame+_newTime.slot) - (_oldTime.sfn*_numOfSlotsPerRadioFrame+_oldTime.slot) : \ +(_newTime.sfn*_numOfSlotsPerRadioFrame+_newTime.slot) + (1024*_numOfSlotsPerRadioFrame - (_oldTime.sfn*_numOfSlotsPerRadioFrame+_oldTime.slot))) + +/** @brief Macro to used calculate timer index */ +#define SCH_CALCULATE_TIMER_INDEX(_numSlots, _timerIndx)\ +{\ + _timerIndx = _numSlots % MAX_DRX_SIZE; \ +} + +void schInitDrxUeCb(SchUeCb *ueCb); +void schFillDrxUeCb(uint8_t numerology, SchDrxCfg drxCfg, SchDrxUeCb *drxUeCb); +void schDeleteUeDrxInfo(SchCellCb *cell, SchUeCb *ueCb); +void schHandleStartDrxTimer(SchCellCb *cell); +void schHdlDrxInActvStrtTmr(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta); +void schInitDrxHarqCb(SchDrxHarqCb *hqCb); +void schAddUeInOndurationList(SchCellCb *cell, SchUeCb *ueCb, uint8_t delta); +void schDrxUeReCfgTimer(SchCellCb *cell, SchUeCb *ueCb); +void schHdlDrxShortCycleExpiryTimer(SchCellCb *cell); +void schHdlDrxOnDurExpiryTimer(SchCellCb *cell); +void schHandleExpiryDrxTimer(SchCellCb *cell); +/********************************************************************** + End of file + **********************************************************************/ diff --git a/src/5gnrsch/sch_rach.c b/src/5gnrsch/sch_rach.c index 8a81745fd..315ac6e27 100644 --- a/src/5gnrsch/sch_rach.c +++ b/src/5gnrsch/sch_rach.c @@ -570,7 +570,7 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin } /* Calculating time frame to send DCI for RAR */ - ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA); + ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots); dciSlot = dciTime.slot; #ifdef NR_TDD /* Consider this slot for sending DCI, only if it is a DL slot */ @@ -595,7 +595,7 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin k0 = cell->cellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[k0Index].k0; /* Calculating time frame to send RAR PDSCH */ - ADD_DELTA_TO_TIME(dciTime, rarTime, k0); + ADD_DELTA_TO_TIME(dciTime, rarTime, k0, cell->numSlots); rarSlot = rarTime.slot; /* If PDSCH is already scheduled on this slot, cannot schedule PDSCH for another UE here. */ @@ -620,7 +620,7 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin k1 = defaultUlAckTbl[k1Index]; } - ADD_DELTA_TO_TIME(rarTime, pucchTime, k1); + ADD_DELTA_TO_TIME(rarTime, pucchTime, k1, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(pucchTime.slot, cell->slotFrmtBitMap) == DL_SLOT) continue; @@ -643,7 +643,7 @@ bool schProcessRaReq(Inst schInst, SchCellCb *cell, SlotTimingInfo currTime, uin k2 = k2 + msg3Delta; if(k2 >= msg3MinSchTime) { - ADD_DELTA_TO_TIME(rarTime, msg3Time, k2); + ADD_DELTA_TO_TIME(rarTime, msg3Time, k2, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(msg3Time.slot % totalCfgSlot, cell->slotFrmtBitMap) == DL_SLOT) continue; @@ -830,7 +830,7 @@ uint8_t schProcessRachInd(RachIndInfo *rachInd, Inst schInst) winNumSlots = (float)cell->cellCfg.schRachCfg.raRspWindow / slotDuration; /* Adding window size to window start time to get window end time */ - ADD_DELTA_TO_TIME(raReq->winStartTime, raReq->winEndTime, winNumSlots); + ADD_DELTA_TO_TIME(raReq->winStartTime, raReq->winEndTime, winNumSlots, cell->numSlots); cell->raReq[ueId -1] = raReq; /* Adding UE Id to list of pending UEs to be scheduled */ diff --git a/src/5gnrsch/sch_rr.c b/src/5gnrsch/sch_rr.c index a6c52e2ec..64ae9210b 100644 --- a/src/5gnrsch/sch_rr.c +++ b/src/5gnrsch/sch_rr.c @@ -54,7 +54,7 @@ uint8_t schMsg3RetxSchedulingForUe(SchRaCb *raCb) currTime = cell->slotInfo; /* Calculating time frame to send DCI for MSG3 Retx*/ - ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA); + ADD_DELTA_TO_TIME(currTime, dciTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots); #ifdef NR_TDD /* Consider this slot for sending DCI, only if it is a DL slot */ if(schGetSlotSymbFrmt(dciSlot, raCb->cell->slotFrmtBitMap) == DL_SLOT) @@ -154,7 +154,7 @@ bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, S k2 = k2 + msg3Delta; if(k2 >= msg3MinSchTime) { - ADD_DELTA_TO_TIME(currTime, msg3TempTime, k2); + ADD_DELTA_TO_TIME(currTime, msg3TempTime, k2, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(msg3TempTime.slot % totalCfgSlot, cell->slotFrmtBitMap) == DL_SLOT) continue; @@ -177,4 +177,4 @@ bool schGetMsg3K2(SchCellCb *cell, SchUlHqProcCb* msg3HqProc, uint16_t dlTime, S } /********************************************************************** End of file - **********************************************************************/ \ No newline at end of file + **********************************************************************/ diff --git a/src/5gnrsch/sch_slot_ind.c b/src/5gnrsch/sch_slot_ind.c index 12a387cb0..3bcff2e01 100644 --- a/src/5gnrsch/sch_slot_ind.c +++ b/src/5gnrsch/sch_slot_ind.c @@ -128,7 +128,7 @@ uint8_t sendDlPageAllocToMac(DlPageAlloc *dlPageAlloc, Inst inst) * RFAILED - failure * * ****************************************************************/ -void schCalcSlotValues(SlotTimingInfo slotInd, SchSlotValue *schSlotValue) +void schCalcSlotValues(SlotTimingInfo slotInd, SchSlotValue *schSlotValue, uint16_t numOfSlots) { /**************************************************************** * PHY_DELTA - the physical layer delta * @@ -143,11 +143,11 @@ void schCalcSlotValues(SlotTimingInfo slotInd, SchSlotValue *schSlotValue) * on PHY_DELTA + SCHED_DELTA + BO_DELTA * ****************************************************************/ - ADD_DELTA_TO_TIME(slotInd, schSlotValue->currentTime, PHY_DELTA_DL); - ADD_DELTA_TO_TIME(slotInd, schSlotValue->broadcastTime, PHY_DELTA_DL + SCHED_DELTA); - ADD_DELTA_TO_TIME(slotInd, schSlotValue->rarTime, PHY_DELTA_DL + SCHED_DELTA); - ADD_DELTA_TO_TIME(slotInd, schSlotValue->dlMsgTime, PHY_DELTA_DL + SCHED_DELTA); - ADD_DELTA_TO_TIME(slotInd, schSlotValue->ulDciTime, PHY_DELTA_DL + SCHED_DELTA); + ADD_DELTA_TO_TIME(slotInd, schSlotValue->currentTime, PHY_DELTA_DL, numOfSlots); + ADD_DELTA_TO_TIME(slotInd, schSlotValue->broadcastTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots); + ADD_DELTA_TO_TIME(slotInd, schSlotValue->rarTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots); + ADD_DELTA_TO_TIME(slotInd, schSlotValue->dlMsgTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots); + ADD_DELTA_TO_TIME(slotInd, schSlotValue->ulDciTime, PHY_DELTA_DL + SCHED_DELTA, numOfSlots); } /******************************************************************* @@ -252,7 +252,7 @@ bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, SchUeCb *ueCb = NULLP; SchK0K1TimingInfoTbl *k0K1InfoTbl; - ADD_DELTA_TO_TIME(currTime, (*pdcchTime), PHY_DELTA_DL + SCHED_DELTA); + ADD_DELTA_TO_TIME(currTime, (*pdcchTime), PHY_DELTA_DL + SCHED_DELTA, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(pdcchTime->slot, cell->slotFrmtBitMap) != DL_SLOT) { @@ -296,7 +296,7 @@ bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, } } - ADD_DELTA_TO_TIME((*pdcchTime), (*pdschTime), k0Val); + ADD_DELTA_TO_TIME((*pdcchTime), (*pdschTime), k0Val, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(pdschTime->slot, cell->slotFrmtBitMap) != DL_SLOT) { @@ -323,7 +323,7 @@ bool findValidK0K1Value(SchCellCb *cell, SlotTimingInfo currTime, uint8_t ueId, k1Val = ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg.dlDataToUlAck->dlDataToUlAckList[k1Index]; } } - ADD_DELTA_TO_TIME((*pdschTime),(*pucchTime), k1Val); + ADD_DELTA_TO_TIME((*pdschTime),(*pucchTime), k1Val, cell->numSlots); #ifdef NR_TDD if(schGetSlotSymbFrmt(pucchTime->slot, cell->slotFrmtBitMap) == DL_SLOT) { @@ -678,7 +678,7 @@ uint8_t schProcDlPageAlloc(SchCellCb *cell, SlotTimingInfo currTime, Inst schIns { dlPageAlloc.cellId = currTime.cellId; - ADD_DELTA_TO_TIME(currTime, dlPageAlloc.dlPageTime, PHY_DELTA_DL + SCHED_DELTA); + ADD_DELTA_TO_TIME(currTime, dlPageAlloc.dlPageTime, PHY_DELTA_DL + SCHED_DELTA, cell->numSlots); dlPageAlloc.shortMsgInd = FALSE; pdschTime = dlPageAlloc.dlPageTime; @@ -775,18 +775,18 @@ uint8_t schProcessSlotInd(SlotTimingInfo *slotInd, Inst schInst) SchDlHqProcCb *hqP = NULLP; SchUlHqProcCb *ulHqP = NULLP; - memset(&dlSchedInfo, 0, sizeof(DlSchedInfo)); - schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue); - dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc; - dlBrdcstAlloc->ssbTrans = NO_TRANSMISSION; - dlBrdcstAlloc->sib1Trans = NO_TRANSMISSION; - cell = schCb[schInst].cells[schInst]; if(cell == NULLP) { DU_LOG("\nERROR --> SCH : Cell Does not exist"); return RFAILED; } + memset(&dlSchedInfo, 0, sizeof(DlSchedInfo)); + schCalcSlotValues(*slotInd, &dlSchedInfo.schSlotValue, cell->numSlots); + dlBrdcstAlloc = &dlSchedInfo.brdcstAlloc; + dlBrdcstAlloc->ssbTrans = NO_TRANSMISSION; + dlBrdcstAlloc->sib1Trans = NO_TRANSMISSION; + memcpy(&cell->slotInfo, slotInd, sizeof(SlotTimingInfo)); dlBrdcstAlloc->ssbIdxSupported = SSB_IDX_SUPPORTED; diff --git a/src/5gnrsch/sch_ue_mgr.c b/src/5gnrsch/sch_ue_mgr.c index aa74c06b5..b2ddafaa1 100644 --- a/src/5gnrsch/sch_ue_mgr.c +++ b/src/5gnrsch/sch_ue_mgr.c @@ -28,6 +28,9 @@ #include "mac_sch_interface.h" #include "sch.h" #include "sch_utils.h" +#ifdef NR_DRX +#include "sch_drx.h" +#endif /* local defines */ SchUeCfgRspFunc SchUeCfgRspOpts[] = @@ -256,8 +259,56 @@ uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg) { memcpy(&ueCb->ueCfg.macCellGrpCfg , &ueCfg->macCellGrpCfg, sizeof(SchMacCellGrpCfg)); ueCb->ueCfg.macCellGrpCfgPres = true; +#ifdef NR_DRX + if(ueCfg->macCellGrpCfg.drxCfgPresent == true) + { + if(ueCb->ueDrxInfoPres == false) + { + ueCb->ueDrxInfoPres = true; + /* intialize the drxUeCb */ + schInitDrxUeCb(ueCb); + + /* intialize the Dl drxHarqCb */ + for(idx =0; idxdlHqEnt.numHqPrcs; idx++) + { + schInitDrxHarqCb(&ueCb->dlHqEnt.procs[idx].dlDrxHarqCb); + } + /* intialize the Ul drxHarqCb */ + for(idx =0; idxulHqEnt.numHqPrcs; idx++) + { + schInitDrxHarqCb(&ueCb->ulHqEnt.procs[idx].ulDrxHarqCb); + } + /* convert all the drx configuration recived in ms/subms into number of slots and store into the drxUeCb */ + schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueCfg->macCellGrpCfg.drxCfg, &ueCb->drxUeCb); + /* Calculate the onduration timer and short cycle timer (if shortcycle configuration is present) as soon as we + * recived ueCfg request */ + schAddUeInOndurationList(ueCb->cellCb, ueCb, 0); + + } + else + { + /* convert all the drx configuration recived in ms/subms into number + * of slots and store into the drxUeCb */ + schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueCfg->macCellGrpCfg.drxCfg, &ueCb->drxUeCb); + + /* Recalculate/Restart timer based on their presence */ + schDrxUeReCfgTimer(ueCb->cellCb, ueCb); + } + } +#endif } +#ifdef NR_DRX + if(ueCfg->drxConfigIndicatorRelease == true) + { + if(ueCb->ueDrxInfoPres == true) + { + schDeleteUeDrxInfo(ueCb->cellCb, ueCb); + ueCb->ueDrxInfoPres = false; + } + } +#endif + if(ueCfg->phyCellGrpCfgPres == true) { memcpy(&ueCb->ueCfg.phyCellGrpCfg , &ueCfg->phyCellGrpCfg, sizeof(SchPhyCellGrpCfg)); @@ -1139,7 +1190,14 @@ void deleteSchUeCb(SchUeCb *ueCb) SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai)); } - +#ifdef NR_DRX + if(ueCb->ueDrxInfoPres) + { + /* Removing all the calculated drx configuration timer list */ + schDeleteUeDrxInfo(ueCb->cellCb, ueCb); + ueCb->ueDrxInfoPres = false; + } +#endif memset(ueCb, 0, sizeof(SchUeCb)); } } diff --git a/src/cm/du_app_mac_inf.h b/src/cm/du_app_mac_inf.h index 9020815d4..cbb8935b0 100644 --- a/src/cm/du_app_mac_inf.h +++ b/src/cm/du_app_mac_inf.h @@ -843,6 +843,7 @@ typedef struct macCellGrpCfg bool phrCfgSetupPres; /* true/false: phrCfgSetup/phrCfgRelease */ PhrCfg phrCfg; #ifdef NR_DRX + bool drxCfgPresent; DrxCfg drxCfg; #endif }MacCellGrpCfg; @@ -1300,6 +1301,9 @@ typedef struct macUeCfg LcCfg lcCfgList[MAX_NUM_LC]; UeCfgState macUeCfgState; /* InActive / Completed */ DataTransmissionAction transmissionAction; +#ifdef NR_DRX + bool drxConfigIndicatorRelease; +#endif }MacUeCfg; typedef struct nrcgi diff --git a/src/cm/mac_sch_interface.h b/src/cm/mac_sch_interface.h index 0d1ab67a9..ad34d1744 100644 --- a/src/cm/mac_sch_interface.h +++ b/src/cm/mac_sch_interface.h @@ -105,9 +105,9 @@ #define DEFAULT_K2_VALUE_FOR_SCS60 2 #define DEFAULT_K2_VALUE_FOR_SCS120 3 -#define ADD_DELTA_TO_TIME(crntTime, toFill, incr) \ +#define ADD_DELTA_TO_TIME(crntTime, toFill, incr, numOfSlot) \ { \ - if ((crntTime.slot + incr) > (MAX_SLOTS - 1)) \ + if ((crntTime.slot + incr) > (numOfSlot - 1)) \ { \ toFill.sfn = (crntTime.sfn + 1); \ } \ @@ -115,7 +115,7 @@ { \ toFill.sfn = crntTime.sfn; \ } \ - toFill.slot = (crntTime.slot + incr) % MAX_SLOTS; \ + toFill.slot = (crntTime.slot + incr) % numOfSlot; \ if (toFill.sfn >= MAX_SFN) \ { \ toFill.sfn%=MAX_SFN; \ @@ -1200,6 +1200,7 @@ typedef struct schMacCellGrpCfg SchTagCfg tagCfg; SchPhrCfg phrCfg; /* To be used only if phrCfgSetupPres is true */ #ifdef NR_DRX + bool drxCfgPresent; SchDrxCfg drxCfg; /* Drx configuration */ #endif }SchMacCellGrpCfg; @@ -1654,6 +1655,9 @@ typedef struct schUeCfg uint8_t numLcs; SchLcCfg schLcCfg[MAX_NUM_LC]; SchDataTransmission dataTransmissionInfo; +#ifdef NR_DRX + bool drxConfigIndicatorRelease; +#endif }SchUeCfg; typedef struct schUeCfgRsp diff --git a/src/cu_stub/cu_f1ap_msg_hdl.c b/src/cu_stub/cu_f1ap_msg_hdl.c index 4e2e2f5fa..435f2a242 100644 --- a/src/cu_stub/cu_f1ap_msg_hdl.c +++ b/src/cu_stub/cu_f1ap_msg_hdl.c @@ -1954,25 +1954,22 @@ void fillLongCycleOffsetValue(DrxLongCycleStartOffset *drxLongCycleStartOffset, * ****************************************************************/ void storeDrxCfgInUeCb(struct DRX_ConfigRrc *drxSetup, DrxCfg *drxCfg) { - if(drxSetup) + switch(drxSetup->drx_onDurationTimer.present) { - switch(drxSetup->drx_onDurationTimer.present) - { - case DRX_ConfigRrc__drx_onDurationTimer_PR_NOTHING: + case DRX_ConfigRrc__drx_onDurationTimer_PR_NOTHING: + break; + case DRX_ConfigRrc__drx_onDurationTimer_PR_milliSeconds: + { + drxCfg->drxOnDurationTimer.onDurationTimerValInMs = true; + drxCfg->drxOnDurationTimer.onDurationtimerValue.milliSeconds=drxSetup->drx_onDurationTimer.choice.milliSeconds; break; - case DRX_ConfigRrc__drx_onDurationTimer_PR_milliSeconds: - { - drxCfg->drxOnDurationTimer.onDurationTimerValInMs = true; - drxCfg->drxOnDurationTimer.onDurationtimerValue.milliSeconds=drxSetup->drx_onDurationTimer.choice.milliSeconds; - break; - } - case DRX_ConfigRrc__drx_onDurationTimer_PR_subMilliSeconds: - { - drxCfg->drxOnDurationTimer.onDurationTimerValInMs = false; - drxCfg->drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = drxSetup->drx_onDurationTimer.choice.subMilliSeconds; - break; - } - } + } + case DRX_ConfigRrc__drx_onDurationTimer_PR_subMilliSeconds: + { + drxCfg->drxOnDurationTimer.onDurationTimerValInMs = false; + drxCfg->drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = drxSetup->drx_onDurationTimer.choice.subMilliSeconds; + break; + } } fillLongCycleOffsetValue(&drxCfg->drxLongCycleStartOffset, &drxSetup->drx_LongCycleStartOffset); drxCfg->drxInactivityTimer = drxSetup->drx_InactivityTimer; @@ -2049,7 +2046,11 @@ uint8_t extractCellGroupConfig(CuUeCb *ueCb, CellGroupConfigRrc_t *cellGrpCfg) case MAC_CellGroupConfig__drx_ConfigRrc_PR_setup: { - storeDrxCfgInUeCb(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup, &ueCb->drxCfg); + if(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup) + { + ueCb->drxCfgPresent = true; + storeDrxCfgInUeCb(cellGrpCfg->mac_CellGroupConfig->drx_ConfigRrc->choice.setup, &ueCb->drxCfg); + } break; } @@ -10944,7 +10945,11 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt elementCnt = 3; else if((action == STOP_DATA_TX) || (action == RESTART_DATA_TX)) elementCnt = 5; - + +#ifdef NR_DRX + if(DRX_TO_BE_RELEASE && ueCb->drxCfgPresent) + elementCnt++; +#endif ueContextModifyReq->protocolIEs.list.count = elementCnt; ueContextModifyReq->protocolIEs.list.size = elementCnt*sizeof(UEContextModificationRequest_t *); @@ -11070,6 +11075,20 @@ uint8_t BuildAndSendUeContextModificationReq(uint32_t duId, void *cuUeCb, UeCtxt ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.RRCDeliveryStatusRequest = RRCDeliveryStatusRequest_true; } +#ifdef NR_DRX + if(DRX_TO_BE_RELEASE && ueCb->drxCfgPresent) + { + /* DRX Configuration Indicator */ + ieIdx++; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->id = ProtocolIE_ID_id_DRXConfigurationIndicator; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->criticality = Criticality_ignore; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.present = UEContextModificationRequestIEs__value_PR_DRXConfigurationIndicator; + ueContextModifyReq->protocolIEs.list.array[ieIdx]->value.choice.DRXConfigurationIndicator = DRXConfigurationIndicator_release; + ueCb->drxCfgPresent = false; + memset(&ueCb->drxCfg, 0, sizeof(DrxCfg)); + } +#endif + xer_fprint(stdout, &asn_DEF_F1AP_PDU, f1apMsg); /* Encode the F1SetupRequest type as APER */ diff --git a/src/cu_stub/cu_stub.h b/src/cu_stub/cu_stub.h index fed791c2b..f6cb5c70e 100644 --- a/src/cu_stub/cu_stub.h +++ b/src/cu_stub/cu_stub.h @@ -95,6 +95,12 @@ }\ } +#ifdef NR_DRX +/* Set this parameter true of false as per the need to enable or disable drx of + * a particular UE */ +#define DRX_TO_BE_RELEASE true +#endif + typedef enum { CELL_INACTIVE, @@ -304,6 +310,7 @@ typedef struct cuUeCb F1apMsgDb f1apMsgDb; UeState state; #ifdef NR_DRX + bool drxCfgPresent; DrxCfg drxCfg; #endif HandoverInfo hoInfo; diff --git a/src/du_app/du_f1ap_msg_hdl.c b/src/du_app/du_f1ap_msg_hdl.c index a44829db0..e6b933457 100644 --- a/src/du_app/du_f1ap_msg_hdl.c +++ b/src/du_app/du_f1ap_msg_hdl.c @@ -13406,62 +13406,72 @@ void freeAperDecodeF1UeContextSetupReq(UEContextSetupRequest_t *ueSetReq) { for(ieIdx = 0; ieIdx < ueSetReq->protocolIEs.list.count; ieIdx++) { - if(ueSetReq->protocolIEs.list.array[ieIdx]) - { - switch(ueSetReq->protocolIEs.list.array[ieIdx]->id) - { - case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID: - break; - case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID: - break; - case ProtocolIE_ID_id_SpCell_ID: - freeAperDecodeNrcgi(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.NRCGI); - break; - case ProtocolIE_ID_id_ServCellIndex: - break; - case ProtocolIE_ID_id_SpCellULConfigured: - break; - case ProtocolIE_ID_id_CUtoDURRCInformation: + if(ueSetReq->protocolIEs.list.array[ieIdx]) + { + switch(ueSetReq->protocolIEs.list.array[ieIdx]->id) + { + case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID: + break; + case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID: + break; + case ProtocolIE_ID_id_SpCell_ID: + freeAperDecodeNrcgi(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.NRCGI); + break; + case ProtocolIE_ID_id_ServCellIndex: + break; + case ProtocolIE_ID_id_SpCellULConfigured: + break; + case ProtocolIE_ID_id_CUtoDURRCInformation: - freeAperDecodeCuToDuInfo(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation); - break; - case ProtocolIE_ID_id_SCell_ToBeSetup_List: + freeAperDecodeCuToDuInfo(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.CUtoDURRCInformation); + break; + case ProtocolIE_ID_id_SCell_ToBeSetup_List: - freeAperDecodeSplCellList(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SCell_ToBeSetup_List); - break; - case ProtocolIE_ID_id_SRBs_ToBeSetup_List: + freeAperDecodeSplCellList(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SCell_ToBeSetup_List); + break; + case ProtocolIE_ID_id_SRBs_ToBeSetup_List: - freeAperDecodeSRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SRBs_ToBeSetup_List); - break; - case ProtocolIE_ID_id_DRBs_ToBeSetup_List: + freeAperDecodeSRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.SRBs_ToBeSetup_List); + break; + case ProtocolIE_ID_id_DRBs_ToBeSetup_List: - freeAperDecodeDRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRBs_ToBeSetup_List); - break; - case ProtocolIE_ID_id_RRCContainer: - { + freeAperDecodeDRBSetup(&ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRBs_ToBeSetup_List); + break; + case ProtocolIE_ID_id_RRCContainer: + { - if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf != NULLP) - { + if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf != NULLP) + { - free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf); - } - break; - } - case ProtocolIE_ID_id_RRCDeliveryStatusRequest: - break; - case ProtocolIE_ID_id_GNB_DU_UE_AMBR_UL: - { - if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf) - { - free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf); - } - break; - } - default: - DU_LOG("\nERROR --> F1AP: Invalid event type %ld " ,ueSetReq->protocolIEs.list.array[ieIdx]->id); - } - free(ueSetReq->protocolIEs.list.array[ieIdx]); - } + free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.RRCContainer.buf); + } + break; + } + case ProtocolIE_ID_id_RRCDeliveryStatusRequest: + break; + case ProtocolIE_ID_id_GNB_DU_UE_AMBR_UL: + { + if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf) + { + free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.BitRate.buf); + } + break; + } +#ifdef NR_DRX + case ProtocolIE_ID_id_DRXCycle: + { + if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleLength) + free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleLength); + if(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleTimer) + free(ueSetReq->protocolIEs.list.array[ieIdx]->value.choice.DRXCycle.shortDRXCycleTimer); + break; + } +#endif + default: + DU_LOG("\nERROR --> F1AP: Invalid event type %ld " ,ueSetReq->protocolIEs.list.array[ieIdx]->id); + } + free(ueSetReq->protocolIEs.list.array[ieIdx]); + } } free(ueSetReq->protocolIEs.list.array); } @@ -13840,50 +13850,52 @@ void FreeUeContextSetupRsp(F1AP_PDU_t *f1apMsg) { if(f1apMsg->choice.successfulOutcome) { - ueSetRsp = &f1apMsg->choice.successfulOutcome->value.choice.\ - UEContextSetupResponse; - if(ueSetRsp->protocolIEs.list.array) - { - for(idx = 0; idx < ueSetRsp->protocolIEs.list.count; idx++) - { - if(ueSetRsp->protocolIEs.list.array[idx]) - { - switch(ueSetRsp->protocolIEs.list.array[idx]->id) - { - case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID: - break; - case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID: - break; - case ProtocolIE_ID_id_DUtoCURRCInformation: - { - CellGroupConfig_t *cellGrpCfg = NULLP; - cellGrpCfg = &ueSetRsp->protocolIEs.list.array[idx]->value.choice.\ - DUtoCURRCInformation.cellGroupConfig; - if(cellGrpCfg->buf != NULLP) - { - DU_FREE(cellGrpCfg->buf, cellGrpCfg->size); - cellGrpCfg = NULLP; - } - break; - } - case ProtocolIE_ID_id_DRBs_Setup_List: - { + ueSetRsp = &f1apMsg->choice.successfulOutcome->value.choice.\ + UEContextSetupResponse; + if(ueSetRsp->protocolIEs.list.array) + { + for(idx = 0; idx < ueSetRsp->protocolIEs.list.count; idx++) + { + if(ueSetRsp->protocolIEs.list.array[idx]) + { + switch(ueSetRsp->protocolIEs.list.array[idx]->id) + { + case ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID: + break; + case ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID: + break; + case ProtocolIE_ID_id_C_RNTI: + break; + case ProtocolIE_ID_id_DUtoCURRCInformation: + { + CellGroupConfig_t *cellGrpCfg = NULLP; + cellGrpCfg = &ueSetRsp->protocolIEs.list.array[idx]->value.choice.\ + DUtoCURRCInformation.cellGroupConfig; + if(cellGrpCfg->buf != NULLP) + { + DU_FREE(cellGrpCfg->buf, cellGrpCfg->size); + cellGrpCfg = NULLP; + } + break; + } + case ProtocolIE_ID_id_DRBs_Setup_List: + { freeDrbSetupList(&ueSetRsp->protocolIEs.list.array[idx]->value.choice.DRBs_Setup_List); break; - } - default: - DU_LOG("\nERROR --> DUAPP: Invalid Id %ld at FreeUeContextSetupRsp()",\ - ueSetRsp->protocolIEs.list.array[idx]->id); - break; - } - DU_FREE(ueSetRsp->protocolIEs.list.array[idx],\ - sizeof(UEContextSetupResponseIEs_t)); - } - } - DU_FREE(ueSetRsp->protocolIEs.list.array, \ - ueSetRsp->protocolIEs.list.size); - } - DU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t)); + } + default: + DU_LOG("\nERROR --> DUAPP: Invalid Id %ld at FreeUeContextSetupRsp()",\ + ueSetRsp->protocolIEs.list.array[idx]->id); + break; + } + DU_FREE(ueSetRsp->protocolIEs.list.array[idx],\ + sizeof(UEContextSetupResponseIEs_t)); + } + } + DU_FREE(ueSetRsp->protocolIEs.list.array, \ + ueSetRsp->protocolIEs.list.size); + } + DU_FREE(f1apMsg->choice.successfulOutcome, sizeof(SuccessfulOutcome_t)); } DU_FREE(f1apMsg, sizeof(F1AP_PDU_t)); } @@ -16360,6 +16372,13 @@ uint8_t procF1UeContextModificationReq(F1AP_PDU_t *f1apMsg) } break; } +#ifdef NR_DRX + case ProtocolIE_ID_id_DRXConfigurationIndicator: + { + duUeCb->f1UeDb->duUeCfg.drxConfigIndicatorRelease = true; + break; + } +#endif } } diff --git a/src/du_app/du_mgr.h b/src/du_app/du_mgr.h index c2604087e..e7345f58d 100644 --- a/src/du_app/du_mgr.h +++ b/src/du_app/du_mgr.h @@ -157,6 +157,7 @@ typedef struct duUeCfg #ifdef NR_DRX bool drxCyclePres; DrxCycle drxCycle; + bool drxConfigIndicatorRelease; #endif }DuUeCfg; diff --git a/src/du_app/du_mgr_main.c b/src/du_app/du_mgr_main.c index ba89f0be0..0d171a510 100644 --- a/src/du_app/du_mgr_main.c +++ b/src/du_app/du_mgr_main.c @@ -548,7 +548,7 @@ uint8_t commonInit() DU_LOG("\nERROR --> DU_APP : System Task creation for DU APP failed"); return RFAILED; } - ODU_SET_THREAD_AFFINITY(&du_app_stsk, SS_AFFINITY_MODE_EXCL, 16, 0); + //ODU_SET_THREAD_AFFINITY(&du_app_stsk, SS_AFFINITY_MODE_EXCL, 16, 0); /* system task for EGTP */ if(ODU_CREATE_TASK(PRIOR0, &egtp_stsk) != ROK) @@ -556,7 +556,7 @@ uint8_t commonInit() DU_LOG("\nERROR --> DU_APP : System Task creation for EGTP failed"); return RFAILED; } - ODU_SET_THREAD_AFFINITY(&egtp_stsk, SS_AFFINITY_MODE_EXCL, 27, 0); + //ODU_SET_THREAD_AFFINITY(&egtp_stsk, SS_AFFINITY_MODE_EXCL, 27, 0); /* system task for RLC_DL and MAC */ if(ODU_CREATE_TASK(PRIOR0, &rlc_mac_cl_stsk) != ROK) @@ -566,7 +566,7 @@ uint8_t commonInit() } pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - ODU_SET_THREAD_AFFINITY(&rlc_mac_cl_stsk, SS_AFFINITY_MODE_EXCL, 18, 0); + //ODU_SET_THREAD_AFFINITY(&rlc_mac_cl_stsk, SS_AFFINITY_MODE_EXCL, 18, 0); /* system task for RLC UL */ if(ODU_CREATE_TASK(PRIOR1, &rlc_ul_stsk) != ROK) @@ -574,7 +574,7 @@ uint8_t commonInit() DU_LOG("\nERROR --> DU_APP : System Task creation for RLC UL failed"); return RFAILED; } - ODU_SET_THREAD_AFFINITY(&rlc_ul_stsk, SS_AFFINITY_MODE_EXCL, 22, 0); + //ODU_SET_THREAD_AFFINITY(&rlc_ul_stsk, SS_AFFINITY_MODE_EXCL, 22, 0); /* system task for SCTP receiver thread */ if(ODU_CREATE_TASK(PRIOR0, &sctp_stsk) != ROK) @@ -582,7 +582,7 @@ uint8_t commonInit() DU_LOG("\nERROR --> DU_APP : System Task creation for SCTP failed"); return RFAILED; } - ODU_SET_THREAD_AFFINITY(&sctp_stsk, SS_AFFINITY_MODE_EXCL, 25, 0); + //ODU_SET_THREAD_AFFINITY(&sctp_stsk, SS_AFFINITY_MODE_EXCL, 25, 0); /* system task for lower-mac receiver thread */ if(ODU_CREATE_TASK(PRIOR0, &lwr_mac_stsk) != ROK) @@ -590,7 +590,7 @@ uint8_t commonInit() DU_LOG("\nERROR --> DU_APP : System Task creation for Lower MAC failed"); return RFAILED; } - ODU_SET_THREAD_AFFINITY(&lwr_mac_stsk, SS_AFFINITY_MODE_EXCL, 21, 0); + //ODU_SET_THREAD_AFFINITY(&lwr_mac_stsk, SS_AFFINITY_MODE_EXCL, 21, 0); #ifndef INTEL_WLS_MEM /* system task for phy stub's slot indication generator thread */ diff --git a/src/du_app/du_ue_mgr.c b/src/du_app/du_ue_mgr.c index b77b231a8..d55defdc5 100644 --- a/src/du_app/du_ue_mgr.c +++ b/src/du_app/du_ue_mgr.c @@ -1283,6 +1283,9 @@ uint8_t fillMacUeCfg(uint16_t cellId, uint8_t gnbDuUef1apId, uint16_t crnti, DuU } #ifdef NR_DRX + + macUeCfg->drxConfigIndicatorRelease = ueCfgDb->drxConfigIndicatorRelease; + if(ueCfgDb->drxCyclePres) { macUeCfg->macCellGrpCfg.drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetChoice = ueCfgDb->drxCycle.drxLongCycleLength; diff --git a/src/phy_stub/phy_stub_msg_hdl.c b/src/phy_stub/phy_stub_msg_hdl.c index b88a260d3..ab3607a27 100644 --- a/src/phy_stub/phy_stub_msg_hdl.c +++ b/src/phy_stub/phy_stub_msg_hdl.c @@ -1203,7 +1203,7 @@ S16 l1HdlUlTtiReq(uint16_t msgLen, void *msg) memset(&ulTtiSlotInd, 0, sizeof(fapi_ul_tti_req_t)); ulTtiSlotInd.slot = ulTtiReq->slot; ulTtiSlotInd.sfn = ulTtiReq->sfn; - ADD_DELTA_TO_TIME(ulTtiSlotInd, ulTtiSlotInd, SLOT_DELAY); + ADD_DELTA_TO_TIME(ulTtiSlotInd, ulTtiSlotInd, SLOT_DELAY, MAX_SLOTS); l1BuildAndSendUciInd(ulTtiSlotInd.slot, ulTtiSlotInd.sfn, ulTtiReq->pdus[numPdus-1].pdu.pucch_pdu); } numPdus--; -- 2.16.6