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