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