[Epic-ID: ODUHIGH-462][Task-ID: ODUHIGH-472] Handling of drx timer in SCH [storing... 31/9531/5
authorlal.harshita <Harshita.Lal@radisys.com>
Tue, 8 Nov 2022 13:45:54 +0000 (19:15 +0530)
committerlal.harshita <Harshita.Lal@radisys.com>
Mon, 14 Nov 2022 14:40:52 +0000 (20:10 +0530)
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
Change-Id: I8f24fb565665f55d3e81a480f657bbf31e09693c
Signed-off-by: lal.harshita <Harshita.Lal@radisys.com>
24 files changed:
src/5gnrmac/lwr_mac_fsm.c
src/5gnrmac/mac.h
src/5gnrmac/mac_cfg_hdl.c
src/5gnrmac/mac_rach.c
src/5gnrmac/mac_slot_ind.c
src/5gnrmac/mac_ue_mgr.c
src/5gnrsch/sch.c
src/5gnrsch/sch.h
src/5gnrsch/sch_common.c
src/5gnrsch/sch_drx.c [new file with mode: 0644]
src/5gnrsch/sch_drx.h [new file with mode: 0644]
src/5gnrsch/sch_rach.c
src/5gnrsch/sch_rr.c
src/5gnrsch/sch_slot_ind.c
src/5gnrsch/sch_ue_mgr.c
src/cm/du_app_mac_inf.h
src/cm/mac_sch_interface.h
src/cu_stub/cu_f1ap_msg_hdl.c
src/cu_stub/cu_stub.h
src/du_app/du_f1ap_msg_hdl.c
src/du_app/du_mgr.h
src/du_app/du_mgr_main.c
src/du_app/du_ue_mgr.c
src/phy_stub/phy_stub_msg_hdl.c

index d384c3d..cdf66a7 100644 (file)
@@ -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)
index 6115c67..534b80e 100644 (file)
@@ -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];
index f354fa4..6d94f0e 100644 (file)
@@ -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, \
index cc59d5c..5190ea8 100644 (file)
@@ -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;
index 2492f2a..7c42b10 100644 (file)
@@ -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; ueIdx<MAX_NUM_UE; ueIdx++)
index b83130e..fda65cf 100644 (file)
@@ -138,7 +138,7 @@ uint8_t fillMacCellGroupCfg(MacCellGrpCfg macCellGrp, SchMacCellGrpCfg  *macCell
 
 #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 = \
@@ -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;
 }
 
index 3e485c4..1bd9343 100644 (file)
@@ -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);
index 4281ef8..89eb270 100644 (file)
 #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;
 
 
index bc5ca0f..c441a0c 100644 (file)
@@ -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 (file)
index 0000000..ff0844d
--- /dev/null
@@ -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; 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
+ **********************************************************************/
diff --git a/src/5gnrsch/sch_drx.h b/src/5gnrsch/sch_drx.h
new file mode 100644 (file)
index 0000000..c19b710
--- /dev/null
@@ -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
+ **********************************************************************/
index 8a81745..315ac6e 100644 (file)
@@ -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 */
index a6c52e2..64ae921 100644 (file)
@@ -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
+ **********************************************************************/
index 12a387c..3bcff2e 100644 (file)
@@ -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;
 
index aa74c06..b2ddafa 100644 (file)
@@ -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; 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));
@@ -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));
    }
 }
index 9020815..cbb8935 100644 (file)
@@ -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
index 0d1ab67..ad34d17 100644 (file)
 #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;                                 \
@@ -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
index 4e2e2f5..435f2a2 100644 (file)
@@ -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 */
index fed791c..f6cb5c7 100644 (file)
    }\
 }
 
+#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;
index a44829d..e6b9334 100644 (file)
@@ -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
               
       }
    }
index c260408..e7345f5 100644 (file)
@@ -157,6 +157,7 @@ typedef struct duUeCfg
 #ifdef NR_DRX
    bool     drxCyclePres;
    DrxCycle drxCycle;
+   bool     drxConfigIndicatorRelease;
 #endif
 }DuUeCfg;
 
index ba89f0b..0d171a5 100644 (file)
@@ -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 */
index b77b231..d55defd 100644 (file)
@@ -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;
index b88a260..ab3607a 100644 (file)
@@ -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--;