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