d28babbb322f92be6b357230f482d3802e8939f4
[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    CmLList *sliceCfg = schCb[inst].sliceCfg.first;
204    SchRrmPolicyOfSlice *rrmPolicyOfSlices;
205
206    while(sliceCfg)
207    {
208       rrmPolicyOfSlices = (SchRrmPolicyOfSlice*)sliceCfg->node;
209       if(rrmPolicyOfSlices && (memcmp(snssai, &(rrmPolicyOfSlices->snssai), sizeof(Snssai)) == 0))
210       {
211          /*Updating latest RrmPolicy*/
212          *rsvdDedicatedPRB = \
213                              (uint16_t)(((rrmPolicyOfSlices->rrmPolicyRatioInfo.dedicatedRatio)*(MAX_NUM_RB))/100);
214          *isDedicated = TRUE;
215          DU_LOG("\nINFO  -->  SCH : Updated RRM policy, reservedPOOL:%d",*rsvdDedicatedPRB);
216          break;
217       }
218       sliceCfg = sliceCfg->next;
219    }
220    /*case: This LcCtxt  is either a Default LC or this LC is part of someother RRM_MemberList*/
221    if(*isDedicated != TRUE) 
222    {
223       DU_LOG("\nINFO  -->  SCH : This SNSSAI is not a part of this RRMPolicy");
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    
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->sib1SchCfg.bwp.subcarrierSpacing;
976    dciInfo->bwpCfg.cyclicPrefix       = cellCb->sib1SchCfg.bwp.cyclicPrefix;
977    dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.dlCfgCommon.schInitialDlBwp.bwp.freqAlloc.startPrb;
978    dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.dlCfgCommon.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.dlCfgCommon.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->dciFormatInfo.formatType = FORMAT0_0;
999    msg3HqProc->tbInfo.rvIdx++;
1000    msg3HqProc->tbInfo.rv = schCmnDlRvTbl[msg3HqProc->tbInfo.rvIdx & 0x03];
1001    /* fill UL grant */
1002    dciInfo->dciFormatInfo.format.format0_0.resourceAllocType                  = msg3HqProc->puschResType;
1003    dciInfo->dciFormatInfo.format.format0_0.freqAlloc.resAllocType             = msg3HqProc->puschResType;
1004    dciInfo->dciFormatInfo.format.format0_0.freqAlloc.resAlloc.type1.startPrb  = msg3HqProc->puschStartPrb;
1005    dciInfo->dciFormatInfo.format.format0_0.freqAlloc.resAlloc.type1.numPrb    = msg3HqProc->puschNumPrb;
1006    dciInfo->dciFormatInfo.format.format0_0.timeAlloc.startSymb = msg3HqProc->strtSymbl;
1007    dciInfo->dciFormatInfo.format.format0_0.timeAlloc.numSymb   = msg3HqProc->numSymbl;
1008    dciInfo->dciFormatInfo.format.format0_0.rowIndex            = 0; /* row Index */
1009    dciInfo->dciFormatInfo.format.format0_0.mcs                 = msg3HqProc->tbInfo.iMcs;
1010    dciInfo->dciFormatInfo.format.format0_0.harqProcId          = msg3HqProc->procId;
1011    dciInfo->dciFormatInfo.format.format0_0.freqHopFlag         = FALSE; /* disabled */
1012    dciInfo->dciFormatInfo.format.format0_0.ndi                 = msg3HqProc->tbInfo.ndi; /* new transmission */
1013    dciInfo->dciFormatInfo.format.format0_0.rvIndex             = msg3HqProc->tbInfo.rv;
1014    dciInfo->dciFormatInfo.format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
1015    dciInfo->dciFormatInfo.format.format0_0.sulIndicator             = 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.beta_pdcch_1_0       = 0;
1029    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
1030    memset(&dciInfo->dciInfo.pdschCfg, 0, sizeof(PdschCfg));
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->crnti  = ueCb->crnti;
1081
1082    /* fill bwp cfg */
1083    dciInfo->bwpCfg.subcarrierSpacing  = cellCb->sib1SchCfg.bwp.subcarrierSpacing;
1084    dciInfo->bwpCfg.cyclicPrefix       = cellCb->sib1SchCfg.bwp.cyclicPrefix;
1085    dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.dlCfgCommon.schInitialDlBwp.bwp.freqAlloc.startPrb;
1086    dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.dlCfgCommon.schInitialDlBwp.bwp.freqAlloc.numPrb; 
1087
1088    /*fill coreset cfg */
1089    //Considering number of RBs in coreset1 is same as coreset0
1090    dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
1091    //Considering coreset1 also starts from same symbol as coreset0
1092    dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
1093    dciInfo->coresetCfg.durationSymbols  = coreset1.duration;
1094    memcpy(dciInfo->coresetCfg.freqDomainResource, coreset1.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
1095    
1096    dciInfo->coresetCfg.cceRegMappingType   = coreset1.cceRegMappingType; /* non-interleaved */
1097    dciInfo->coresetCfg.regBundleSize       = 6; /* must be 6 for non-interleaved */
1098    dciInfo->coresetCfg.interleaverSize     = 0; /* NA for non-interleaved */
1099    dciInfo->coresetCfg.coreSetType         = 1; /* non PBCH coreset */
1100    dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
1101    dciInfo->coresetCfg.precoderGranularity = coreset1.precoderGranularity;
1102    dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
1103    dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
1104    
1105    dciInfo->dciFormatInfo.formatType = FORMAT0_0;
1106    
1107    /* fill UL grant */
1108    dciInfo->dciFormatInfo.format.format0_0.resourceAllocType   = puschInfo->fdAlloc.resAllocType;
1109    dciInfo->dciFormatInfo.format.format0_0.freqAlloc.resAllocType = puschInfo->fdAlloc.resAllocType;
1110    dciInfo->dciFormatInfo.format.format0_0.freqAlloc.resAlloc.type1.startPrb  = \
1111    puschInfo->fdAlloc.resAlloc.type1.startPrb;
1112    dciInfo->dciFormatInfo.format.format0_0.freqAlloc.resAlloc.type1.numPrb    = \
1113    puschInfo->fdAlloc.resAlloc.type1.numPrb;
1114    dciInfo->dciFormatInfo.format.format0_0.timeAlloc.startSymb = puschInfo->tdAlloc.startSymb;
1115    dciInfo->dciFormatInfo.format.format0_0.timeAlloc.numSymb   = puschInfo->tdAlloc.numSymb;
1116    dciInfo->dciFormatInfo.format.format0_0.rowIndex            = 0; /* row Index */
1117    dciInfo->dciFormatInfo.format.format0_0.mcs                 = puschInfo->tbInfo.mcs;
1118    dciInfo->dciFormatInfo.format.format0_0.harqProcId          = puschInfo->harqProcId;
1119    dciInfo->dciFormatInfo.format.format0_0.freqHopFlag         = FALSE; /* disabled */
1120    dciInfo->dciFormatInfo.format.format0_0.ndi                 = puschInfo->tbInfo.ndi; /* new transmission */
1121    dciInfo->dciFormatInfo.format.format0_0.rvIndex             = puschInfo->tbInfo.rv;
1122    dciInfo->dciFormatInfo.format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
1123    dciInfo->dciFormatInfo.format.format0_0.sulIndicator             = FALSE; /* SUL not configured */
1124    
1125    /* Fill DCI Structure */
1126    dciInfo->dciInfo.rnti                              = ueCb->crnti;
1127    dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
1128    dciInfo->dciInfo.scramblingRnti                    = 0;
1129    dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
1130    dciInfo->dciInfo.aggregLevel                       = 4;
1131    dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
1132    dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
1133    dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
1134    dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
1135    dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
1136    dciInfo->dciInfo.txPdcchPower.beta_pdcch_1_0       = 0;
1137    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
1138    memset(&dciInfo->dciInfo.pdschCfg, 0, sizeof(PdschCfg));
1139
1140    return ROK;
1141 }
1142
1143 /*******************************************************************
1144  *
1145  * @brief Function to Modify Ue Config request from MAC
1146  *
1147  * @details
1148  *
1149  *    Function : SchModUeConfigReq
1150  *
1151  *    Functionality: Function to modify Ue Config request from MAC
1152  *
1153  * @params[in] 
1154  * @return ROK     - success
1155  *         RFAILED - failure
1156  *
1157  * ****************************************************************/
1158 uint8_t SchModUeConfigReq(Pst *pst, SchUeRecfgReq *ueRecfg)
1159 {
1160    uint8_t ueId, lcIdx, ret = ROK;
1161    SchCellCb    *cellCb = NULLP;
1162    SchUeCb      *ueCb = NULLP;
1163    SchUeRecfgRsp  recfgRsp;
1164    Inst         inst = pst->dstInst - SCH_INST_START;
1165    memset(&recfgRsp, 0, sizeof(SchUeRecfgRsp));
1166   
1167    if(!ueRecfg)
1168    {
1169       DU_LOG("\nERROR  -->  SCH : Modifying Ue Config request failed at SchModUeConfigReq()");
1170       return RFAILED;
1171    }
1172    DU_LOG("\nDEBUG  -->  SCH : Modifying Ue Config Request for CRNTI[%d]", ueRecfg->crnti);
1173    cellCb = getSchCellCb(pst->event, inst, ueRecfg->cellId);
1174
1175    if(cellCb == NULLP)
1176    {
1177       SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_NOK, &recfgRsp);
1178       return RFAILED;
1179    }
1180
1181    /* Search if UE already configured */
1182    GET_UE_ID(ueRecfg->crnti, ueId);
1183    ueCb = &cellCb->ueCb[ueId -1];
1184    
1185    if(!ueCb)
1186    {
1187       DU_LOG("\nERROR  -->  SCH : SchUeCb not found at SchModUeConfigReq() ");
1188       SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_NOK, &recfgRsp);
1189       return RFAILED;
1190    }
1191    if((ueCb->crnti == ueRecfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
1192    {
1193       /* Found the UeCb to Reconfig */
1194       ret = fillSchUeCbFrmRecfgReq(inst, ueCb, ueRecfg);
1195       if(ret == ROK)
1196       {
1197          ueCb->cellCb = cellCb;
1198          ueCb->srRcvd = false;
1199          ueCb->bsrRcvd = false;
1200          for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
1201             ueCb->bsrInfo[lcIdx].dataVol = 0;
1202
1203          SchSendUeRecfgRspToMac(ueRecfg, inst, RSP_OK, &recfgRsp);
1204       }
1205    }
1206    return ret;
1207 }
1208
1209
1210 /*******************************************************************
1211 *
1212 * @brief Function to delete Sch Pucch ResrcCfg
1213 *
1214 * @details
1215 *
1216 *    Function : deleteSchPucchResrcCfg 
1217 *
1218 *    Functionality: Function to delete Sch Pucch ResrcCfg
1219 *
1220 * @params[in] SchPucchResrcCfg *resrc
1221 * @return void 
1222 *
1223 * ****************************************************************/
1224
1225 void deleteSchPucchResrcCfg(SchPucchResrcCfg *resrc)
1226 {
1227    uint8_t rsrcIdx=0;
1228    for(rsrcIdx=0; rsrcIdx < resrc->resrcToAddModListCount; rsrcIdx++)
1229    {
1230       switch(resrc->resrcToAddModList[rsrcIdx].pucchFormat)
1231       {
1232          case PUCCH_FORMAT_0:
1233          {
1234             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format0,\
1235             sizeof(SchPucchFormat0));
1236             break;
1237          }
1238          case PUCCH_FORMAT_1:
1239          {
1240             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format1,\
1241             sizeof(SchPucchFormat1));
1242             break;
1243          }
1244          case PUCCH_FORMAT_2:
1245          {
1246             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format2,\
1247             sizeof(SchPucchFormat2_3));
1248             break;
1249          }
1250          case PUCCH_FORMAT_3:
1251          {
1252             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format3,\
1253             sizeof(SchPucchFormat2_3));
1254             break;
1255          }
1256          case PUCCH_FORMAT_4:
1257          {
1258             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format4,\
1259             sizeof(SchPucchFormat4));
1260             break;
1261          }
1262       }
1263    }
1264 }
1265
1266 /*******************************************************************
1267 *
1268 * @brief Function to delete SCH Pdsch ServCellCfg
1269 *
1270 * @details
1271 *
1272 *    Function : deleteSchPdschServCellCfg
1273 *
1274 *    Functionality: Function to delete SCH Pdsch ServCellCfg
1275 *
1276 * @params[in] SchPdschServCellCfg *pdschServCellCfg
1277 * @return void 
1278 *
1279 * ****************************************************************/
1280
1281 void deleteSchPdschServCellCfg(SchPdschServCellCfg *pdschServCellCfg)
1282 {
1283    SCH_FREE(pdschServCellCfg->maxMimoLayers, sizeof(uint8_t));
1284    SCH_FREE(pdschServCellCfg->maxCodeBlkGrpPerTb, sizeof(SchMaxCodeBlkGrpPerTB));
1285    SCH_FREE(pdschServCellCfg->codeBlkGrpFlushInd, sizeof(bool));
1286    SCH_FREE(pdschServCellCfg->xOverhead, sizeof(SchPdschXOverhead));
1287 }
1288
1289 /*******************************************************************
1290 *
1291 * @brief Function to  delete SCH UeCb
1292 *
1293 * @details
1294 *
1295 *    Function : deleteSchUeCb 
1296 *
1297 *    Functionality: Function to delete SCH UeCb
1298 *
1299 * @params[in]
1300 * @return ROK     - success
1301 *         RFAILED - failure
1302 *
1303 * ****************************************************************/
1304 void deleteSchUeCb(SchUeCb *ueCb) 
1305 {
1306    uint8_t timeDomRsrcIdx = 0, ueLcIdx = 0, idx =0;
1307    SchPucchCfg *pucchCfg = NULLP;
1308    SchPdschConfig *pdschCfg = NULLP;
1309
1310    if(ueCb)
1311    {
1312       if(ueCb->hqDlmap)
1313       {
1314          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1315          {
1316             if(ueCb->hqDlmap[idx])
1317             {
1318                cmLListDeleteLList(&ueCb->hqDlmap[idx]->hqList);
1319                SCH_FREE(ueCb->hqDlmap[idx], sizeof(SchHqDlMap));
1320             }
1321          }
1322          SCH_FREE(ueCb->hqDlmap, sizeof(SchHqDlMap*)*(ueCb->cellCb->numSlots));
1323       }
1324
1325       if(ueCb->hqUlmap)
1326       {
1327          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1328          {
1329             if(ueCb->hqUlmap[idx])
1330             {
1331                cmLListDeleteLList(&ueCb->hqUlmap[idx]->hqList);
1332                SCH_FREE(ueCb->hqUlmap[idx], sizeof(SchHqUlMap));
1333             }
1334          }
1335          SCH_FREE(ueCb->hqUlmap, sizeof(SchHqUlMap*)*(ueCb->cellCb->numSlots));
1336       }
1337
1338       schDlHqEntDelete(ueCb);
1339       schUlHqEntDelete(ueCb);
1340
1341       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
1342       if(ueCb->ueCfg.spCellCfgPres)
1343       {
1344          if(ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfgPres == true)
1345          {
1346             pdschCfg = &ueCb->ueCfg.spCellCfg.servCellRecfg.initDlBwp.pdschCfg;
1347             for(timeDomRsrcIdx = 0; timeDomRsrcIdx < pdschCfg->numTimeDomRsrcAlloc; timeDomRsrcIdx++)
1348                SCH_FREE(pdschCfg->timeDomRsrcAllociList[timeDomRsrcIdx].k0, sizeof(uint8_t));
1349          }
1350
1351          if(ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfgPres == true)
1352          {
1353             pucchCfg = &ueCb->ueCfg.spCellCfg.servCellRecfg.initUlBwp.pucchCfg;
1354             SCH_FREE(pucchCfg->resrcSet,sizeof(SchPucchResrcSetCfg));
1355             if(pucchCfg->resrc)
1356             {
1357                deleteSchPucchResrcCfg(pucchCfg->resrc);
1358                SCH_FREE(pucchCfg->resrc, sizeof(SchPucchResrcCfg));
1359             }
1360             SCH_FREE(pucchCfg->format1, sizeof(SchPucchFormatCfg));
1361             SCH_FREE(pucchCfg->format2, sizeof(SchPucchFormatCfg));
1362             SCH_FREE(pucchCfg->format3, sizeof(SchPucchFormatCfg));
1363             SCH_FREE(pucchCfg->format4, sizeof(SchPucchFormatCfg));
1364             SCH_FREE(pucchCfg->schedReq, sizeof(SchPucchSchedReqCfg));
1365             SCH_FREE(pucchCfg->multiCsiCfg, sizeof(SchPucchMultiCsiCfg));
1366             SCH_FREE(pucchCfg->spatialInfo, sizeof(SchPucchSpatialCfg));  
1367             SCH_FREE(pucchCfg->dlDataToUlAck, sizeof(SchPucchDlDataToUlAck));
1368             SCH_FREE(pucchCfg->powerControl,sizeof(SchPucchPowerControl));
1369          }
1370          SCH_FREE(ueCb->ueCfg.spCellCfg.servCellRecfg.bwpInactivityTmr, sizeof(uint8_t));
1371          deleteSchPdschServCellCfg(&ueCb->ueCfg.spCellCfg.servCellRecfg.pdschServCellCfg);
1372       }
1373       /*Need to Free the memory allocated for S-NSSAI*/
1374       for(ueLcIdx = 0; ueLcIdx < MAX_NUM_LC; ueLcIdx++)
1375       {
1376          SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1377          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1378       }
1379 #ifdef NR_DRX
1380       if(ueCb->ueDrxInfoPres)
1381       {
1382          /* Removing all the calculated drx configuration timer list */ 
1383          schDeleteUeDrxInfo(ueCb->cellCb, ueCb);
1384          ueCb->ueDrxInfoPres = false;
1385       }
1386 #endif
1387       memset(ueCb, 0, sizeof(SchUeCb));
1388    }
1389 }
1390
1391 /*******************************************************************
1392 *
1393 * @brief Fill and send UE delete response to MAC
1394 *
1395 * @details
1396 *
1397 *    Function :  SchSendUeDeleteRspToMac
1398 *
1399 *    Functionality: Fill and send UE delete response to MAC
1400 *
1401 * @params[in] Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, 
1402 *              ErrorCause cause
1403 * @return ROK     - success
1404 *         RFAILED - failure
1405 *
1406 * ****************************************************************/
1407 void SchSendUeDeleteRspToMac(Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, ErrorCause cause)
1408 {
1409     Pst rspPst;
1410     SchUeDeleteRsp  delRsp;
1411     
1412     memset(&delRsp, 0, sizeof(SchUeDeleteRsp));
1413     delRsp.cellId = ueDelete->cellId;
1414     delRsp.crnti = ueDelete->crnti;
1415     delRsp.rsp = result; 
1416     delRsp.cause = cause; 
1417
1418     /* Filling response post */
1419     memset(&rspPst, 0, sizeof(Pst));
1420     FILL_PST_SCH_TO_MAC(rspPst, inst);
1421     rspPst.event = EVENT_UE_DELETE_RSP_TO_MAC;
1422     MacMessageRouter(&rspPst, (void *)&delRsp);
1423 }
1424
1425 /*******************************************************************
1426 *
1427 * @brief Function for Ue Delete request from MAC to SCH
1428 *
1429 * @details
1430 *
1431 *    Function : SchProcUeDeleteReq 
1432 *
1433 *    Functionality: Function for Ue Delete request from MAC to SCH
1434 *
1435 * @params[in] Pst *pst, SchUeDelete  *ueDelete
1436 * @return ROK     - success
1437 *         RFAILED - failure
1438 *
1439 * ****************************************************************/
1440 uint8_t SchProcUeDeleteReq(Pst *pst, SchUeDelete  *ueDelete)
1441 {
1442     uint8_t      idx=0, ueId=0, ret=ROK;
1443     ErrorCause   result;
1444     SchCellCb    *cellCb = NULLP;
1445     Inst         inst = pst->dstInst - SCH_INST_START;
1446    
1447     if(!ueDelete)
1448     {
1449        DU_LOG("\nERROR  -->  SCH : SchProcUeDeleteReq(): Ue Delete request failed");
1450        ret = RFAILED;
1451     }
1452     DU_LOG("\nDEBUG  -->  SCH : Ue Delete request received for crnti[%d]", ueDelete->crnti);
1453     
1454     cellCb = schCb[inst].cells[idx];
1455
1456     if(cellCb->cellId != ueDelete->cellId)
1457     {
1458        DU_LOG("\nERROR  -->  SCH : SchProcUeDeleteReq(): cell Id is not available");
1459        result =  INVALID_CELLID;
1460     }
1461     else
1462     {
1463        GET_UE_ID(ueDelete->crnti, ueId);
1464        if(( cellCb->ueCb[ueId-1].crnti == ueDelete->crnti) && ( cellCb->ueCb[ueId-1].state == SCH_UE_STATE_ACTIVE))
1465        {
1466           /* Remove UE from ueToBeScheduled list */
1467           cellCb->api->SchUeDeleteReq(&cellCb->ueCb[ueId-1]);
1468           deleteSchUeCb(&cellCb->ueCb[ueId-1]);
1469           cellCb->numActvUe--;
1470           result = NOT_APPLICABLE;
1471        }
1472        else
1473        {
1474           DU_LOG("\nERROR  -->  SCH : SchProcUeDeleteReq(): SchUeCb not found");
1475           result =  INVALID_UEID;
1476        }
1477     }
1478     
1479     if(result == NOT_APPLICABLE)
1480     {
1481        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_OK, result);
1482     }
1483     else
1484     {
1485        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_NOK, result);
1486        ret = RFAILED;
1487     }
1488     return ret;
1489 }
1490
1491 /*******************************************************************
1492  *
1493  * @brief Function updates DL HARQ Feedback
1494  *
1495  * @details
1496  *
1497  *    Function : schUpdateHarqFdbk
1498  *
1499  *    Functionality: Function updates DL HARQ feedback
1500  *
1501  * @params[in] SchUeCb *ueCb, UE cb struct pointer
1502  * @params[in] uint8_t numHarq, number of HARQ processes in feedback 
1503  * @params[in] uint8_t *harqPayload, harq feedback payload received
1504  * @params[in] SlotTimingInfo *slotInd, slot timing information
1505  * @return void
1506  *
1507  * ****************************************************************/
1508 void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload, SlotTimingInfo *slotInd)
1509 {
1510    SchDlHqProcCb *hqP;
1511    SchHqDlMap *hqDlMap;
1512    CmLList  *node;
1513    uint8_t fdbkPos = 0;
1514
1515    hqDlMap = ueCb->hqDlmap[slotInd->slot];
1516
1517    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState == SCH_RA_STATE_MSG2_HANDLE)
1518    {
1519       return;
1520    }
1521    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState != SCH_RA_STATE_MSG4_PENDING)
1522    {
1523       node = hqDlMap->hqList.first;
1524       while(node)
1525       {
1526          hqP = (SchDlHqProcCb*)node->node;
1527          node = node->next;
1528          cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1529          /* 
1530             Decode harq feedback if needed post FAPI message decoding also or check how to decode this FAPI msg.
1531             case 1 semi static harq Ack/Nack codebook //Supported
1532             case 2 dynamic harq ACK/NACK codebook //Not supported
1533          */
1534          schDlHqFeedbackUpdate(hqP, harqPayload[fdbkPos++], HQ_TB_ACKED);//Marking 2nd TB as ACKED for now as only one TB to be used
1535       }
1536    }
1537    else
1538    {
1539       node = hqDlMap->hqList.first;
1540       hqP = (SchDlHqProcCb*)node->node;
1541       cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1542       schMsg4FeedbackUpdate(hqP, harqPayload[fdbkPos++]);
1543    }
1544 }
1545 /**********************************************************************
1546   End of file
1547  **********************************************************************/