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