{
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;
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)
{
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)
struct macCellCb
{
uint16_t cellId;
+ uint16_t numOfSlots;
CellState state;
uint16_t crntiMap;
MacRaCbInfo macRaCb[MAX_NUM_UE];
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, \
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;
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; ueIdx<MAX_NUM_UE; ueIdx++)
#ifdef NR_DRX
/* Copy Drx configuration */
-
+ macCellGrpCfg->drxCfgPresent = true;
macCellGrpCfg->drxCfg.drxOnDurationTimer.onDurationTimerValInMs = macCellGrp.drxCfg.drxOnDurationTimer.onDurationTimerValInMs;
if(!macCellGrp.drxCfg.drxOnDurationTimer.onDurationTimerValInMs)
macCellGrpCfg->drxCfg.drxOnDurationTimer.onDurationtimerValue.subMilliSeconds = \
DU_LOG("\nERROR --> MAC : Failed to copy LCs at fillSchUeCfg()");
return ret;
}
+
+#ifdef NR_DRX
+ schUeCfg->drxConfigIndicatorRelease = ueCfg->drxConfigIndicatorRelease;;
+#endif
+
return ret;
}
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);
#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;
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 */
uint8_t dmrsMappingType;
uint8_t nrOfDmrsSymbols;
uint8_t dmrsAddPos;
+#ifdef NR_DRX
+ SchDrxHarqCb ulDrxHarqCb;
+#endif
}SchUlHqProcCb;
struct schDlHqProcCb
uint8_t k1;
SchLcPrbEstimate dlLcPrbEst; /*DL PRB Alloc Estimate among different LC*/
CmLList dlHqProcLink;
+#ifdef NR_DRX
+ SchDrxHarqCb dlDrxHarqCb;
+#endif
};
struct schUlHqEnt
{
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
SchHqUlMap **hqUlmap;
CmLListCp ulRetxHqList;
CmLListCp dlRetxHqList;
+#ifdef NR_DRX
+ bool ueDrxInfoPres;
+ SchDrxUeCb drxUeCb;
+#endif
}SchUeCb;
/**
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.
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 */
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;
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;
/* 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;
}
/* 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
}
/* 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;
--- /dev/null
+
+/*******************************************************************************
+################################################################################
+# 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; idx<numHqPrcs; idx++)
+ {
+ procs = &dlHqEnt->procs[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; idx<numHqPrcs; idx++)
+ {
+ procs = &ulHqEnt->procs[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
+ **********************************************************************/
--- /dev/null
+/*******************************************************************************
+################################################################################
+# 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
+ **********************************************************************/
}
/* 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 */
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. */
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;
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;
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 */
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)
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;
}
/**********************************************************************
End of file
- **********************************************************************/
\ No newline at end of file
+ **********************************************************************/
* RFAILED - failure
*
* ****************************************************************/
-void schCalcSlotValues(SlotTimingInfo slotInd, SchSlotValue *schSlotValue)
+void schCalcSlotValues(SlotTimingInfo slotInd, SchSlotValue *schSlotValue, uint16_t numOfSlots)
{
/****************************************************************
* PHY_DELTA - the physical layer delta *
* 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);
}
/*******************************************************************
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)
{
}
}
- 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)
{
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)
{
{
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;
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;
#include "mac_sch_interface.h"
#include "sch.h"
#include "sch_utils.h"
+#ifdef NR_DRX
+#include "sch_drx.h"
+#endif
/* local defines */
SchUeCfgRspFunc SchUeCfgRspOpts[] =
{
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; idx<ueCb->dlHqEnt.numHqPrcs; idx++)
+ {
+ schInitDrxHarqCb(&ueCb->dlHqEnt.procs[idx].dlDrxHarqCb);
+ }
+ /* intialize the Ul drxHarqCb */
+ for(idx =0; idx<ueCb->ulHqEnt.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));
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));
}
}
bool phrCfgSetupPres; /* true/false: phrCfgSetup/phrCfgRelease */
PhrCfg phrCfg;
#ifdef NR_DRX
+ bool drxCfgPresent;
DrxCfg drxCfg;
#endif
}MacCellGrpCfg;
LcCfg lcCfgList[MAX_NUM_LC];
UeCfgState macUeCfgState; /* InActive / Completed */
DataTransmissionAction transmissionAction;
+#ifdef NR_DRX
+ bool drxConfigIndicatorRelease;
+#endif
}MacUeCfg;
typedef struct nrcgi
#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); \
} \
{ \
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; \
SchTagCfg tagCfg;
SchPhrCfg phrCfg; /* To be used only if phrCfgSetupPres is true */
#ifdef NR_DRX
+ bool drxCfgPresent;
SchDrxCfg drxCfg; /* Drx configuration */
#endif
}SchMacCellGrpCfg;
uint8_t numLcs;
SchLcCfg schLcCfg[MAX_NUM_LC];
SchDataTransmission dataTransmissionInfo;
+#ifdef NR_DRX
+ bool drxConfigIndicatorRelease;
+#endif
}SchUeCfg;
typedef struct schUeCfgRsp
* ****************************************************************/
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;
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;
}
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 *);
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 */
}\
}
+#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,
F1apMsgDb f1apMsgDb;
UeState state;
#ifdef NR_DRX
+ bool drxCfgPresent;
DrxCfg drxCfg;
#endif
HandoverInfo hoInfo;
{
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);
}
{
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));
}
}
break;
}
+#ifdef NR_DRX
+ case ProtocolIE_ID_id_DRXConfigurationIndicator:
+ {
+ duUeCb->f1UeDb->duUeCfg.drxConfigIndicatorRelease = true;
+ break;
+ }
+#endif
}
}
#ifdef NR_DRX
bool drxCyclePres;
DrxCycle drxCycle;
+ bool drxConfigIndicatorRelease;
#endif
}DuUeCfg;
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)
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)
}
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)
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)
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)
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 */
}
#ifdef NR_DRX
+
+ macUeCfg->drxConfigIndicatorRelease = ueCfgDb->drxConfigIndicatorRelease;
+
if(ueCfgDb->drxCyclePres)
{
macUeCfg->macCellGrpCfg.drxCfg.drxLongCycleStartOffset.drxLongCycleStartOffsetChoice = ueCfgDb->drxCycle.drxLongCycleLength;
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--;