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