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