61db4b24207751854c950502159d7ebf04d28b64
[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.crnti             = ueCb->crnti;
913       puschInfo.harqProcId        = SCH_HARQ_PROC_ID;
914       puschInfo.resAllocType      = SCH_ALLOC_TYPE_1;
915       puschInfo.fdAlloc.startPrb  = startPrb;
916       puschInfo.fdAlloc.numPrb    = numRb;
917       puschInfo.tdAlloc.startSymb = startSymb;
918       puschInfo.tdAlloc.numSymb   = symbLen;
919       puschInfo.tbInfo.qamOrder   = ueCb->ueCfg.ulModInfo.modOrder;
920       puschInfo.tbInfo.mcs        = ueCb->ueCfg.ulModInfo.mcsIndex;
921       puschInfo.tbInfo.mcsTable   = ueCb->ueCfg.ulModInfo.mcsTable;
922       puschInfo.tbInfo.ndi        = 1; /* new transmission */
923       puschInfo.tbInfo.rv         = 0;
924       puschInfo.tbInfo.tbSize     = tbSize;
925       puschInfo.dmrsMappingType   = DMRS_MAP_TYPE_A;  /* Setting Type-A */
926       puschInfo.nrOfDmrsSymbols   = NUM_DMRS_SYMBOLS;
927       puschInfo.dmrsAddPos        = DMRS_ADDITIONAL_POS;
928       hqP->puschResType = puschInfo.resAllocType;
929       hqP->puschStartPrb = puschInfo.fdAlloc.startPrb;
930       hqP->puschNumPrb = puschInfo.fdAlloc.numPrb;
931       hqP->strtSymbl = puschInfo.tdAlloc.startSymb;
932       hqP->numSymbl = puschInfo.tdAlloc.numSymb;
933       hqP->tbInfo.qamOrder = puschInfo.tbInfo.qamOrder;
934       hqP->tbInfo.iMcs = puschInfo.tbInfo.mcs;
935       hqP->tbInfo.mcsTable = puschInfo.tbInfo.mcsTable;
936       hqP->tbInfo.ndi = puschInfo.tbInfo.ndi;
937       hqP->tbInfo.rv = puschInfo.tbInfo.rv;
938       hqP->tbInfo.rvIdx = 0;
939       hqP->tbInfo.tbSzReq = puschInfo.tbInfo.tbSize;
940       hqP->dmrsMappingType = puschInfo.dmrsMappingType;
941       hqP->nrOfDmrsSymbols = puschInfo.nrOfDmrsSymbols;
942       hqP->dmrsAddPos = puschInfo.dmrsAddPos;
943    }
944    else
945    {
946       puschInfo.crnti             = ueCb->crnti;
947       puschInfo.harqProcId        = hqP->procId;
948       puschInfo.resAllocType      = hqP->puschResType;
949       puschInfo.fdAlloc.startPrb  = hqP->puschStartPrb;
950       puschInfo.fdAlloc.numPrb    = hqP->puschNumPrb;
951       puschInfo.tdAlloc.startSymb = hqP->strtSymbl;
952       puschInfo.tdAlloc.numSymb   = hqP->numSymbl;
953       puschInfo.tbInfo.qamOrder   = hqP->tbInfo.qamOrder;
954       puschInfo.tbInfo.mcs        = hqP->tbInfo.iMcs;
955       puschInfo.tbInfo.mcsTable   = hqP->tbInfo.mcsTable;
956       puschInfo.tbInfo.ndi        = hqP->tbInfo.ndi; /* retransmission */
957       hqP->tbInfo.rvIdx = (hqP->tbInfo.rvIdx +1) & 0x3;
958       puschInfo.tbInfo.rv         = schCmnDlRvTbl[hqP->tbInfo.rvIdx];
959       puschInfo.tbInfo.tbSize     = hqP->tbInfo.tbSzReq;
960       puschInfo.dmrsMappingType   = hqP->dmrsMappingType;  /* Setting Type-A */
961       puschInfo.nrOfDmrsSymbols   = hqP->nrOfDmrsSymbols;
962       puschInfo.dmrsAddPos        = hqP->dmrsAddPos;
963    }
964   schUlSlotInfo = cellCb->schUlSlotInfo[puschTime.slot];
965   SCH_ALLOC(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo));
966   if(!schUlSlotInfo->schPuschInfo)
967   {
968      DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schAllocMsg3Pusch");
969      return RFAILED;
970   }
971   memcpy(schUlSlotInfo->schPuschInfo, &puschInfo, sizeof(SchPuschInfo));
972
973   return ROK;
974 }
975 /*******************************************************************
976 *
977 * @brief Fills UL DCI information for MSG3 retransmission
978 *
979 * @details
980 *
981 *    Function : schFillUlDciForMsg3Retx
982 *
983 *    Functionality: fills UL DCI information for MSG3 retransmission
984 *
985 * @params[in]
986 * @return ROK     - success
987 *         RFAILED - failure
988 *
989 * ****************************************************************/
990 uint8_t schFillUlDciForMsg3Retx(SchRaCb *raCb, SchPuschInfo *puschInfo, DciInfo *dciInfo)
991 {
992    SchCellCb         *cellCb  = raCb->cell;
993    dciInfo->cellId = cellCb->cellId;
994    dciInfo->crnti  = raCb->tcrnti;
995    SchUlHqProcCb *msg3HqProc = &raCb->msg3HqProc;
996    if (msg3HqProc == NULLP)
997    {
998       return RFAILED;
999    }
1000
1001    /* fill bwp cfg */
1002    dciInfo->bwpCfg.subcarrierSpacing  = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
1003    dciInfo->bwpCfg.cyclicPrefix       = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
1004    dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb;
1005    dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb; 
1006
1007    /*fill coreset cfg */
1008    //Considering number of RBs in coreset1 is same as coreset0
1009    dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
1010    //Considering coreset1 also starts from same symbol as coreset0
1011    dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
1012    dciInfo->coresetCfg.durationSymbols  = coresetIdxTable[0][2];
1013    memcpy(dciInfo->coresetCfg.freqDomainResource, cellCb->cellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
1014    
1015    dciInfo->coresetCfg.cceRegMappingType   = 1; /* coreset0 is always interleaved */
1016    dciInfo->coresetCfg.regBundleSize       = 6; /* spec-38.211 sec 7.3.2.2 */
1017    dciInfo->coresetCfg.interleaverSize     = 2; /* spec-38.211 sec 7.3.2.2 */
1018    dciInfo->coresetCfg.coreSetType         = 0;
1019    dciInfo->coresetCfg.coreSetSize         = coresetIdxTable[0][1];
1020    dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
1021    dciInfo->coresetCfg.precoderGranularity = 0;
1022    dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
1023    dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
1024    
1025    dciInfo->formatType = FORMAT0_0;
1026    msg3HqProc->tbInfo.rvIdx++;
1027    msg3HqProc->tbInfo.rv = schCmnDlRvTbl[msg3HqProc->tbInfo.rvIdx & 0x03];
1028    /* fill UL grant */
1029    dciInfo->format.format0_0.resourceAllocType   = msg3HqProc->puschResType;
1030    dciInfo->format.format0_0.freqAlloc.startPrb  = msg3HqProc->puschStartPrb;
1031    dciInfo->format.format0_0.freqAlloc.numPrb    = msg3HqProc->puschNumPrb;
1032    dciInfo->format.format0_0.timeAlloc.startSymb = msg3HqProc->strtSymbl;
1033    dciInfo->format.format0_0.timeAlloc.numSymb   = msg3HqProc->numSymbl;
1034    dciInfo->format.format0_0.rowIndex            = 0; /* row Index */
1035    dciInfo->format.format0_0.mcs                 = msg3HqProc->tbInfo.iMcs;
1036    dciInfo->format.format0_0.harqProcId          = msg3HqProc->procId;
1037    dciInfo->format.format0_0.puschHopFlag        = FALSE; /* disabled */
1038    dciInfo->format.format0_0.freqHopFlag         = FALSE; /* disabled */
1039    dciInfo->format.format0_0.ndi                 = msg3HqProc->tbInfo.ndi; /* new transmission */
1040    dciInfo->format.format0_0.rv                  = msg3HqProc->tbInfo.rv;
1041    dciInfo->format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
1042    dciInfo->format.format0_0.sUlCfgd             = FALSE; /* SUL not configured */
1043    
1044    /* Fill DCI Structure */
1045    dciInfo->dciInfo.rnti                              = raCb->tcrnti;
1046    dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
1047    dciInfo->dciInfo.scramblingRnti                    = 0;
1048    dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
1049    dciInfo->dciInfo.aggregLevel                       = 4;
1050    dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
1051    dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
1052    dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
1053    dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
1054    dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
1055    dciInfo->dciInfo.txPdcchPower.powerValue           = 0;
1056    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
1057    dciInfo->dciInfo.pdschCfg                          = NULL; /* No DL data being sent */
1058    msg3HqProc->tbInfo.txCntr++;
1059
1060   puschInfo->crnti             = raCb->tcrnti;
1061   puschInfo->harqProcId        = msg3HqProc->procId;
1062   puschInfo->resAllocType      = msg3HqProc->puschResType;
1063   puschInfo->fdAlloc.startPrb  = msg3HqProc->puschStartPrb;
1064   puschInfo->fdAlloc.numPrb    = msg3HqProc->puschNumPrb;
1065   puschInfo->tdAlloc.startSymb = msg3HqProc->strtSymbl;
1066   puschInfo->tdAlloc.numSymb   = msg3HqProc->numSymbl;
1067   puschInfo->tbInfo.qamOrder   = msg3HqProc->tbInfo.qamOrder;
1068   puschInfo->tbInfo.mcs        = msg3HqProc->tbInfo.iMcs;
1069   puschInfo->tbInfo.mcsTable   = msg3HqProc->tbInfo.mcsTable;
1070   puschInfo->tbInfo.ndi        = msg3HqProc->tbInfo.ndi; /* retransmission */
1071   puschInfo->tbInfo.rv         = msg3HqProc->tbInfo.rvIdx;
1072   puschInfo->tbInfo.tbSize     = msg3HqProc->tbInfo.tbSzReq;
1073   puschInfo->dmrsMappingType   = msg3HqProc->dmrsMappingType;  /* Setting Type-A */
1074   puschInfo->nrOfDmrsSymbols   = msg3HqProc->nrOfDmrsSymbols;
1075   puschInfo->dmrsAddPos        = msg3HqProc->dmrsAddPos;
1076
1077    return ROK;
1078 }
1079
1080 /*******************************************************************
1081  *
1082  * @brief Fills DCI for UL grant
1083  *
1084  * @details
1085  *
1086  *    Function : schFillUlDci
1087  *
1088  *    Functionality: fills DCI for UL grant in response to BSR
1089  *
1090  * @params[in] SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo,
1091  * @params[in] bool isRetx, SchUlHqProcCb *hqP 
1092  * @return ROK     - success
1093  *         RFAILED - failure
1094  *
1095  * ****************************************************************/
1096 uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo, bool isRetx, SchUlHqProcCb *hqP)
1097 {
1098    SchCellCb         *cellCb  = ueCb->cellCb;
1099    SchControlRsrcSet coreset1 ;
1100   
1101    memset(&coreset1, 0, sizeof(SchControlRsrcSet));
1102    if(ueCb->ueCfg.spCellCfgPres == true)
1103    {
1104      coreset1 = ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdcchCfg.cRSetToAddModList[0];
1105    }
1106    
1107    dciInfo->cellId = cellCb->cellId;
1108    dciInfo->crnti  = ueCb->crnti;
1109
1110    /* fill bwp cfg */
1111    dciInfo->bwpCfg.subcarrierSpacing  = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
1112    dciInfo->bwpCfg.cyclicPrefix       = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
1113    dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb;
1114    dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb; 
1115
1116    /*fill coreset cfg */
1117    //Considering number of RBs in coreset1 is same as coreset0
1118    dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
1119    //Considering coreset1 also starts from same symbol as coreset0
1120    dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
1121    dciInfo->coresetCfg.durationSymbols  = coreset1.duration;
1122    memcpy(dciInfo->coresetCfg.freqDomainResource, coreset1.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
1123    
1124    dciInfo->coresetCfg.cceRegMappingType   = coreset1.cceRegMappingType; /* non-interleaved */
1125    dciInfo->coresetCfg.regBundleSize       = 6; /* must be 6 for non-interleaved */
1126    dciInfo->coresetCfg.interleaverSize     = 0; /* NA for non-interleaved */
1127    dciInfo->coresetCfg.coreSetType         = 1; /* non PBCH coreset */
1128    dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
1129    dciInfo->coresetCfg.precoderGranularity = coreset1.precoderGranularity;
1130    dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
1131    dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
1132    
1133    dciInfo->formatType = FORMAT0_0;
1134    
1135    /* fill UL grant */
1136    dciInfo->format.format0_0.resourceAllocType   = puschInfo->resAllocType;
1137    dciInfo->format.format0_0.freqAlloc.startPrb  = puschInfo->fdAlloc.startPrb;
1138    dciInfo->format.format0_0.freqAlloc.numPrb    = puschInfo->fdAlloc.numPrb;
1139    dciInfo->format.format0_0.timeAlloc.startSymb = puschInfo->tdAlloc.startSymb;
1140    dciInfo->format.format0_0.timeAlloc.numSymb   = puschInfo->tdAlloc.numSymb;
1141    dciInfo->format.format0_0.rowIndex            = 0; /* row Index */
1142    dciInfo->format.format0_0.mcs                 = puschInfo->tbInfo.mcs;
1143    dciInfo->format.format0_0.harqProcId          = puschInfo->harqProcId;
1144    dciInfo->format.format0_0.puschHopFlag        = FALSE; /* disabled */
1145    dciInfo->format.format0_0.freqHopFlag         = FALSE; /* disabled */
1146    dciInfo->format.format0_0.ndi                 = puschInfo->tbInfo.ndi; /* new transmission */
1147    dciInfo->format.format0_0.rv                  = puschInfo->tbInfo.rv;
1148    dciInfo->format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
1149    dciInfo->format.format0_0.sUlCfgd             = FALSE; /* SUL not configured */
1150    
1151    /* Fill DCI Structure */
1152    dciInfo->dciInfo.rnti                              = ueCb->crnti;
1153    dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
1154    dciInfo->dciInfo.scramblingRnti                    = 0;
1155    dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
1156    dciInfo->dciInfo.aggregLevel                       = 4;
1157    dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
1158    dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
1159    dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
1160    dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
1161    dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
1162    dciInfo->dciInfo.txPdcchPower.powerValue           = 0;
1163    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
1164    dciInfo->dciInfo.pdschCfg                          = NULL; /* No DL data being sent */
1165
1166    return ROK;
1167 }
1168
1169 /*******************************************************************
1170  *
1171  * @brief Function to Modify Ue Config request from MAC
1172  *
1173  * @details
1174  *
1175  *    Function : MacSchModUeConfigReq
1176  *
1177  *    Functionality: Function to modify Ue Config request from MAC
1178  *
1179  * @params[in] 
1180  * @return ROK     - success
1181  *         RFAILED - failure
1182  *
1183  * ****************************************************************/
1184 uint8_t MacSchModUeConfigReq(Pst *pst, SchUeRecfgReq *ueRecfg)
1185 {
1186    uint8_t ueId, lcIdx, ret = ROK;
1187    SchCellCb    *cellCb = NULLP;
1188    SchUeCb      *ueCb = NULLP;
1189    SchUeRecfgRsp  recfgRsp;
1190    Inst         inst = pst->dstInst - SCH_INST_START;
1191    memset(&recfgRsp, 0, sizeof(SchUeRecfgRsp));
1192   
1193 #ifdef CALL_FLOW_DEBUG_LOG
1194    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_MODIFY_UE_CONFIG_REQ_TO_SCH\n");
1195 #endif
1196
1197    if(!ueRecfg)
1198    {
1199       DU_LOG("\nERROR  -->  SCH : Modifying Ue Config request failed at MacSchModUeConfigReq()");
1200       return RFAILED;
1201    }
1202    DU_LOG("\nDEBUG  -->  SCH : Modifying Ue Config Request for CRNTI[%d]", ueRecfg->crnti);
1203    cellCb = getSchCellCb(pst->event, inst, ueRecfg->cellId);
1204
1205    if(cellCb == NULLP)
1206    {
1207       SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_NOK, &recfgRsp);
1208       return RFAILED;
1209    }
1210
1211    /* Search if UE already configured */
1212    GET_UE_ID(ueRecfg->crnti, ueId);
1213    ueCb = &cellCb->ueCb[ueId -1];
1214    
1215    if(!ueCb)
1216    {
1217       DU_LOG("\nERROR  -->  SCH : SchUeCb not found at MacSchModUeConfigReq() ");
1218       SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_NOK, &recfgRsp);
1219       return RFAILED;
1220    }
1221    if((ueCb->crnti == ueRecfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
1222    {
1223       /* Found the UeCb to Reconfig */
1224       ret = fillSchUeCbFrmRecfgReq(inst, ueCb, ueRecfg);
1225       if(ret == ROK)
1226       {
1227          ueCb->cellCb = cellCb;
1228          ueCb->srRcvd = false;
1229          ueCb->bsrRcvd = false;
1230          for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
1231             ueCb->bsrInfo[lcIdx].dataVol = 0;
1232
1233          SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_OK, &recfgRsp);
1234       }
1235    }
1236    return ret;
1237 }
1238
1239 /*******************************************************************
1240 *
1241 * @brief Fill and send UE delete response to MAC
1242 *
1243 * @details
1244 *
1245 *    Function :  SchSendUeDeleteRspToMac
1246 *
1247 *    Functionality: Fill and send UE delete response to MAC
1248 *
1249 * @params[in] Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, 
1250 *              ErrorCause cause
1251 * @return ROK     - success
1252 *         RFAILED - failure
1253 *
1254 * ****************************************************************/
1255 void SchSendUeDeleteRspToMac(Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, ErrorCause cause)
1256 {
1257     Pst rspPst;
1258     SchUeDeleteRsp  delRsp;
1259     
1260     memset(&delRsp, 0, sizeof(SchUeDeleteRsp));
1261     delRsp.cellId = ueDelete->cellId;
1262     delRsp.crnti = ueDelete->crnti;
1263     delRsp.rsp = result; 
1264     delRsp.cause = cause; 
1265
1266     /* Filling response post */
1267     memset(&rspPst, 0, sizeof(Pst));
1268     FILL_PST_SCH_TO_MAC(rspPst, inst);
1269     rspPst.event = EVENT_UE_DELETE_RSP_TO_MAC;
1270     SchUeDeleteRspOpts[rspPst.selector](&rspPst, &delRsp);
1271 }
1272
1273 /*******************************************************************
1274 *
1275 * @brief Function to delete Sch Pucch ResrcCfg
1276 *
1277 * @details
1278 *
1279 *    Function : deleteSchPucchResrcCfg 
1280 *
1281 *    Functionality: Function to delete Sch Pucch ResrcCfg
1282 *
1283 * @params[in] SchPucchResrcCfg *resrc
1284 * @return void 
1285 *
1286 * ****************************************************************/
1287
1288 void deleteSchPucchResrcCfg(SchPucchResrcCfg *resrc)
1289 {
1290    uint8_t rsrcIdx=0;
1291    for(rsrcIdx=0; rsrcIdx < resrc->resrcToAddModListCount; rsrcIdx++)
1292    {
1293       switch(resrc->resrcToAddModList[rsrcIdx].pucchFormat)
1294       {
1295          case PUCCH_FORMAT_0:
1296          {
1297             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format0,\
1298             sizeof(SchPucchFormat0));
1299             break;
1300          }
1301          case PUCCH_FORMAT_1:
1302          {
1303             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format1,\
1304             sizeof(SchPucchFormat1));
1305             break;
1306          }
1307          case PUCCH_FORMAT_2:
1308          {
1309             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format2,\
1310             sizeof(SchPucchFormat2_3));
1311             break;
1312          }
1313          case PUCCH_FORMAT_3:
1314          {
1315             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format3,\
1316             sizeof(SchPucchFormat2_3));
1317             break;
1318          }
1319          case PUCCH_FORMAT_4:
1320          {
1321             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format4,\
1322             sizeof(SchPucchFormat4));
1323             break;
1324          }
1325       }
1326    }
1327 }
1328
1329 /*******************************************************************
1330 *
1331 * @brief Function to delete SCH Pdsch ServCellCfg
1332 *
1333 * @details
1334 *
1335 *    Function : deleteSchPdschServCellCfg
1336 *
1337 *    Functionality: Function to delete SCH Pdsch ServCellCfg
1338 *
1339 * @params[in] SchPdschServCellCfg *pdschServCellCfg
1340 * @return void 
1341 *
1342 * ****************************************************************/
1343
1344 void deleteSchPdschServCellCfg(SchPdschServCellCfg *pdschServCellCfg)
1345 {
1346    SCH_FREE(pdschServCellCfg->maxMimoLayers, sizeof(uint8_t));
1347    SCH_FREE(pdschServCellCfg->maxCodeBlkGrpPerTb, sizeof(SchMaxCodeBlkGrpPerTB));
1348    SCH_FREE(pdschServCellCfg->codeBlkGrpFlushInd, sizeof(bool));
1349    SCH_FREE(pdschServCellCfg->xOverhead, sizeof(SchPdschXOverhead));
1350 }
1351
1352 /*******************************************************************
1353 *
1354 * @brief Function to  delete SCH UeCb
1355 *
1356 * @details
1357 *
1358 *    Function : deleteSchUeCb 
1359 *
1360 *    Functionality: Function to delete SCH UeCb
1361 *
1362 * @params[in]
1363 * @return ROK     - success
1364 *         RFAILED - failure
1365 *
1366 * ****************************************************************/
1367 void deleteSchUeCb(SchUeCb *ueCb) 
1368 {
1369    uint8_t timeDomRsrcIdx = 0, ueLcIdx = 0, idx =0;
1370    SchPucchCfg *pucchCfg = NULLP;
1371    SchPdschConfig *pdschCfg = NULLP;
1372
1373    if(ueCb)
1374    {
1375       if(ueCb->hqDlmap)
1376       {
1377          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1378          {
1379             if(ueCb->hqDlmap[idx])
1380             {
1381                cmLListDeleteLList(&ueCb->hqDlmap[idx]->hqList);
1382                SCH_FREE(ueCb->hqDlmap[idx], sizeof(SchHqDlMap));
1383             }
1384          }
1385          SCH_FREE(ueCb->hqDlmap, sizeof(SchHqDlMap*)*(ueCb->cellCb->numSlots));
1386       }
1387
1388       if(ueCb->hqUlmap)
1389       {
1390          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1391          {
1392             if(ueCb->hqUlmap[idx])
1393             {
1394                cmLListDeleteLList(&ueCb->hqUlmap[idx]->hqList);
1395                SCH_FREE(ueCb->hqUlmap[idx], sizeof(SchHqUlMap));
1396             }
1397          }
1398          SCH_FREE(ueCb->hqUlmap, sizeof(SchHqUlMap*)*(ueCb->cellCb->numSlots));
1399       }
1400
1401       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
1402       if(ueCb->ueCfg.spCellCfgPres)
1403       {
1404          if(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfgPres == true)
1405          {
1406             pdschCfg = &ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg;
1407             for(timeDomRsrcIdx = 0; timeDomRsrcIdx < pdschCfg->numTimeDomRsrcAlloc; timeDomRsrcIdx++)
1408                SCH_FREE(pdschCfg->timeDomRsrcAllociList[timeDomRsrcIdx].k0, sizeof(uint8_t));
1409          }
1410
1411          if(ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfgPres == true)
1412          {
1413             pucchCfg = &ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg;
1414             SCH_FREE(pucchCfg->resrcSet,sizeof(SchPucchResrcSetCfg));
1415             if(pucchCfg->resrc)
1416             {
1417                deleteSchPucchResrcCfg(pucchCfg->resrc);
1418                SCH_FREE(pucchCfg->resrc, sizeof(SchPucchResrcCfg));
1419             }
1420             SCH_FREE(pucchCfg->format1, sizeof(SchPucchFormatCfg));
1421             SCH_FREE(pucchCfg->format2, sizeof(SchPucchFormatCfg));
1422             SCH_FREE(pucchCfg->format3, sizeof(SchPucchFormatCfg));
1423             SCH_FREE(pucchCfg->format4, sizeof(SchPucchFormatCfg));
1424             SCH_FREE(pucchCfg->schedReq, sizeof(SchPucchSchedReqCfg));
1425             SCH_FREE(pucchCfg->multiCsiCfg, sizeof(SchPucchMultiCsiCfg));
1426             SCH_FREE(pucchCfg->spatialInfo, sizeof(SchPucchSpatialCfg));  
1427             SCH_FREE(pucchCfg->dlDataToUlAck, sizeof(SchPucchDlDataToUlAck));
1428             SCH_FREE(pucchCfg->powerControl,sizeof(SchPucchPowerControl));
1429          }
1430          SCH_FREE(ueCb->ueCfg.spCellCfg.servCellRecfg.bwpInactivityTmr, sizeof(uint8_t));
1431          deleteSchPdschServCellCfg(&ueCb->ueCfg.spCellCfg.servCellRecfg.pdschServCellCfg);
1432       }
1433       /*Need to Free the memory allocated for S-NSSAI*/
1434       for(ueLcIdx = 0; ueLcIdx < MAX_NUM_LC; ueLcIdx++)
1435       {
1436          SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1437          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1438       }
1439 #ifdef NR_DRX
1440       if(ueCb->ueDrxInfoPres)
1441       {
1442          /* Removing all the calculated drx configuration timer list */ 
1443          schDeleteUeDrxInfo(ueCb->cellCb, ueCb);
1444          ueCb->ueDrxInfoPres = false;
1445       }
1446 #endif
1447       memset(ueCb, 0, sizeof(SchUeCb));
1448    }
1449 }
1450
1451 /*******************************************************************
1452 *
1453 * @brief Function for Ue Delete request from MAC to SCH
1454 *
1455 * @details
1456 *
1457 *    Function : MacSchUeDeleteReq 
1458 *
1459 *    Functionality: Function for Ue Delete request from MAC to SCH
1460 *
1461 * @params[in] Pst *pst, SchUeDelete  *ueDelete
1462 * @return ROK     - success
1463 *         RFAILED - failure
1464 *
1465 * ****************************************************************/
1466 uint8_t MacSchUeDeleteReq(Pst *pst, SchUeDelete  *ueDelete)
1467 {
1468     uint8_t      idx=0, ueId=0, ueIdToDel=0, ret=ROK;
1469     ErrorCause   result;
1470     SchCellCb    *cellCb = NULLP;
1471     Inst         inst = pst->dstInst - SCH_INST_START;
1472     CmLList      *node = NULL, *next = NULL;
1473    
1474 #ifdef CALL_FLOW_DEBUG_LOG
1475     DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_UE_DELETE_REQ_TO_SCH\n");
1476 #endif
1477
1478     if(!ueDelete)
1479     {
1480        DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): Ue Delete request failed");
1481        ret = RFAILED;
1482     }
1483     DU_LOG("\nDEBUG  -->  SCH : Ue Delete request received for crnti[%d]", ueDelete->crnti);
1484     
1485     cellCb = schCb[inst].cells[idx];
1486
1487     if(cellCb->cellId != ueDelete->cellId)
1488     {
1489        DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): cell Id is not available");
1490        result =  INVALID_CELLID;
1491     }
1492     else
1493     {
1494        GET_UE_ID(ueDelete->crnti, ueId);
1495        if(( cellCb->ueCb[ueId-1].crnti == ueDelete->crnti) && ( cellCb->ueCb[ueId-1].state == SCH_UE_STATE_ACTIVE))
1496        {
1497           deleteSchUeCb(&cellCb->ueCb[ueId-1]);
1498           ueIdToDel  = ueId;
1499           /* Remove UE from ueToBeScheduled list */
1500           node = cellCb->ueToBeScheduled.first;
1501           while(node)
1502           {
1503              next = node->next;
1504              ueId = *(uint8_t *)node->node;
1505              if(ueId == ueIdToDel)
1506              {
1507                 SCH_FREE(node->node, sizeof(uint8_t));
1508                 deleteNodeFromLList(&cellCb->ueToBeScheduled, node);
1509                 break;
1510              }
1511              node = next;
1512           }
1513           cellCb->numActvUe--;
1514           result = NOT_APPLICABLE;
1515        }
1516        else
1517        {
1518           DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): SchUeCb not found");
1519           result =  INVALID_UEID;
1520        }
1521     }
1522     
1523     if(result == NOT_APPLICABLE)
1524     {
1525        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_OK, result);
1526     }
1527     else
1528     {
1529        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_NOK, result);
1530        ret = RFAILED;
1531     }
1532     return ret;
1533 }
1534
1535 /*******************************************************************
1536  *
1537  * @brief Fill and send Cell delete response to MAC
1538  *
1539  * @details
1540  *
1541  *    Function :  SchSendCellDeleteRspToMac
1542  *
1543  *    Functionality: Fill and send Cell delete response to MAC
1544  *
1545  * @params[in] SchCellDelete  *ueDelete, Inst inst, SchMacRsp result
1546  * @return ROK     - success
1547  *         RFAILED - failure
1548  *
1549  * ****************************************************************/
1550 uint8_t SchSendCellDeleteRspToMac(SchCellDeleteReq  *ueDelete, Inst inst, SchMacRsp result)
1551 {
1552    Pst rspPst;
1553    uint8_t ret=0;
1554    
1555    SchCellDeleteRsp  delRsp;
1556
1557    DU_LOG("\nINFO   --> SCH : Filling Cell Delete response");
1558    memset(&delRsp, 0, sizeof(SchCellDeleteRsp));
1559    delRsp.cellId = ueDelete->cellId;
1560    delRsp.rsp = result;
1561
1562    /* Filling response post */
1563    memset(&rspPst, 0, sizeof(Pst));
1564    FILL_PST_SCH_TO_MAC(rspPst, inst);
1565    rspPst.event = EVENT_CELL_DELETE_RSP_TO_MAC;
1566    ret =  SchCellDeleteRspOpts[rspPst.selector](&rspPst, &delRsp);
1567    if(ret == RFAILED)
1568    {
1569       DU_LOG("\nERROR  -->  SCH : SchSendCellDeleteRspToMac(): failed to send the Cell Delete response");
1570       return ret;
1571    }
1572    return ret;
1573 }
1574
1575 /*******************************************************************
1576  *
1577  * @brief Function for cellCb Deletion 
1578  *
1579  * @details
1580  *
1581  *    Function : deleteSchCellCb 
1582  *
1583  *    Functionality: Function for cellCb Deletion 
1584  *
1585  * @params[in] SchCellDelete  *cellDelete
1586  * @return ROK     - success
1587  *         RFAILED - failure
1588  *
1589  * ****************************************************************/
1590 void deleteSchCellCb(SchCellCb *cellCb)
1591 {
1592    uint8_t sliceIdx=0, slotIdx=0;
1593    CmLListCp *list=NULL;
1594    CmLList *node=NULL, *next=NULL;
1595    SchPageInfo *tempNode = NULLP;
1596
1597    if(cellCb->schDlSlotInfo)
1598    {
1599       for(slotIdx=0; slotIdx<cellCb->numSlots; slotIdx++)
1600       {
1601          list = &cellCb->schDlSlotInfo[slotIdx]->prbAlloc.freePrbBlockList;
1602          node = list->first;
1603          while(node)
1604          {
1605             next = node->next;
1606             SCH_FREE(node->node, sizeof(FreePrbBlock));
1607             deleteNodeFromLList(list, node);
1608             node = next;
1609          }
1610          SCH_FREE(cellCb->schDlSlotInfo[slotIdx], sizeof(SchDlSlotInfo));
1611       }
1612       SCH_FREE(cellCb->schDlSlotInfo, cellCb->numSlots *sizeof(SchDlSlotInfo*));
1613    }
1614
1615    if(cellCb->schUlSlotInfo)
1616    {
1617       for(slotIdx=0; slotIdx<cellCb->numSlots; slotIdx++)
1618       {
1619          list = &cellCb->schUlSlotInfo[slotIdx]->prbAlloc.freePrbBlockList;
1620          node = list->first;
1621          while(node)
1622          {
1623             next = node->next;
1624             SCH_FREE(node->node, sizeof(FreePrbBlock));
1625             deleteNodeFromLList(list, node);
1626             node = next;
1627          }
1628          SCH_FREE(cellCb->schUlSlotInfo[slotIdx], sizeof(SchUlSlotInfo));  
1629       }
1630       SCH_FREE(cellCb->schUlSlotInfo,  cellCb->numSlots * sizeof(SchUlSlotInfo*));
1631    }
1632
1633    if(cellCb->cellCfg.plmnInfoList.snssai)
1634    {
1635       for(sliceIdx=0; sliceIdx<cellCb->cellCfg.plmnInfoList.numSliceSupport; sliceIdx++)
1636       {
1637          SCH_FREE(cellCb->cellCfg.plmnInfoList.snssai[sliceIdx], sizeof(Snssai));
1638       }
1639       SCH_FREE(cellCb->cellCfg.plmnInfoList.snssai, cellCb->cellCfg.plmnInfoList.numSliceSupport*sizeof(Snssai*));
1640    }
1641    
1642    for(uint16_t idx =0; idx<MAX_SFN; idx++)
1643    {
1644       list = &cellCb->pageCb.pageIndInfoRecord[idx];
1645       node = list->first;
1646       while(node)
1647       {
1648          next = node->next;
1649          if(node->node)
1650          {
1651             tempNode = (SchPageInfo*)(node->node);
1652             SCH_FREE(tempNode->pagePdu, tempNode->msgLen);
1653             SCH_FREE(node->node,  sizeof(SchPageInfo));
1654          }
1655          deleteNodeFromLList(list, node);
1656          node = next;
1657       }
1658    }
1659
1660    /* Remove all UE from ueToBeScheduled list and deallocate */
1661    node = cellCb->ueToBeScheduled.first;
1662    while(node)
1663    {
1664       next = node->next;
1665       SCH_FREE(node->node, sizeof(uint8_t));
1666       cmLListDelFrm(&cellCb->ueToBeScheduled, node);
1667       SCH_FREE(node, sizeof(CmLList));
1668       node = next;
1669    }
1670
1671    memset(cellCb, 0, sizeof(SchCellCb));
1672
1673 }
1674
1675 /*******************************************************************
1676  *
1677  * @brief Function for cell Delete request from MAC to SCH
1678  *
1679  * @details
1680  *
1681  *    Function : MacSchCellDeleteReq
1682  *
1683  *    Functionality: Function for cell Delete request from MAC to SCH
1684  *
1685  * @params[in] Pst *pst, SchCellDelete  *cellDelete
1686  * @return ROK     - success
1687  *         RFAILED - failure
1688  *
1689  * ****************************************************************/
1690
1691 uint8_t MacSchCellDeleteReq(Pst *pst, SchCellDeleteReq  *cellDelete)
1692 {
1693    uint8_t   cellIdx=0, ret = RFAILED;
1694    Inst      inst = pst->dstInst - SCH_INST_START;
1695    SchMacRsp result= RSP_OK;
1696    
1697 #ifdef CALL_FLOW_DEBUG_LOG
1698    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_CELL_DELETE_REQ_TO_SCH\n");
1699 #endif   
1700
1701    if(!cellDelete)
1702    {
1703       DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): Ue Delete request failed");
1704    }
1705    else
1706    {
1707       GET_CELL_IDX(cellDelete->cellId, cellIdx);
1708       if(schCb[inst].cells[cellIdx] == NULLP)
1709       { 
1710          DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): cell Id[%d] is not available", cellDelete->cellId);
1711          result = RSP_NOK;
1712       }
1713       else
1714       {
1715          if(schCb[inst].cells[cellIdx]->cellId == cellDelete->cellId)
1716          {
1717             deleteSchCellCb(schCb[inst].cells[cellIdx]);
1718             result = RSP_OK;
1719             ret = ROK;
1720             SCH_FREE(schCb[inst].cells[cellIdx], sizeof(SchCellCb));
1721             DU_LOG("\nINFO   -->  SCH : Sending Cell Delete response to MAC");
1722          }
1723          else
1724          {
1725             DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): cell Id[%d] is not available",cellDelete->cellId);
1726             result = RSP_NOK;
1727          }
1728       }
1729
1730       if(SchSendCellDeleteRspToMac(cellDelete, inst, result)!=ROK)
1731       {
1732          DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): failed to send Cell Delete response");
1733          ret =  RFAILED;
1734       }
1735    }
1736    return ret;   
1737 }
1738 /*******************************************************************
1739  *
1740  * @brief Function updates DL HARQ Feedback
1741  *
1742  * @details
1743  *
1744  *    Function : schUpdateHarqFdbk
1745  *
1746  *    Functionality: Function updates DL HARQ feedback
1747  *
1748  * @params[in] SchUeCb *ueCb, UE cb struct pointer
1749  * @params[in] uint8_t numHarq, number of HARQ processes in feedback 
1750  * @params[in] uint8_t *harqPayload, harq feedback payload received
1751  * @params[in] SlotTimingInfo *slotInd, slot timing information
1752  * @return void
1753  *
1754  * ****************************************************************/
1755 void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload, SlotTimingInfo *slotInd)
1756 {
1757    SchDlHqProcCb *hqP;
1758    SchHqDlMap *hqDlMap;
1759    CmLList  *node;
1760    uint8_t fdbkPos = 0;
1761
1762    hqDlMap = ueCb->hqDlmap[slotInd->slot];
1763
1764    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState == SCH_RA_STATE_MSG2_HANDLE)
1765    {
1766       return;
1767    }
1768    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState != SCH_RA_STATE_MSG4_PENDING)
1769    {
1770       node = hqDlMap->hqList.first;
1771       while(node)
1772       {
1773          hqP = (SchDlHqProcCb*)node->node;
1774          node = node->next;
1775          cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1776          /* 
1777             Decode harq feedback if needed post FAPI message decoding also or check how to decode this FAPI msg.
1778             case 1 semi static harq Ack/Nack codebook //Supported
1779             case 2 dynamic harq ACK/NACK codebook //Not supported
1780          */
1781          schDlHqFeedbackUpdate(hqP, harqPayload[fdbkPos++], HQ_TB_ACKED);//Marking 2nd TB as ACKED for now as only one TB to be used
1782       }
1783    }
1784    else
1785    {
1786       node = hqDlMap->hqList.first;
1787       hqP = (SchDlHqProcCb*)node->node;
1788       cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1789       schMsg4FeedbackUpdate(hqP, harqPayload[fdbkPos++]);
1790    }
1791 }
1792 /**********************************************************************
1793   End of file
1794  **********************************************************************/