[EPIC-ID: ODUHIGH-488][TASK-ID: ODUHIGH-494]SCH framework update to support different...
[o-du/l2.git] / src / 5gnrsch / sch_ue_mgr.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17  *******************************************************************************/
18 /* This file contains UE management handling functionality for SCH */
19
20 #include "common_def.h"
21 #include "tfu.h"
22 #include "lrg.h"
23
24 #include "tfu.x"
25 #include "lrg.x"
26 #include "du_log.h"
27 #include "du_app_mac_inf.h"
28 #include "mac_sch_interface.h"
29 #include "sch.h"
30 #include "sch_utils.h"
31 #ifdef NR_DRX 
32 #include "sch_drx.h"
33 #endif
34
35 /*******************************************************************
36  *
37  * @brief Fill and send UE cfg response to MAC
38  *
39  * @details
40  *
41  *    Function : SchSendUeCfgRspToMac
42  *
43  *    Functionality: Fill and send UE cfg response to MAC
44  *
45  * @params[in] 
46  * @return ROK     - success
47  *         RFAILED - failure
48  *
49  * ****************************************************************/
50 void SchSendUeCfgRspToMac(SchUeCfgReq *ueCfg, Inst inst,\
51       SchMacRsp result, SchUeCfgRsp *cfgRsp)
52 {
53    Pst rspPst;
54
55    cfgRsp->cellId = ueCfg->cellId;
56    cfgRsp->ueId = ueCfg->ueId;
57    cfgRsp->crnti = ueCfg->crnti;
58    cfgRsp->rsp = result;   
59
60    /* Filling response post */
61    memset(&rspPst, 0, sizeof(Pst));
62    FILL_PST_SCH_TO_MAC(rspPst, inst);
63    rspPst.event = EVENT_UE_CONFIG_RSP_TO_MAC;
64    DU_LOG("\nINFO  -->  SCH :  Sending UE Config response to MAC");
65    MacMessageRouter(&rspPst, (void *)cfgRsp);
66 }
67
68 /*******************************************************************
69  *
70  * @brief Fill and send UE Recfg response to MAC
71  *
72  * @details
73  *
74  *    Function : SchSendUeRecfgRspToMac
75  *
76  *    Functionality: Fill and send UE Recfg response to MAC
77  *
78  * @params[in] 
79  * @return ROK     - success
80  *         RFAILED - failure
81  *
82  * ****************************************************************/
83 void SchSendUeRecfgRspToMac(SchUeRecfgReq *ueRecfgReq, Inst inst,\
84       SchMacRsp result, SchUeRecfgRsp *reCfgRsp)
85 {
86    Pst rspPst;
87
88    reCfgRsp->cellId = ueRecfgReq->cellId;
89    reCfgRsp->ueId = ueRecfgReq->ueId;
90    reCfgRsp->crnti = ueRecfgReq->crnti;
91    reCfgRsp->rsp = result;   
92
93    /* Filling response post */
94    memset(&rspPst, 0, sizeof(Pst));
95    FILL_PST_SCH_TO_MAC(rspPst, inst);
96    rspPst.event = EVENT_UE_RECONFIG_RSP_TO_MAC;
97    DU_LOG("\nINFO  -->  SCH :  Sending UE Reconfig response to MAC");
98     MacMessageRouter(&rspPst, (void *)reCfgRsp);
99 }
100
101 /*******************************************************************
102  
103  *
104  * @brief Function to fill Dl Lc Context in SCH Ue Cb
105  *
106  * @details
107  *
108  *    Function : fillSchDlLcCtxt
109  *
110  *    Functionality: Function to fill Dl Lc Context in SCH Ue Cb
111  *
112  * @params[in] SchDlLcCtxt pointer,
113  *             SchLcCfg pointer
114  * @return void
115  *
116  * ****************************************************************/
117
118 void fillSchDlLcCtxt(SchDlLcCtxt *ueCbLcCfg, SchLcCfg *lcCfg)
119 {
120    ueCbLcCfg->lcId = lcCfg->lcId;
121    ueCbLcCfg->lcp = lcCfg->dlLcCfg.lcp;
122    ueCbLcCfg->lcState = SCH_LC_STATE_ACTIVE;
123    ueCbLcCfg->bo = 0;
124    if(lcCfg->drbQos)
125    {
126      ueCbLcCfg->pduSessionId = lcCfg->drbQos->pduSessionId;
127    }
128    if(lcCfg->snssai)
129    {
130      if(ueCbLcCfg->snssai == NULLP)/*In CONFIG_MOD case, no need to allocate SNSSAI memory*/
131      {
132         SCH_ALLOC(ueCbLcCfg->snssai, sizeof(Snssai));
133      }
134      memcpy(ueCbLcCfg->snssai, lcCfg->snssai,sizeof(Snssai));
135    }
136 }
137
138 /*******************************************************************
139  *
140  * @brief Function to fill Ul Lc Context in SCH Ue Cb
141  *
142  * @details
143  *
144  *    Function : fillSchUlLcCtxt
145  *
146  *    Functionality: Function to fill Ul Lc Context in SCH Ue Cb
147  *
148  * @params[in] SchUlLcCtxt pointer,
149  *             SchLcCfg pointer
150  * @return void
151  *
152  * ****************************************************************/
153
154 void fillSchUlLcCtxt(SchUlLcCtxt *ueCbLcCfg, SchLcCfg *lcCfg)
155 {
156    ueCbLcCfg->lcId = lcCfg->lcId;
157    ueCbLcCfg->lcState = SCH_LC_STATE_ACTIVE;
158    ueCbLcCfg->priority = lcCfg->ulLcCfg.priority;
159    ueCbLcCfg->lcGroup = lcCfg->ulLcCfg.lcGroup;
160    ueCbLcCfg->schReqId = lcCfg->ulLcCfg.schReqId;
161    ueCbLcCfg->pbr     = lcCfg->ulLcCfg.pbr;
162    ueCbLcCfg->bsd     = lcCfg->ulLcCfg.bsd;
163
164    if(lcCfg->drbQos)
165    {
166       ueCbLcCfg->pduSessionId = lcCfg->drbQos->pduSessionId;
167    }
168    if(lcCfg->snssai)
169    {
170      /*In CONFIG_MOD case, no need to allocate SNSSAI memory again*/
171      if(ueCbLcCfg->snssai == NULLP)
172      {
173         SCH_ALLOC(ueCbLcCfg->snssai, sizeof(Snssai));
174      }
175      memcpy(ueCbLcCfg->snssai, lcCfg->snssai,sizeof(Snssai));
176    }
177 }
178
179 /*******************************************************************
180  *
181  * @brief Function to update/allocate dedLC Info
182  *
183  * @details
184  *
185  *    Function : updateDedLcInfo
186  *
187  *    Functionality: Function to fill DLDedLcInfo
188  *
189  * @params[arg] scheduler instance,
190  *              snssai pointer,
191  *              SchRrmPolicy pointer,
192  *              SchLcPrbEstimate pointer , It will be filled
193  *              isDedicated pointer,(Address of isDedicated flag in LC Context)
194  *
195  * @return ROK      >> This LC is part of RRM MemberList.
196  *         RFAILED  >> FATAL Error
197  *         ROKIGNORE >> This LC is not part of this RRM MemberList 
198  *
199  * ****************************************************************/
200
201 uint8_t updateDedLcInfo(Inst inst, Snssai *snssai, uint16_t *rsvdDedicatedPRB, bool *isDedicated)
202 {
203    uint8_t sliceCfgIdx =0;
204    SchSliceCfg sliceCfg = schCb[inst].sliceCfg;
205
206    if(sliceCfg.numOfSliceConfigured)
207    {
208       for(sliceCfgIdx = 0; sliceCfgIdx<sliceCfg.numOfSliceConfigured; sliceCfgIdx++)
209       {
210          if(memcmp(snssai, &(sliceCfg.listOfConfirguration[sliceCfgIdx]->snssai), sizeof(Snssai)) == 0)
211          {
212             if(sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo)
213             {
214                /*Updating latest RrmPolicy*/
215                 *rsvdDedicatedPRB = \
216                (uint16_t)(((sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo->policyDedicatedRatio)*(MAX_NUM_RB))/100);
217                *isDedicated = TRUE;
218                DU_LOG("\nINFO  -->  SCH : Updated RRM policy, reservedPOOL:%d",*rsvdDedicatedPRB);
219             }
220          }
221       }
222       /*case: This LcCtxt  is either a Default LC or this LC is part of someother RRM_MemberList*/
223       if(*isDedicated != TRUE) 
224       {
225          DU_LOG("\nINFO  -->  SCH : This SNSSAI is not a part of this RRMPolicy");
226       }
227    }
228    return ROK;   
229 }
230
231 /*******************************************************************
232  *
233  * @brief Function to fill SpCellCfg in SchUeCb From SchUeCfg Req
234  *
235  * @details
236  *
237  *    Function : fillSpCellInSchCb
238  *
239  *    Functionality: Function to fill SpCellCfg in SchUeCb
240  *
241  * @params[in] Scheduler instance,
242  *             SchUeCb pointer,
243  *             SchUeCfg pointer
244  * @return ROK/RFAILED
245  *
246  * ****************************************************************/
247
248 void fillSpCellInSchCb(SchSpCellRecfg *destSpCellCfg, SchSpCellCfg *srcSpCellCfg)
249 {
250    destSpCellCfg->servCellIdx = srcSpCellCfg->servCellIdx;
251    memcpy(&destSpCellCfg->servCellRecfg.initDlBwp, &srcSpCellCfg->servCellCfg.initDlBwp, sizeof(SchInitalDlBwp));
252    destSpCellCfg->servCellRecfg.numDlBwpToAddOrMod =  srcSpCellCfg->servCellCfg.numDlBwpToAdd;
253    if(destSpCellCfg->servCellRecfg.numDlBwpToAddOrMod > 0)
254    {
255       memcpy(destSpCellCfg->servCellRecfg.dlBwpToAddOrModList, srcSpCellCfg->servCellCfg.dlBwpToAddList,\
256               (sizeof(SchDlBwpInfo) * srcSpCellCfg->servCellCfg.numDlBwpToAdd));
257    }
258    destSpCellCfg->servCellRecfg.firstActvDlBwpId = srcSpCellCfg->servCellCfg.firstActvDlBwpId;
259    destSpCellCfg->servCellRecfg.defaultDlBwpId = srcSpCellCfg->servCellCfg.defaultDlBwpId;
260    destSpCellCfg->servCellRecfg.bwpInactivityTmr = srcSpCellCfg->servCellCfg.bwpInactivityTmr;
261    memcpy(&destSpCellCfg->servCellRecfg.pdschServCellCfg, &srcSpCellCfg->servCellCfg.pdschServCellCfg, sizeof(SchPdschServCellCfg));
262    memcpy(&destSpCellCfg->servCellRecfg.initUlBwp, &srcSpCellCfg->servCellCfg.initUlBwp, sizeof(SchInitialUlBwp));
263    
264    destSpCellCfg->servCellRecfg.numDlBwpToAddOrMod =  srcSpCellCfg->servCellCfg.numDlBwpToAdd;
265    if(destSpCellCfg->servCellRecfg.numDlBwpToAddOrMod > 0)
266    {
267       memcpy(destSpCellCfg->servCellRecfg.ulBwpToAddOrModList, srcSpCellCfg->servCellCfg.ulBwpToAddList,\
268               (sizeof(SchUlBwpInfo) * srcSpCellCfg->servCellCfg.numUlBwpToAdd));
269    }
270    destSpCellCfg->servCellRecfg.firstActvUlBwpId = srcSpCellCfg->servCellCfg.firstActvUlBwpId;
271    return;
272 }
273
274 /*******************************************************************
275  *
276  * @brief Function to fill SchUeCb From UeCfg Req
277  *
278  * @details
279  *
280  *    Function : fillSchUeCbFrmCfgReq
281  *
282  *    Functionality: Function to fill SchUeCb
283  *
284  * @params[in] Scheduler instance,
285  *             SchUeCb pointer,
286  *             SchUeCfg pointer
287  * @return ROK/RFAILED
288  *
289  * ****************************************************************/
290
291 uint8_t fillSchUeCbFrmCfgReq(Inst inst, SchUeCb *ueCb, SchUeCfgReq *ueCfg)
292 {
293    uint8_t   lcIdx, ueLcIdx, idx;
294    uint8_t   freqDomainResource[FREQ_DOM_RSRC_SIZE] = {0};
295    SchPdschCfgCmn pdschCfg;
296    SchPucchDlDataToUlAck *dlDataToUlAck;
297    uint8_t retDL = ROK, retUL = ROK;
298    bool isLcIdValid = FALSE;
299
300    ueCb->ueCfg.cellId = ueCfg->cellId;
301    ueCb->ueCfg.ueId = ueCfg->ueId;
302    ueCb->ueCfg.crnti = ueCfg->crnti;
303    if(ueCfg->macCellGrpCfgPres == true)
304    {
305       memcpy(&ueCb->ueCfg.macCellGrpCfg , &ueCfg->macCellGrpCfg, sizeof(SchMacCellGrpCfg)); 
306       ueCb->ueCfg.macCellGrpCfgPres = true;
307 #ifdef NR_DRX
308       if(ueCfg->macCellGrpCfg.drxCfgPresent == true)
309       {
310          if(ueCb->ueDrxInfoPres == false)
311          {
312             ueCb->ueDrxInfoPres = true;
313             /* intialize the drxUeCb */
314             schInitDrxUeCb(ueCb);
315
316             /* intialize the Dl drxHarqCb */
317             for(idx =0; idx<ueCb->dlHqEnt.numHqPrcs; idx++)
318             {
319                schInitDrxHarqCb(&ueCb->dlHqEnt.procs[idx].dlDrxHarqCb);
320             }
321             /* intialize the Ul drxHarqCb */
322             for(idx =0; idx<ueCb->ulHqEnt.numHqPrcs; idx++)
323             {
324                schInitDrxHarqCb(&ueCb->ulHqEnt.procs[idx].ulDrxHarqCb);
325             }
326             /* convert all the drx configuration recived in ms/subms into number of slots and store into the drxUeCb */
327             schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueCfg->macCellGrpCfg.drxCfg, &ueCb->drxUeCb);
328             /* Calculate the onduration timer and short cycle timer (if shortcycle configuration is present) as soon as we 
329              * recived ueCfg request */
330             schAddUeInOndurationList(ueCb->cellCb, ueCb, 0);
331
332          }
333          else
334          {
335             /* convert all the drx configuration recived in ms/subms into number
336              * of slots and store into the drxUeCb */
337             schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueCfg->macCellGrpCfg.drxCfg, &ueCb->drxUeCb);
338
339             /* Recalculate/Restart timer based on their presence */
340             schDrxUeReCfgTimer(ueCb->cellCb, ueCb);
341          }
342       }
343 #endif
344    }
345
346    if(ueCfg->phyCellGrpCfgPres == true)
347    {
348       memcpy(&ueCb->ueCfg.phyCellGrpCfg ,  &ueCfg->phyCellGrpCfg, sizeof(SchPhyCellGrpCfg));
349       ueCb->ueCfg.phyCellGrpCfgPres = true;
350    }
351
352    if(ueCfg->spCellCfgPres == true)
353    {
354       if(ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfgPres == true)
355       {
356          if(ueCb->ueCfg.spCellCfgPres && ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfgPres == true)
357          {
358             for(idx = 0; idx < ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.numTimeDomRsrcAlloc; idx++)
359             {
360                if(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0 && ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0)
361                {
362                   SCH_FREE(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0, sizeof(uint8_t));  
363                }
364             }
365          }
366       }
367       fillSpCellInSchCb(&ueCb->ueCfg.spCellCfg, &ueCfg->spCellCfg);
368
369       covertFreqDomRsrcMapToIAPIFormat(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc,\
370             freqDomainResource);
371       memset(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, 0, FREQ_DOM_RSRC_SIZE);
372       memcpy(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, freqDomainResource, FREQ_DOM_RSRC_SIZE);
373
374       ueCb->ueCfg.spCellCfgPres = true;
375       dlDataToUlAck = ueCfg->spCellCfg.servCellCfg.initUlBwp.pucchCfg.dlDataToUlAck;
376       if(ueCb->cellCb)
377       {
378          if(dlDataToUlAck)
379          {
380             BuildK0K1Table(ueCb->cellCb, &ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.k0K1InfoTbl, false, pdschCfg,\
381                   ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg, dlDataToUlAck->dlDataToUlAckListCount,\
382                   dlDataToUlAck->dlDataToUlAckList);
383             ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.k0K1TblPrsnt = true;
384             BuildK2InfoTable(ueCb->cellCb, ueCfg->spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList,\
385                   ueCfg->spCellCfg.servCellCfg.initUlBwp.puschCfg.numTimeDomRsrcAlloc,\
386                   NULLP, &ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.k2InfoTbl);
387             ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.k2TblPrsnt = true;
388          }
389       }
390    }
391
392    if(ueCfg->ambrCfg)
393    {
394       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
395       ueCb->ueCfg.ambrCfg =  ueCfg->ambrCfg;
396    }
397    memcpy(&ueCb->ueCfg.dlModInfo,  &ueCfg->dlModInfo , sizeof(SchModulationInfo));
398    memcpy(&ueCb->ueCfg.ulModInfo,  &ueCfg->ulModInfo , sizeof(SchModulationInfo));
399    //Updating SchUlCb and SchDlCb DB in SchUeCb
400    for(lcIdx = 0; lcIdx < ueCfg->numLcsToAdd; lcIdx++)
401    {
402       isLcIdValid = FALSE; /*Re-Initializing*/
403
404       ueLcIdx = ueCfg->schLcCfg[lcIdx].lcId;
405       CHECK_LCID(ueLcIdx, isLcIdValid);
406       if(isLcIdValid == FALSE)
407       {
408          DU_LOG("ERROR --> SCH: LCID:%d is not Valid",ueLcIdx);
409          continue;
410       }
411       fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
412       fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
413
414       /*Checking whether this LC belong to Dedicated S-NSSAI 
415        * and Create the Dedicated LC List & Update the Reserve PRB number*/
416       if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP)
417       {
418          retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
419                &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated));
420       }
421       if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP)
422       {
423          retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
424                &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated));
425       }
426
427       if(retUL == RFAILED  || retDL == RFAILED)/*FATAL error*/
428       {
429          DU_LOG("\nERROR  -->  SCH : Failure in updateDedLcInfo");
430          return RFAILED;
431       }
432       SCH_FREE(ueCfg->schLcCfg[lcIdx].drbQos, sizeof(SchDrbQosInfo));
433       SCH_FREE(ueCfg->schLcCfg[lcIdx].snssai, sizeof(Snssai));
434
435    }/* End of outer for loop */
436    return ROK;
437 }
438
439 /*******************************************************************
440  *
441  * @brief Function to fill SchUeCb From UeReconfig Req
442  *
443  * @details
444  *
445  *    Function : fillSchUeCbFrmRecfgReq
446  *
447  *    Functionality: Function to fill SchUeCb
448  *
449  * @params[in] Scheduler instance,
450  *             SchUeCb pointer,
451  *             SchUeCfg pointer
452  * @return ROK/RFAILED
453  *
454  * ****************************************************************/
455
456 uint8_t fillSchUeCbFrmRecfgReq(Inst inst, SchUeCb *ueCb, SchUeRecfgReq *ueRecfg)
457 {
458    uint8_t   lcIdx, ueLcIdx, idx;
459    uint8_t   freqDomainResource[FREQ_DOM_RSRC_SIZE] = {0};
460    SchPdschCfgCmn pdschCfg;
461    SchPucchDlDataToUlAck *dlDataToUlAck;
462    uint8_t retDL = ROK, retUL = ROK;
463    bool isLcIdValid = FALSE;
464
465
466    ueCb->ueCfg.cellId = ueRecfg->cellId;
467    ueCb->ueCfg.ueId = ueRecfg->ueId;
468    ueCb->ueCfg.crnti = ueRecfg->crnti;
469    ueCb->ueCfg.dataTransmissionAction = ueRecfg->dataTransmissionInfo;
470    if(ueRecfg->macCellGrpRecfgPres == true)
471    {
472       memcpy(&ueCb->ueCfg.macCellGrpCfg , &ueRecfg->macCellGrpRecfg, sizeof(SchMacCellGrpCfg)); 
473       ueCb->ueCfg.macCellGrpCfgPres = true;
474 #ifdef NR_DRX
475       if(ueRecfg->macCellGrpRecfg.drxCfgPresent == true)
476       {
477          if(ueCb->ueDrxInfoPres == false)
478          {
479             ueCb->ueDrxInfoPres = true;
480             /* intialize the drxUeCb */
481             schInitDrxUeCb(ueCb);
482
483             /* intialize the Dl drxHarqCb */
484             for(idx =0; idx<ueCb->dlHqEnt.numHqPrcs; idx++)
485             {
486                schInitDrxHarqCb(&ueCb->dlHqEnt.procs[idx].dlDrxHarqCb);
487             }
488             /* intialize the Ul drxHarqCb */
489             for(idx =0; idx<ueCb->ulHqEnt.numHqPrcs; idx++)
490             {
491                schInitDrxHarqCb(&ueCb->ulHqEnt.procs[idx].ulDrxHarqCb);
492             }
493             /* convert all the drx configuration recived in ms/subms into number of slots and store into the drxUeCb */
494             schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueRecfg->macCellGrpRecfg.drxCfg, &ueCb->drxUeCb);
495             /* Calculate the onduration timer and short cycle timer (if shortcycle configuration is present) as soon as we 
496              * recived ueCfg request */
497             schAddUeInOndurationList(ueCb->cellCb, ueCb, 0);
498
499          }
500          else
501          {
502             /* convert all the drx configuration recived in ms/subms into number
503              * of slots and store into the drxUeCb */
504             schFillDrxUeCb(ueCb->cellCb->cellCfg.numerology, ueRecfg->macCellGrpRecfg.drxCfg, &ueCb->drxUeCb);
505
506             /* Recalculate/Restart timer based on their presence */
507             schDrxUeReCfgTimer(ueCb->cellCb, ueCb);
508          }
509       }
510 #endif
511    }
512
513 #ifdef NR_DRX
514    if(ueRecfg->drxConfigIndicatorRelease == true)
515    {
516       if(ueCb->ueDrxInfoPres == true)
517       {
518          schDeleteUeDrxInfo(ueCb->cellCb, ueCb);
519          ueCb->ueDrxInfoPres = false;
520       }
521    }
522 #endif
523
524    if(ueRecfg->phyCellGrpRecfgPres == true)
525    {
526       memcpy(&ueCb->ueCfg.phyCellGrpCfg ,  &ueRecfg->phyCellGrpRecfg, sizeof(SchPhyCellGrpCfg));
527       ueCb->ueCfg.phyCellGrpCfgPres = true;
528    }
529
530    if(ueRecfg->spCellRecfgPres == true)
531    {
532       if(ueRecfg->spCellRecfg.servCellRecfg.initDlBwp.pdschCfgPres == true)
533       {
534          if(ueCb->ueCfg.spCellCfgPres && ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfgPres == true)
535          {
536             for(idx = 0; idx < ueRecfg->spCellRecfg.servCellRecfg.initDlBwp.pdschCfg.numTimeDomRsrcAlloc; idx++)
537             {
538                if(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0 && ueRecfg->spCellRecfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0)
539                {
540                   SCH_FREE(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0, sizeof(uint8_t));  
541                }
542             }
543          }
544       }
545       memcpy(&ueCb->ueCfg.spCellCfg , &ueRecfg->spCellRecfg, sizeof(SchSpCellRecfg));
546
547       covertFreqDomRsrcMapToIAPIFormat(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc,\
548             freqDomainResource);
549       memset(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, 0, FREQ_DOM_RSRC_SIZE);
550       memcpy(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, freqDomainResource, FREQ_DOM_RSRC_SIZE);
551
552       ueCb->ueCfg.spCellCfgPres = true;
553       dlDataToUlAck = ueRecfg->spCellRecfg.servCellRecfg.initUlBwp.pucchCfg.dlDataToUlAck;
554       if(ueCb->cellCb)
555       {
556          if(dlDataToUlAck)
557          {
558             BuildK0K1Table(ueCb->cellCb, &ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.k0K1InfoTbl, false, pdschCfg,\
559                   ueRecfg->spCellRecfg.servCellRecfg.initDlBwp.pdschCfg, dlDataToUlAck->dlDataToUlAckListCount,\
560                   dlDataToUlAck->dlDataToUlAckList);
561             ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.k0K1TblPrsnt = true;
562             BuildK2InfoTable(ueCb->cellCb, ueRecfg->spCellRecfg.servCellRecfg.initUlBwp.puschCfg.timeDomRsrcAllocList,\
563                   ueRecfg->spCellRecfg.servCellRecfg.initUlBwp.puschCfg.numTimeDomRsrcAlloc,\
564                   NULLP, &ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.k2InfoTbl);
565             ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.k2TblPrsnt = true;
566          }
567       }
568    }
569
570    if(ueRecfg->ambrRecfg)
571    {
572       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
573       ueCb->ueCfg.ambrCfg =  ueRecfg->ambrRecfg;
574    }
575    memcpy(&ueCb->ueCfg.dlModInfo,  &ueRecfg->dlModInfo , sizeof(SchModulationInfo));
576    memcpy(&ueCb->ueCfg.ulModInfo,  &ueRecfg->ulModInfo , sizeof(SchModulationInfo));
577    //Updating Num of LC to ADD SchUlCb and SchDlCb DB in SchUeCb
578    for(lcIdx = 0; lcIdx < ueRecfg->numLcsToAdd; lcIdx++)
579    {
580       isLcIdValid = FALSE; /*Re-Initializing*/
581
582       ueLcIdx = ueRecfg->schLcCfgAdd[lcIdx].lcId;
583       CHECK_LCID(ueLcIdx, isLcIdValid);
584       if(isLcIdValid == FALSE)
585       {
586          DU_LOG("ERROR --> SCH: LCID:%d is not Valid",ueLcIdx);
587          continue;
588       }
589       fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueRecfg->schLcCfgAdd[lcIdx]);
590       fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueRecfg->schLcCfgAdd[lcIdx]);
591
592       /*Checking whether this LC belong to Dedicated S-NSSAI 
593        * and Create the Dedicated LC List & Update the Reserve PRB number*/
594       if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP)
595       {
596          retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
597                &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated));
598       }
599       if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP)
600       {
601          retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
602                &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated));
603       }
604
605       if(retUL == RFAILED  || retDL == RFAILED)/*FATAL error*/
606       {
607          DU_LOG("\nERROR  -->  SCH : Failure in updateDedLcInfo");
608          return RFAILED;
609       }
610       SCH_FREE(ueRecfg->schLcCfgAdd[lcIdx].drbQos, sizeof(SchDrbQosInfo));
611       SCH_FREE(ueRecfg->schLcCfgAdd[lcIdx].snssai, sizeof(Snssai));
612    }
613    //Updating Num of LC to DEL SchUlCb and SchDlCb DB in SchUeCb
614    for(lcIdx = 0; lcIdx < ueRecfg->numLcsToDel; lcIdx++)
615    {
616       ueLcIdx = ueRecfg->lcIdToDel[lcIdx];
617
618       if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].lcId == ueRecfg->lcIdToDel[lcIdx])
619       {
620          /*Delete the LC node from the DL LC List*/
621          if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated)
622          {
623             /*Remove from HARQ Transmission or retransmission*/
624          }
625          else
626          {
627          }
628          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
629          memset(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], 0, sizeof(SchDlLcCtxt));
630       }
631       if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].lcId == ueRecfg->lcIdToDel[lcIdx])
632       {
633          /*Delete the LC node from the UL LC List*/
634          if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated)
635          {
636             /*Remove from HARQ Transmission or retransmission*/
637          }
638          else/*Default LC list*/
639          {
640
641          }
642          SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
643          memset(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], 0, sizeof(SchUlLcCtxt));
644       }
645    }
646    //Updating Num of LC to DEL SchUlCb and SchDlCb DB in SchUeCb
647    for(lcIdx = 0; lcIdx < ueRecfg->numLcsToMod; lcIdx++)
648    {
649       ueLcIdx = ueRecfg->schLcCfgMod[lcIdx].lcId;
650
651       if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].lcId == ueRecfg->schLcCfgMod[lcIdx].lcId)
652       {
653          fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueRecfg->schLcCfgMod[lcIdx]);
654          /*Updating the RRM reserved pool PRB count*/
655          if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP)
656          {
657             retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].rsvdDedicatedPRB),\
658                   &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated));
659          }
660          if(retUL == RFAILED)
661          {
662             DU_LOG("\nERROR  -->  SCH : Failed in updating Ded Lc info");
663             return RFAILED;
664          }
665       }/*End of UL LC Ctxt*/
666
667       if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].lcId == ueRecfg->schLcCfgMod[lcIdx].lcId)
668       {
669          fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueRecfg->schLcCfgMod[lcIdx]);
670          /*Updating the RRM policy*/
671          if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP)
672          {
673             retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].rsvdDedicatedPRB), \
674                   &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated));
675          }
676          if(retDL == RFAILED)
677          {
678             DU_LOG("\nERROR  -->  SCH : Failed in updating Ded Lc info");
679             return RFAILED;
680          }
681       }/*End of DL LC ctxt*/
682
683       SCH_FREE(ueRecfg->schLcCfgMod[lcIdx].drbQos, sizeof(SchDrbQosInfo));
684       SCH_FREE(ueRecfg->schLcCfgMod[lcIdx].snssai, sizeof(Snssai));
685    }/* End of outer for loop */
686    return ROK;
687 }
688
689 /*******************************************************************
690  *
691  * @brief Function to get SCH Cell Cb
692  *
693  * @details
694  *
695  *    Function : getSchCellCb
696  *
697  *    Functionality: Function to get SCH Cell Cb
698  *
699  * @params[in] event, SchUeCfg pointer 
700  * @return schUeCb pointer  - success
701  *         NULLP - failure
702  *
703  * ****************************************************************/
704
705 SchCellCb *getSchCellCb(uint16_t srcEvent, Inst inst, uint16_t cellId)
706 {
707    uint8_t      idx = 0;
708    SchCellCb    *cellCb = NULLP;
709
710    /* Search of cell cb */
711    for(idx = 0; idx < MAX_NUM_CELL; idx++)
712    {
713       cellCb = schCb[inst].cells[idx];
714       if((cellCb != NULLP) && (cellCb->cellId == cellId))
715          break;
716    }
717    if((idx == MAX_NUM_CELL) || (cellCb == NULLP))
718    {
719       DU_LOG("\nERROR  -->  SCH : Ue create request failed. Invalid cell id %d", cellId);
720       return NULLP;
721    }
722
723    /* Check if max number of UE configured */
724    if(cellCb->numActvUe > MAX_NUM_UE)
725    {
726       DU_LOG("\nERROR  -->  SCH :  Max number of UE [%d] already configured", MAX_NUM_UE);
727       return NULLP;
728    }
729    return cellCb;
730 }
731
732
733 /*******************************************************************
734  *
735  * @brief Function to Add Ue Config Request from MAC
736  *
737  * @details
738  *
739  *    Function : SchAddUeConfigReq
740  *
741  *    Functionality: Function to Add Ue config request from MAC
742  *
743  * @params[in] 
744  * @return ROK     - success
745  *         RFAILED - failure
746  *
747  * ****************************************************************/
748 uint8_t SchAddUeConfigReq(Pst *pst, SchUeCfgReq *ueCfg)
749 {
750    uint8_t      lcIdx = 0, ret = ROK, idx = 0;
751    SchCellCb    *cellCb = NULLP;
752    SchUeCb      *ueCb = NULLP;
753    SchUeCfgRsp  cfgRsp;
754    Inst         inst = pst->dstInst - SCH_INST_START;
755    memset(&cfgRsp, 0, sizeof(SchUeCfgRsp));
756   
757    if(!ueCfg)
758    {
759       DU_LOG("\nERROR  -->  SCH :  Adding UE Config Request failed at SchAddUeConfigReq()");
760       return RFAILED;
761    }
762    DU_LOG("\nDEBUG  -->  SCH :  Adding UE Config Request for CRNTI[%d]", ueCfg->crnti);
763    cellCb = getSchCellCb(pst->event, inst, ueCfg->cellId);
764
765    if(cellCb == NULLP)
766    {
767       SchSendUeCfgRspToMac(ueCfg, inst, RSP_NOK, &cfgRsp);
768       return RFAILED; 
769    }
770    /* Search if UE already configured */
771    ueCb = &cellCb->ueCb[ueCfg->ueId - 1];
772
773    if((ueCb->crnti == ueCfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
774    {
775       DU_LOG("\nDEBUG  -->  SCH : CRNTI %d already configured ", ueCfg->crnti);
776       SchSendUeCfgRspToMac(ueCfg, inst, RSP_OK, &cfgRsp);
777       return ROK;
778    }
779
780    /* Fill received Ue Configuration in UeCb */
781    memset(ueCb, 0, sizeof(SchUeCb));
782
783    ueCb->ueId = ueCfg->ueId;
784    ueCb->crnti = ueCfg->crnti;
785    ueCb->cellCb = cellCb;
786    schUlHqEntInit(cellCb, &cellCb->ueCb[ueCfg->ueId-1]);
787    schDlHqEntInit(cellCb, &cellCb->ueCb[ueCfg->ueId-1]);
788    SCH_ALLOC(ueCb->hqDlmap, sizeof(SchHqDlMap*)*(ueCb->cellCb->numSlots));
789    SCH_ALLOC(ueCb->hqUlmap, sizeof(SchHqUlMap*)*(ueCb->cellCb->numSlots));
790
791    if ( (ueCb->hqDlmap == NULLP) || (ueCb->hqUlmap == NULLP) )
792    {
793       DU_LOG("\nINFO  -->  SCH : Memory Allocation Failed");
794       return RFAILED;
795    }
796    for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
797    {
798       SCH_ALLOC(ueCb->hqDlmap[idx], sizeof(SchHqDlMap));
799       SCH_ALLOC(ueCb->hqUlmap[idx], sizeof(SchHqUlMap));
800       
801       if ( (ueCb->hqDlmap[idx] == NULLP) || (ueCb->hqUlmap[idx] == NULLP) )
802       {
803          DU_LOG("\nINFO  -->  SCH : Memory Allocation Failed");
804          return RFAILED;
805       }
806       cmLListInit(&ueCb->hqDlmap[idx]->hqList);
807       cmLListInit(&ueCb->hqUlmap[idx]->hqList);
808    }
809    ret = fillSchUeCbFrmCfgReq(inst, ueCb, ueCfg);
810
811    if(ret == ROK)
812    {
813       /* If UE has initiated RACH and then UE context is created, it means UE is
814        * active now.
815        * Else if UE context is created before RACH, this means that UE is being
816        * handed-in from source DU */
817       if(cellCb->raCb[ueCb->ueId-1].tcrnti == ueCb->crnti)
818       {
819          cellCb->numActvUe++;
820          SET_ONE_BIT(ueCb->ueId, cellCb->actvUeBitMap);
821          ueCb->state = SCH_UE_STATE_ACTIVE;
822       }
823       else
824       {
825          ueCb->state = SCH_UE_HANDIN_IN_PROGRESS;
826       }
827
828       ueCb->srRcvd = false;
829       ueCb->bsrRcvd = false;
830       for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
831          ueCb->bsrInfo[lcIdx].dataVol = 0;
832
833       SchSendUeCfgRspToMac(ueCfg, inst, RSP_OK, &cfgRsp);
834    }
835
836    cellCb->api->SchAddUeConfigReq(ueCb);
837    return ret;
838 }
839
840 /*******************************************************************
841 *
842 * @brief Fills PUSCH UL allocation
843 *
844 * @details
845 *
846 *    Function : schFillPuschAlloc
847 *
848 *    Functionality: fills PUSCH info
849 *
850 * @params[in] SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSize
851 * @params[in] uint8_t startSymb, uint8_t symbLen, uint16_t startPrb
852 * @params[in] bool isRetx, SchUlHqProcCb *hq
853 * @return ROK     - success
854 *         RFAILED - failure
855 *
856 * ****************************************************************/
857 uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSize, 
858                           uint8_t startSymb, uint8_t symbLen, uint16_t startPrb, bool isRetx, SchUlHqProcCb *hqP)
859 {
860   uint8_t  numRb          = 0;
861   SchCellCb *cellCb       = NULLP;
862   SchUlSlotInfo *schUlSlotInfo = NULLP;
863   SchPuschInfo puschInfo;
864   
865   if(ueCb == NULLP)
866   {
867     DU_LOG("\nERROR --> SCH: UE CB is empty");
868     return RFAILED;
869   }
870
871   cellCb = ueCb->cellCb;
872   if(cellCb == NULLP)
873   {
874     DU_LOG("\nERROR --> SCH: CELL CB is empty");
875     return RFAILED;
876   }
877
878   tbSize  +=  UL_TX_BUFFER_SIZE; /*  2 bytes header + some buffer */
879   numRb   = schCalcNumPrb(tbSize, ueCb->ueCfg.ulModInfo.mcsIndex, symbLen);
880   allocatePrbUl(cellCb, puschTime, startSymb, symbLen, &startPrb, numRb);
881
882    if (isRetx == FALSE)
883    {
884       puschInfo.crnti             = ueCb->crnti;
885       puschInfo.harqProcId        = SCH_HARQ_PROC_ID;
886       puschInfo.resAllocType      = SCH_ALLOC_TYPE_1;
887       puschInfo.fdAlloc.startPrb  = startPrb;
888       puschInfo.fdAlloc.numPrb    = numRb;
889       puschInfo.tdAlloc.startSymb = startSymb;
890       puschInfo.tdAlloc.numSymb   = symbLen;
891       puschInfo.tbInfo.qamOrder   = ueCb->ueCfg.ulModInfo.modOrder;
892       puschInfo.tbInfo.mcs        = ueCb->ueCfg.ulModInfo.mcsIndex;
893       puschInfo.tbInfo.mcsTable   = ueCb->ueCfg.ulModInfo.mcsTable;
894       puschInfo.tbInfo.ndi        = 1; /* new transmission */
895       puschInfo.tbInfo.rv         = 0;
896       puschInfo.tbInfo.tbSize     = tbSize;
897       puschInfo.dmrsMappingType   = DMRS_MAP_TYPE_A;  /* Setting Type-A */
898       puschInfo.nrOfDmrsSymbols   = NUM_DMRS_SYMBOLS;
899       puschInfo.dmrsAddPos        = DMRS_ADDITIONAL_POS;
900       hqP->puschResType = puschInfo.resAllocType;
901       hqP->puschStartPrb = puschInfo.fdAlloc.startPrb;
902       hqP->puschNumPrb = puschInfo.fdAlloc.numPrb;
903       hqP->strtSymbl = puschInfo.tdAlloc.startSymb;
904       hqP->numSymbl = puschInfo.tdAlloc.numSymb;
905       hqP->tbInfo.qamOrder = puschInfo.tbInfo.qamOrder;
906       hqP->tbInfo.iMcs = puschInfo.tbInfo.mcs;
907       hqP->tbInfo.mcsTable = puschInfo.tbInfo.mcsTable;
908       hqP->tbInfo.ndi = puschInfo.tbInfo.ndi;
909       hqP->tbInfo.rv = puschInfo.tbInfo.rv;
910       hqP->tbInfo.rvIdx = 0;
911       hqP->tbInfo.tbSzReq = puschInfo.tbInfo.tbSize;
912       hqP->dmrsMappingType = puschInfo.dmrsMappingType;
913       hqP->nrOfDmrsSymbols = puschInfo.nrOfDmrsSymbols;
914       hqP->dmrsAddPos = puschInfo.dmrsAddPos;
915    }
916    else
917    {
918       puschInfo.crnti             = ueCb->crnti;
919       puschInfo.harqProcId        = hqP->procId;
920       puschInfo.resAllocType      = hqP->puschResType;
921       puschInfo.fdAlloc.startPrb  = hqP->puschStartPrb;
922       puschInfo.fdAlloc.numPrb    = hqP->puschNumPrb;
923       puschInfo.tdAlloc.startSymb = hqP->strtSymbl;
924       puschInfo.tdAlloc.numSymb   = hqP->numSymbl;
925       puschInfo.tbInfo.qamOrder   = hqP->tbInfo.qamOrder;
926       puschInfo.tbInfo.mcs        = hqP->tbInfo.iMcs;
927       puschInfo.tbInfo.mcsTable   = hqP->tbInfo.mcsTable;
928       puschInfo.tbInfo.ndi        = hqP->tbInfo.ndi; /* retransmission */
929       hqP->tbInfo.rvIdx = (hqP->tbInfo.rvIdx +1) & 0x3;
930       puschInfo.tbInfo.rv         = schCmnDlRvTbl[hqP->tbInfo.rvIdx];
931       puschInfo.tbInfo.tbSize     = hqP->tbInfo.tbSzReq;
932       puschInfo.dmrsMappingType   = hqP->dmrsMappingType;  /* Setting Type-A */
933       puschInfo.nrOfDmrsSymbols   = hqP->nrOfDmrsSymbols;
934       puschInfo.dmrsAddPos        = hqP->dmrsAddPos;
935    }
936   schUlSlotInfo = cellCb->schUlSlotInfo[puschTime.slot];
937   SCH_ALLOC(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo));
938   if(!schUlSlotInfo->schPuschInfo)
939   {
940      DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schAllocMsg3Pusch");
941      return RFAILED;
942   }
943   memcpy(schUlSlotInfo->schPuschInfo, &puschInfo, sizeof(SchPuschInfo));
944
945   return ROK;
946 }
947 /*******************************************************************
948 *
949 * @brief Fills UL DCI information for MSG3 retransmission
950 *
951 * @details
952 *
953 *    Function : schFillUlDciForMsg3Retx
954 *
955 *    Functionality: fills UL DCI information for MSG3 retransmission
956 *
957 * @params[in]
958 * @return ROK     - success
959 *         RFAILED - failure
960 *
961 * ****************************************************************/
962 uint8_t schFillUlDciForMsg3Retx(SchRaCb *raCb, SchPuschInfo *puschInfo, DciInfo *dciInfo)
963 {
964    SchCellCb         *cellCb  = raCb->cell;
965    dciInfo->cellId = cellCb->cellId;
966    dciInfo->crnti  = raCb->tcrnti;
967    SchUlHqProcCb *msg3HqProc = &raCb->msg3HqProc;
968    if (msg3HqProc == NULLP)
969    {
970       return RFAILED;
971    }
972
973    /* fill bwp cfg */
974    dciInfo->bwpCfg.subcarrierSpacing  = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
975    dciInfo->bwpCfg.cyclicPrefix       = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
976    dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb;
977    dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb; 
978
979    /*fill coreset cfg */
980    //Considering number of RBs in coreset1 is same as coreset0
981    dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
982    //Considering coreset1 also starts from same symbol as coreset0
983    dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
984    dciInfo->coresetCfg.durationSymbols  = coresetIdxTable[0][2];
985    memcpy(dciInfo->coresetCfg.freqDomainResource, cellCb->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
986    
987    dciInfo->coresetCfg.cceRegMappingType   = 1; /* coreset0 is always interleaved */
988    dciInfo->coresetCfg.regBundleSize       = 6; /* spec-38.211 sec 7.3.2.2 */
989    dciInfo->coresetCfg.interleaverSize     = 2; /* spec-38.211 sec 7.3.2.2 */
990    dciInfo->coresetCfg.coreSetType         = 0;
991    dciInfo->coresetCfg.coreSetSize         = coresetIdxTable[0][1];
992    dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
993    dciInfo->coresetCfg.precoderGranularity = 0;
994    dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
995    dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
996    
997    dciInfo->formatType = FORMAT0_0;
998    msg3HqProc->tbInfo.rvIdx++;
999    msg3HqProc->tbInfo.rv = schCmnDlRvTbl[msg3HqProc->tbInfo.rvIdx & 0x03];
1000    /* fill UL grant */
1001    dciInfo->format.format0_0.resourceAllocType   = msg3HqProc->puschResType;
1002    dciInfo->format.format0_0.freqAlloc.startPrb  = msg3HqProc->puschStartPrb;
1003    dciInfo->format.format0_0.freqAlloc.numPrb    = msg3HqProc->puschNumPrb;
1004    dciInfo->format.format0_0.timeAlloc.startSymb = msg3HqProc->strtSymbl;
1005    dciInfo->format.format0_0.timeAlloc.numSymb   = msg3HqProc->numSymbl;
1006    dciInfo->format.format0_0.rowIndex            = 0; /* row Index */
1007    dciInfo->format.format0_0.mcs                 = msg3HqProc->tbInfo.iMcs;
1008    dciInfo->format.format0_0.harqProcId          = msg3HqProc->procId;
1009    dciInfo->format.format0_0.puschHopFlag        = FALSE; /* disabled */
1010    dciInfo->format.format0_0.freqHopFlag         = FALSE; /* disabled */
1011    dciInfo->format.format0_0.ndi                 = msg3HqProc->tbInfo.ndi; /* new transmission */
1012    dciInfo->format.format0_0.rv                  = msg3HqProc->tbInfo.rv;
1013    dciInfo->format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
1014    dciInfo->format.format0_0.sUlCfgd             = FALSE; /* SUL not configured */
1015    
1016    /* Fill DCI Structure */
1017    dciInfo->dciInfo.rnti                              = raCb->tcrnti;
1018    dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
1019    dciInfo->dciInfo.scramblingRnti                    = 0;
1020    dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
1021    dciInfo->dciInfo.aggregLevel                       = 4;
1022    dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
1023    dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
1024    dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
1025    dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
1026    dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
1027    dciInfo->dciInfo.txPdcchPower.powerValue           = 0;
1028    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
1029    dciInfo->dciInfo.pdschCfg                          = NULL; /* No DL data being sent */
1030    msg3HqProc->tbInfo.txCntr++;
1031
1032   puschInfo->crnti             = raCb->tcrnti;
1033   puschInfo->harqProcId        = msg3HqProc->procId;
1034   puschInfo->resAllocType      = msg3HqProc->puschResType;
1035   puschInfo->fdAlloc.startPrb  = msg3HqProc->puschStartPrb;
1036   puschInfo->fdAlloc.numPrb    = msg3HqProc->puschNumPrb;
1037   puschInfo->tdAlloc.startSymb = msg3HqProc->strtSymbl;
1038   puschInfo->tdAlloc.numSymb   = msg3HqProc->numSymbl;
1039   puschInfo->tbInfo.qamOrder   = msg3HqProc->tbInfo.qamOrder;
1040   puschInfo->tbInfo.mcs        = msg3HqProc->tbInfo.iMcs;
1041   puschInfo->tbInfo.mcsTable   = msg3HqProc->tbInfo.mcsTable;
1042   puschInfo->tbInfo.ndi        = msg3HqProc->tbInfo.ndi; /* retransmission */
1043   puschInfo->tbInfo.rv         = msg3HqProc->tbInfo.rvIdx;
1044   puschInfo->tbInfo.tbSize     = msg3HqProc->tbInfo.tbSzReq;
1045   puschInfo->dmrsMappingType   = msg3HqProc->dmrsMappingType;  /* Setting Type-A */
1046   puschInfo->nrOfDmrsSymbols   = msg3HqProc->nrOfDmrsSymbols;
1047   puschInfo->dmrsAddPos        = msg3HqProc->dmrsAddPos;
1048
1049    return ROK;
1050 }
1051
1052 /*******************************************************************
1053  *
1054  * @brief Fills DCI for UL grant
1055  *
1056  * @details
1057  *
1058  *    Function : schFillUlDci
1059  *
1060  *    Functionality: fills DCI for UL grant in response to BSR
1061  *
1062  * @params[in] SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo,
1063  * @params[in] bool isRetx, SchUlHqProcCb *hqP 
1064  * @return ROK     - success
1065  *         RFAILED - failure
1066  *
1067  * ****************************************************************/
1068 uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo, bool isRetx, SchUlHqProcCb *hqP)
1069 {
1070    SchCellCb         *cellCb  = ueCb->cellCb;
1071    SchControlRsrcSet coreset1 ;
1072   
1073    memset(&coreset1, 0, sizeof(SchControlRsrcSet));
1074    if(ueCb->ueCfg.spCellCfgPres == true)
1075    {
1076      coreset1 = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0];
1077    }
1078    
1079    dciInfo->cellId = cellCb->cellId;
1080    dciInfo->crnti  = ueCb->crnti;
1081
1082    /* fill bwp cfg */
1083    dciInfo->bwpCfg.subcarrierSpacing  = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
1084    dciInfo->bwpCfg.cyclicPrefix       = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
1085    dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb;
1086    dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb; 
1087
1088    /*fill coreset cfg */
1089    //Considering number of RBs in coreset1 is same as coreset0
1090    dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
1091    //Considering coreset1 also starts from same symbol as coreset0
1092    dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
1093    dciInfo->coresetCfg.durationSymbols  = coreset1.duration;
1094    memcpy(dciInfo->coresetCfg.freqDomainResource, coreset1.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
1095    
1096    dciInfo->coresetCfg.cceRegMappingType   = coreset1.cceRegMappingType; /* non-interleaved */
1097    dciInfo->coresetCfg.regBundleSize       = 6; /* must be 6 for non-interleaved */
1098    dciInfo->coresetCfg.interleaverSize     = 0; /* NA for non-interleaved */
1099    dciInfo->coresetCfg.coreSetType         = 1; /* non PBCH coreset */
1100    dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
1101    dciInfo->coresetCfg.precoderGranularity = coreset1.precoderGranularity;
1102    dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
1103    dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
1104    
1105    dciInfo->formatType = FORMAT0_0;
1106    
1107    /* fill UL grant */
1108    dciInfo->format.format0_0.resourceAllocType   = puschInfo->resAllocType;
1109    dciInfo->format.format0_0.freqAlloc.startPrb  = puschInfo->fdAlloc.startPrb;
1110    dciInfo->format.format0_0.freqAlloc.numPrb    = puschInfo->fdAlloc.numPrb;
1111    dciInfo->format.format0_0.timeAlloc.startSymb = puschInfo->tdAlloc.startSymb;
1112    dciInfo->format.format0_0.timeAlloc.numSymb   = puschInfo->tdAlloc.numSymb;
1113    dciInfo->format.format0_0.rowIndex            = 0; /* row Index */
1114    dciInfo->format.format0_0.mcs                 = puschInfo->tbInfo.mcs;
1115    dciInfo->format.format0_0.harqProcId          = puschInfo->harqProcId;
1116    dciInfo->format.format0_0.puschHopFlag        = FALSE; /* disabled */
1117    dciInfo->format.format0_0.freqHopFlag         = FALSE; /* disabled */
1118    dciInfo->format.format0_0.ndi                 = puschInfo->tbInfo.ndi; /* new transmission */
1119    dciInfo->format.format0_0.rv                  = puschInfo->tbInfo.rv;
1120    dciInfo->format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
1121    dciInfo->format.format0_0.sUlCfgd             = FALSE; /* SUL not configured */
1122    
1123    /* Fill DCI Structure */
1124    dciInfo->dciInfo.rnti                              = ueCb->crnti;
1125    dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
1126    dciInfo->dciInfo.scramblingRnti                    = 0;
1127    dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
1128    dciInfo->dciInfo.aggregLevel                       = 4;
1129    dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
1130    dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
1131    dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
1132    dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
1133    dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
1134    dciInfo->dciInfo.txPdcchPower.powerValue           = 0;
1135    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
1136    dciInfo->dciInfo.pdschCfg                          = NULL; /* No DL data being sent */
1137
1138    return ROK;
1139 }
1140
1141 /*******************************************************************
1142  *
1143  * @brief Function to Modify Ue Config request from MAC
1144  *
1145  * @details
1146  *
1147  *    Function : SchModUeConfigReq
1148  *
1149  *    Functionality: Function to modify Ue Config request from MAC
1150  *
1151  * @params[in] 
1152  * @return ROK     - success
1153  *         RFAILED - failure
1154  *
1155  * ****************************************************************/
1156 uint8_t SchModUeConfigReq(Pst *pst, SchUeRecfgReq *ueRecfg)
1157 {
1158    uint8_t ueId, lcIdx, ret = ROK;
1159    SchCellCb    *cellCb = NULLP;
1160    SchUeCb      *ueCb = NULLP;
1161    SchUeRecfgRsp  recfgRsp;
1162    Inst         inst = pst->dstInst - SCH_INST_START;
1163    memset(&recfgRsp, 0, sizeof(SchUeRecfgRsp));
1164   
1165    if(!ueRecfg)
1166    {
1167       DU_LOG("\nERROR  -->  SCH : Modifying Ue Config request failed at SchModUeConfigReq()");
1168       return RFAILED;
1169    }
1170    DU_LOG("\nDEBUG  -->  SCH : Modifying Ue Config Request for CRNTI[%d]", ueRecfg->crnti);
1171    cellCb = getSchCellCb(pst->event, inst, ueRecfg->cellId);
1172
1173    if(cellCb == NULLP)
1174    {
1175       SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_NOK, &recfgRsp);
1176       return RFAILED;
1177    }
1178
1179    /* Search if UE already configured */
1180    GET_UE_ID(ueRecfg->crnti, ueId);
1181    ueCb = &cellCb->ueCb[ueId -1];
1182    
1183    if(!ueCb)
1184    {
1185       DU_LOG("\nERROR  -->  SCH : SchUeCb not found at SchModUeConfigReq() ");
1186       SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_NOK, &recfgRsp);
1187       return RFAILED;
1188    }
1189    if((ueCb->crnti == ueRecfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
1190    {
1191       /* Found the UeCb to Reconfig */
1192       ret = fillSchUeCbFrmRecfgReq(inst, ueCb, ueRecfg);
1193       if(ret == ROK)
1194       {
1195          ueCb->cellCb = cellCb;
1196          ueCb->srRcvd = false;
1197          ueCb->bsrRcvd = false;
1198          for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
1199             ueCb->bsrInfo[lcIdx].dataVol = 0;
1200
1201          SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_OK, &recfgRsp);
1202       }
1203    }
1204    return ret;
1205 }
1206
1207
1208 /*******************************************************************
1209 *
1210 * @brief Function to delete Sch Pucch ResrcCfg
1211 *
1212 * @details
1213 *
1214 *    Function : deleteSchPucchResrcCfg 
1215 *
1216 *    Functionality: Function to delete Sch Pucch ResrcCfg
1217 *
1218 * @params[in] SchPucchResrcCfg *resrc
1219 * @return void 
1220 *
1221 * ****************************************************************/
1222
1223 void deleteSchPucchResrcCfg(SchPucchResrcCfg *resrc)
1224 {
1225    uint8_t rsrcIdx=0;
1226    for(rsrcIdx=0; rsrcIdx < resrc->resrcToAddModListCount; rsrcIdx++)
1227    {
1228       switch(resrc->resrcToAddModList[rsrcIdx].pucchFormat)
1229       {
1230          case PUCCH_FORMAT_0:
1231          {
1232             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format0,\
1233             sizeof(SchPucchFormat0));
1234             break;
1235          }
1236          case PUCCH_FORMAT_1:
1237          {
1238             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format1,\
1239             sizeof(SchPucchFormat1));
1240             break;
1241          }
1242          case PUCCH_FORMAT_2:
1243          {
1244             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format2,\
1245             sizeof(SchPucchFormat2_3));
1246             break;
1247          }
1248          case PUCCH_FORMAT_3:
1249          {
1250             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format3,\
1251             sizeof(SchPucchFormat2_3));
1252             break;
1253          }
1254          case PUCCH_FORMAT_4:
1255          {
1256             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format4,\
1257             sizeof(SchPucchFormat4));
1258             break;
1259          }
1260       }
1261    }
1262 }
1263
1264 /*******************************************************************
1265 *
1266 * @brief Function to delete SCH Pdsch ServCellCfg
1267 *
1268 * @details
1269 *
1270 *    Function : deleteSchPdschServCellCfg
1271 *
1272 *    Functionality: Function to delete SCH Pdsch ServCellCfg
1273 *
1274 * @params[in] SchPdschServCellCfg *pdschServCellCfg
1275 * @return void 
1276 *
1277 * ****************************************************************/
1278
1279 void deleteSchPdschServCellCfg(SchPdschServCellCfg *pdschServCellCfg)
1280 {
1281    SCH_FREE(pdschServCellCfg->maxMimoLayers, sizeof(uint8_t));
1282    SCH_FREE(pdschServCellCfg->maxCodeBlkGrpPerTb, sizeof(SchMaxCodeBlkGrpPerTB));
1283    SCH_FREE(pdschServCellCfg->codeBlkGrpFlushInd, sizeof(bool));
1284    SCH_FREE(pdschServCellCfg->xOverhead, sizeof(SchPdschXOverhead));
1285 }
1286
1287 /*******************************************************************
1288 *
1289 * @brief Function to  delete SCH UeCb
1290 *
1291 * @details
1292 *
1293 *    Function : deleteSchUeCb 
1294 *
1295 *    Functionality: Function to delete SCH UeCb
1296 *
1297 * @params[in]
1298 * @return ROK     - success
1299 *         RFAILED - failure
1300 *
1301 * ****************************************************************/
1302 void deleteSchUeCb(SchUeCb *ueCb) 
1303 {
1304    uint8_t timeDomRsrcIdx = 0, ueLcIdx = 0, idx =0;
1305    SchPucchCfg *pucchCfg = NULLP;
1306    SchPdschConfig *pdschCfg = NULLP;
1307
1308    if(ueCb)
1309    {
1310       if(ueCb->hqDlmap)
1311       {
1312          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1313          {
1314             if(ueCb->hqDlmap[idx])
1315             {
1316                cmLListDeleteLList(&ueCb->hqDlmap[idx]->hqList);
1317                SCH_FREE(ueCb->hqDlmap[idx], sizeof(SchHqDlMap));
1318             }
1319          }
1320          SCH_FREE(ueCb->hqDlmap, sizeof(SchHqDlMap*)*(ueCb->cellCb->numSlots));
1321       }
1322
1323       if(ueCb->hqUlmap)
1324       {
1325          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1326          {
1327             if(ueCb->hqUlmap[idx])
1328             {
1329                cmLListDeleteLList(&ueCb->hqUlmap[idx]->hqList);
1330                SCH_FREE(ueCb->hqUlmap[idx], sizeof(SchHqUlMap));
1331             }
1332          }
1333          SCH_FREE(ueCb->hqUlmap, sizeof(SchHqUlMap*)*(ueCb->cellCb->numSlots));
1334       }
1335
1336       schDlHqEntDelete(ueCb);
1337       schUlHqEntDelete(ueCb);
1338
1339       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
1340       if(ueCb->ueCfg.spCellCfgPres)
1341       {
1342          if(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfgPres == true)
1343          {
1344             pdschCfg = &ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg;
1345             for(timeDomRsrcIdx = 0; timeDomRsrcIdx < pdschCfg->numTimeDomRsrcAlloc; timeDomRsrcIdx++)
1346                SCH_FREE(pdschCfg->timeDomRsrcAllociList[timeDomRsrcIdx].k0, sizeof(uint8_t));
1347          }
1348
1349          if(ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfgPres == true)
1350          {
1351             pucchCfg = &ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg;
1352             SCH_FREE(pucchCfg->resrcSet,sizeof(SchPucchResrcSetCfg));
1353             if(pucchCfg->resrc)
1354             {
1355                deleteSchPucchResrcCfg(pucchCfg->resrc);
1356                SCH_FREE(pucchCfg->resrc, sizeof(SchPucchResrcCfg));
1357             }
1358             SCH_FREE(pucchCfg->format1, sizeof(SchPucchFormatCfg));
1359             SCH_FREE(pucchCfg->format2, sizeof(SchPucchFormatCfg));
1360             SCH_FREE(pucchCfg->format3, sizeof(SchPucchFormatCfg));
1361             SCH_FREE(pucchCfg->format4, sizeof(SchPucchFormatCfg));
1362             SCH_FREE(pucchCfg->schedReq, sizeof(SchPucchSchedReqCfg));
1363             SCH_FREE(pucchCfg->multiCsiCfg, sizeof(SchPucchMultiCsiCfg));
1364             SCH_FREE(pucchCfg->spatialInfo, sizeof(SchPucchSpatialCfg));  
1365             SCH_FREE(pucchCfg->dlDataToUlAck, sizeof(SchPucchDlDataToUlAck));
1366             SCH_FREE(pucchCfg->powerControl,sizeof(SchPucchPowerControl));
1367          }
1368          SCH_FREE(ueCb->ueCfg.spCellCfg.servCellRecfg.bwpInactivityTmr, sizeof(uint8_t));
1369          deleteSchPdschServCellCfg(&ueCb->ueCfg.spCellCfg.servCellRecfg.pdschServCellCfg);
1370       }
1371       /*Need to Free the memory allocated for S-NSSAI*/
1372       for(ueLcIdx = 0; ueLcIdx < MAX_NUM_LC; ueLcIdx++)
1373       {
1374          SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1375          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1376       }
1377 #ifdef NR_DRX
1378       if(ueCb->ueDrxInfoPres)
1379       {
1380          /* Removing all the calculated drx configuration timer list */ 
1381          schDeleteUeDrxInfo(ueCb->cellCb, ueCb);
1382          ueCb->ueDrxInfoPres = false;
1383       }
1384 #endif
1385       memset(ueCb, 0, sizeof(SchUeCb));
1386    }
1387 }
1388
1389 /*******************************************************************
1390 *
1391 * @brief Fill and send UE delete response to MAC
1392 *
1393 * @details
1394 *
1395 *    Function :  SchSendUeDeleteRspToMac
1396 *
1397 *    Functionality: Fill and send UE delete response to MAC
1398 *
1399 * @params[in] Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, 
1400 *              ErrorCause cause
1401 * @return ROK     - success
1402 *         RFAILED - failure
1403 *
1404 * ****************************************************************/
1405 void SchSendUeDeleteRspToMac(Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, ErrorCause cause)
1406 {
1407     Pst rspPst;
1408     SchUeDeleteRsp  delRsp;
1409     
1410     memset(&delRsp, 0, sizeof(SchUeDeleteRsp));
1411     delRsp.cellId = ueDelete->cellId;
1412     delRsp.crnti = ueDelete->crnti;
1413     delRsp.rsp = result; 
1414     delRsp.cause = cause; 
1415
1416     /* Filling response post */
1417     memset(&rspPst, 0, sizeof(Pst));
1418     FILL_PST_SCH_TO_MAC(rspPst, inst);
1419     rspPst.event = EVENT_UE_DELETE_RSP_TO_MAC;
1420     MacMessageRouter(&rspPst, (void *)&delRsp);
1421 }
1422
1423 /*******************************************************************
1424 *
1425 * @brief Function for Ue Delete request from MAC to SCH
1426 *
1427 * @details
1428 *
1429 *    Function : SchProcUeDeleteReq 
1430 *
1431 *    Functionality: Function for Ue Delete request from MAC to SCH
1432 *
1433 * @params[in] Pst *pst, SchUeDelete  *ueDelete
1434 * @return ROK     - success
1435 *         RFAILED - failure
1436 *
1437 * ****************************************************************/
1438 uint8_t SchProcUeDeleteReq(Pst *pst, SchUeDelete  *ueDelete)
1439 {
1440     uint8_t      idx=0, ueId=0, ret=ROK;
1441     ErrorCause   result;
1442     SchCellCb    *cellCb = NULLP;
1443     Inst         inst = pst->dstInst - SCH_INST_START;
1444    
1445     if(!ueDelete)
1446     {
1447        DU_LOG("\nERROR  -->  SCH : SchProcUeDeleteReq(): Ue Delete request failed");
1448        ret = RFAILED;
1449     }
1450     DU_LOG("\nDEBUG  -->  SCH : Ue Delete request received for crnti[%d]", ueDelete->crnti);
1451     
1452     cellCb = schCb[inst].cells[idx];
1453
1454     if(cellCb->cellId != ueDelete->cellId)
1455     {
1456        DU_LOG("\nERROR  -->  SCH : SchProcUeDeleteReq(): cell Id is not available");
1457        result =  INVALID_CELLID;
1458     }
1459     else
1460     {
1461        GET_UE_ID(ueDelete->crnti, ueId);
1462        if(( cellCb->ueCb[ueId-1].crnti == ueDelete->crnti) && ( cellCb->ueCb[ueId-1].state == SCH_UE_STATE_ACTIVE))
1463        {
1464           /* Remove UE from ueToBeScheduled list */
1465           cellCb->api->SchUeDeleteReq(&cellCb->ueCb[ueId-1]);
1466           deleteSchUeCb(&cellCb->ueCb[ueId-1]);
1467           cellCb->numActvUe--;
1468           result = NOT_APPLICABLE;
1469        }
1470        else
1471        {
1472           DU_LOG("\nERROR  -->  SCH : SchProcUeDeleteReq(): SchUeCb not found");
1473           result =  INVALID_UEID;
1474        }
1475     }
1476     
1477     if(result == NOT_APPLICABLE)
1478     {
1479        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_OK, result);
1480     }
1481     else
1482     {
1483        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_NOK, result);
1484        ret = RFAILED;
1485     }
1486     return ret;
1487 }
1488
1489 /*******************************************************************
1490  *
1491  * @brief Function updates DL HARQ Feedback
1492  *
1493  * @details
1494  *
1495  *    Function : schUpdateHarqFdbk
1496  *
1497  *    Functionality: Function updates DL HARQ feedback
1498  *
1499  * @params[in] SchUeCb *ueCb, UE cb struct pointer
1500  * @params[in] uint8_t numHarq, number of HARQ processes in feedback 
1501  * @params[in] uint8_t *harqPayload, harq feedback payload received
1502  * @params[in] SlotTimingInfo *slotInd, slot timing information
1503  * @return void
1504  *
1505  * ****************************************************************/
1506 void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload, SlotTimingInfo *slotInd)
1507 {
1508    SchDlHqProcCb *hqP;
1509    SchHqDlMap *hqDlMap;
1510    CmLList  *node;
1511    uint8_t fdbkPos = 0;
1512
1513    hqDlMap = ueCb->hqDlmap[slotInd->slot];
1514
1515    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState == SCH_RA_STATE_MSG2_HANDLE)
1516    {
1517       return;
1518    }
1519    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState != SCH_RA_STATE_MSG4_PENDING)
1520    {
1521       node = hqDlMap->hqList.first;
1522       while(node)
1523       {
1524          hqP = (SchDlHqProcCb*)node->node;
1525          node = node->next;
1526          cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1527          /* 
1528             Decode harq feedback if needed post FAPI message decoding also or check how to decode this FAPI msg.
1529             case 1 semi static harq Ack/Nack codebook //Supported
1530             case 2 dynamic harq ACK/NACK codebook //Not supported
1531          */
1532          schDlHqFeedbackUpdate(hqP, harqPayload[fdbkPos++], HQ_TB_ACKED);//Marking 2nd TB as ACKED for now as only one TB to be used
1533       }
1534    }
1535    else
1536    {
1537       node = hqDlMap->hqList.first;
1538       hqP = (SchDlHqProcCb*)node->node;
1539       cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1540       schMsg4FeedbackUpdate(hqP, harqPayload[fdbkPos++]);
1541    }
1542 }
1543 /**********************************************************************
1544   End of file
1545  **********************************************************************/