[Issue Id-ODUHIGH-457] Fixes related to memory leak
[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, idx =0;
1073    SchPucchCfg *pucchCfg = NULLP;
1074    SchPdschConfig *pdschCfg = NULLP;
1075    CmLList *node = NULLP, *next = NULLP;
1076
1077    if(ueCb)
1078    {
1079       if(ueCb->hqDlmap)
1080       {
1081          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1082          {
1083             if(ueCb->hqDlmap[idx])
1084             {
1085                cmLListDeleteLList(&ueCb->hqDlmap[idx]->hqList);
1086                SCH_FREE(ueCb->hqDlmap[idx], sizeof(SchHqDlMap));
1087             }
1088          }
1089          SCH_FREE(ueCb->hqDlmap, sizeof(SchHqDlMap*)*(ueCb->cellCb->numSlots));
1090       }
1091
1092       if(ueCb->hqUlmap)
1093       {
1094          for (idx = 0; idx<ueCb->cellCb->numSlots; idx++)
1095          {
1096             if(ueCb->hqUlmap[idx])
1097             {
1098                cmLListDeleteLList(&ueCb->hqUlmap[idx]->hqList);
1099                SCH_FREE(ueCb->hqUlmap[idx], sizeof(SchHqUlMap));
1100             }
1101          }
1102          SCH_FREE(ueCb->hqUlmap, sizeof(SchHqUlMap*)*(ueCb->cellCb->numSlots));
1103       }
1104
1105       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
1106       if(ueCb->ueCfg.spCellCfgPres)
1107       {
1108          if(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfgPres == true)
1109          {
1110             pdschCfg = &ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg;
1111             for(timeDomRsrcIdx = 0; timeDomRsrcIdx < pdschCfg->numTimeDomRsrcAlloc; timeDomRsrcIdx++)
1112                SCH_FREE(pdschCfg->timeDomRsrcAllociList[timeDomRsrcIdx].k0, sizeof(uint8_t));
1113          }
1114
1115          if(ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfgPres == true)
1116          {
1117             pucchCfg = &ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg;
1118             SCH_FREE(pucchCfg->resrcSet,sizeof(SchPucchResrcSetCfg));
1119             if(pucchCfg->resrc)
1120             {
1121                deleteSchPucchResrcCfg(pucchCfg->resrc);
1122                SCH_FREE(pucchCfg->resrc, sizeof(SchPucchResrcCfg));
1123             }
1124             SCH_FREE(pucchCfg->format1, sizeof(SchPucchFormatCfg));
1125             SCH_FREE(pucchCfg->format2, sizeof(SchPucchFormatCfg));
1126             SCH_FREE(pucchCfg->format3, sizeof(SchPucchFormatCfg));
1127             SCH_FREE(pucchCfg->format4, sizeof(SchPucchFormatCfg));
1128             SCH_FREE(pucchCfg->schedReq, sizeof(SchPucchSchedReqCfg));
1129             SCH_FREE(pucchCfg->multiCsiCfg, sizeof(SchPucchMultiCsiCfg));
1130             SCH_FREE(pucchCfg->spatialInfo, sizeof(SchPucchSpatialCfg));  
1131             SCH_FREE(pucchCfg->dlDataToUlAck, sizeof(SchPucchDlDataToUlAck));
1132             SCH_FREE(pucchCfg->powerControl,sizeof(SchPucchPowerControl));
1133          }
1134          SCH_FREE(ueCb->ueCfg.spCellCfg.servCellCfg.bwpInactivityTmr, sizeof(uint8_t));
1135          deleteSchPdschServCellCfg(&ueCb->ueCfg.spCellCfg.servCellCfg.pdschServCellCfg);
1136       }
1137       /*Need to Free the memory allocated for S-NSSAI*/
1138       for(ueLcIdx = 0; ueLcIdx < MAX_NUM_LC; ueLcIdx++)
1139       {
1140          SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1141          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
1142       }
1143
1144       memset(ueCb, 0, sizeof(SchUeCb));
1145    }
1146 }
1147
1148 /*******************************************************************
1149 *
1150 * @brief Function for Ue Delete request from MAC to SCH
1151 *
1152 * @details
1153 *
1154 *    Function : MacSchUeDeleteReq 
1155 *
1156 *    Functionality: Function for Ue Delete request from MAC to SCH
1157 *
1158 * @params[in] Pst *pst, SchUeDelete  *ueDelete
1159 * @return ROK     - success
1160 *         RFAILED - failure
1161 *
1162 * ****************************************************************/
1163 uint8_t MacSchUeDeleteReq(Pst *pst, SchUeDelete  *ueDelete)
1164 {
1165     uint8_t      idx=0, ueId=0, ueIdToDel=0, ret=ROK;
1166     ErrorCause   result;
1167     SchCellCb    *cellCb = NULLP;
1168     Inst         inst = pst->dstInst - SCH_INST_START;
1169     CmLList      *node = NULL, *next = NULL;
1170    
1171 #ifdef CALL_FLOW_DEBUG_LOG
1172     DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_UE_DELETE_REQ_TO_SCH\n");
1173 #endif
1174
1175     if(!ueDelete)
1176     {
1177        DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): Ue Delete request failed");
1178        ret = RFAILED;
1179     }
1180     DU_LOG("\nDEBUG  -->  SCH : Ue Delete request received for crnti[%d]", ueDelete->crnti);
1181     
1182     cellCb = schCb[inst].cells[idx];
1183
1184     if(cellCb->cellId != ueDelete->cellId)
1185     {
1186        DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): cell Id is not available");
1187        result =  INVALID_CELLID;
1188     }
1189     else
1190     {
1191        GET_UE_ID(ueDelete->crnti, ueId);
1192        if(( cellCb->ueCb[ueId-1].crnti == ueDelete->crnti) && ( cellCb->ueCb[ueId-1].state == SCH_UE_STATE_ACTIVE))
1193        {
1194           deleteSchUeCb(&cellCb->ueCb[ueId-1]);
1195           ueIdToDel  = ueId;
1196           /* Remove UE from ueToBeScheduled list */
1197           node = cellCb->ueToBeScheduled.first;
1198           while(node)
1199           {
1200              next = node->next;
1201              ueId = *(uint8_t *)node->node;
1202              if(ueId == ueIdToDel)
1203              {
1204                 SCH_FREE(node->node, sizeof(uint8_t));
1205                 deleteNodeFromLList(&cellCb->ueToBeScheduled, node);
1206                 break;
1207              }
1208              node = next;
1209           }
1210           cellCb->numActvUe--;
1211           result = NOT_APPLICABLE;
1212        }
1213        else
1214        {
1215           DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): SchUeCb not found");
1216           result =  INVALID_UEID;
1217        }
1218     }
1219     
1220     if(result == NOT_APPLICABLE)
1221     {
1222        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_OK, result);
1223     }
1224     else
1225     {
1226        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_NOK, result);
1227        ret = RFAILED;
1228     }
1229     return ret;
1230 }
1231
1232 /*******************************************************************
1233  *
1234  * @brief Fill and send Cell delete response to MAC
1235  *
1236  * @details
1237  *
1238  *    Function :  SchSendCellDeleteRspToMac
1239  *
1240  *    Functionality: Fill and send Cell delete response to MAC
1241  *
1242  * @params[in] SchCellDelete  *ueDelete, Inst inst, SchMacRsp result
1243  * @return ROK     - success
1244  *         RFAILED - failure
1245  *
1246  * ****************************************************************/
1247 uint8_t SchSendCellDeleteRspToMac(SchCellDelete  *ueDelete, Inst inst, SchMacRsp result)
1248 {
1249    Pst rspPst;
1250    uint8_t ret=0;
1251    
1252    SchCellDeleteRsp  delRsp;
1253
1254    DU_LOG("\nINFO   --> SCH : Filling Cell Delete response");
1255    memset(&delRsp, 0, sizeof(SchCellDeleteRsp));
1256    delRsp.cellId = ueDelete->cellId;
1257    delRsp.rsp = result;
1258
1259    /* Filling response post */
1260    memset(&rspPst, 0, sizeof(Pst));
1261    FILL_PST_SCH_TO_MAC(rspPst, inst);
1262    rspPst.event = EVENT_CELL_DELETE_RSP_TO_MAC;
1263    ret =  SchCellDeleteRspOpts[rspPst.selector](&rspPst, &delRsp);
1264    if(ret == RFAILED)
1265    {
1266       DU_LOG("\nERROR  -->  SCH : SchSendCellDeleteRspToMac(): failed to send the Cell Delete response");
1267       return ret;
1268    }
1269    return ret;
1270 }
1271
1272 /*******************************************************************
1273  *
1274  * @brief Function for cellCb Deletion 
1275  *
1276  * @details
1277  *
1278  *    Function : deleteSchCellCb 
1279  *
1280  *    Functionality: Function for cellCb Deletion 
1281  *
1282  * @params[in] SchCellDelete  *cellDelete
1283  * @return ROK     - success
1284  *         RFAILED - failure
1285  *
1286  * ****************************************************************/
1287 void deleteSchCellCb(SchCellCb *cellCb)
1288 {
1289    uint8_t sliceIdx=0, slotIdx=0;
1290    CmLListCp *list=NULL;
1291    CmLList *node=NULL, *next=NULL;
1292    SchPageInfo *tempNode = NULLP;
1293
1294    if(cellCb->schDlSlotInfo)
1295    {
1296       for(slotIdx=0; slotIdx<cellCb->numSlots; slotIdx++)
1297       {
1298          list = &cellCb->schDlSlotInfo[slotIdx]->prbAlloc.freePrbBlockList;
1299          node = list->first;
1300          while(node)
1301          {
1302             next = node->next;
1303             SCH_FREE(node->node, sizeof(FreePrbBlock));
1304             deleteNodeFromLList(list, node);
1305             node = next;
1306          }
1307          SCH_FREE(cellCb->schDlSlotInfo[slotIdx], sizeof(SchDlSlotInfo));
1308       }
1309       SCH_FREE(cellCb->schDlSlotInfo, cellCb->numSlots *sizeof(SchDlSlotInfo*));
1310    }
1311
1312    if(cellCb->schUlSlotInfo)
1313    {
1314       for(slotIdx=0; slotIdx<cellCb->numSlots; slotIdx++)
1315       {
1316          list = &cellCb->schUlSlotInfo[slotIdx]->prbAlloc.freePrbBlockList;
1317          node = list->first;
1318          while(node)
1319          {
1320             next = node->next;
1321             SCH_FREE(node->node, sizeof(FreePrbBlock));
1322             deleteNodeFromLList(list, node);
1323             node = next;
1324          }
1325          SCH_FREE(cellCb->schUlSlotInfo[slotIdx], sizeof(SchUlSlotInfo));  
1326       }
1327       SCH_FREE(cellCb->schUlSlotInfo,  cellCb->numSlots * sizeof(SchUlSlotInfo*));
1328    }
1329
1330    if(cellCb->cellCfg.plmnInfoList.snssai)
1331    {
1332       for(sliceIdx=0; sliceIdx<cellCb->cellCfg.plmnInfoList.numSliceSupport; sliceIdx++)
1333       {
1334          SCH_FREE(cellCb->cellCfg.plmnInfoList.snssai[sliceIdx], sizeof(Snssai));
1335       }
1336       SCH_FREE(cellCb->cellCfg.plmnInfoList.snssai, cellCb->cellCfg.plmnInfoList.numSliceSupport*sizeof(Snssai*));
1337    }
1338    
1339    for(uint16_t idx =0; idx<MAX_SFN; idx++)
1340    {
1341       list = &cellCb->pageCb.pageIndInfoRecord[idx];
1342       node = list->first;
1343       while(node)
1344       {
1345          next = node->next;
1346          if(node->node)
1347          {
1348             tempNode = (SchPageInfo*)(node->node);
1349             SCH_FREE(tempNode->pagePdu, tempNode->msgLen);
1350             SCH_FREE(node->node,  sizeof(SchPageInfo));
1351          }
1352          deleteNodeFromLList(list, node);
1353          node = next;
1354       }
1355    }
1356
1357    /* Remove all UE from ueToBeScheduled list and deallocate */
1358    node = cellCb->ueToBeScheduled.first;
1359    while(node)
1360    {
1361       next = node->next;
1362       SCH_FREE(node->node, sizeof(uint8_t));
1363       cmLListDelFrm(&cellCb->ueToBeScheduled, node);
1364       SCH_FREE(node, sizeof(CmLList));
1365       node = next;
1366    }
1367
1368    memset(cellCb, 0, sizeof(SchCellCb));
1369
1370 }
1371
1372 /*******************************************************************
1373  *
1374  * @brief Function for cell Delete request from MAC to SCH
1375  *
1376  * @details
1377  *
1378  *    Function : MacSchCellDeleteReq
1379  *
1380  *    Functionality: Function for cell Delete request from MAC to SCH
1381  *
1382  * @params[in] Pst *pst, SchCellDelete  *cellDelete
1383  * @return ROK     - success
1384  *         RFAILED - failure
1385  *
1386  * ****************************************************************/
1387
1388 uint8_t MacSchCellDeleteReq(Pst *pst, SchCellDelete  *cellDelete)
1389 {
1390    uint8_t   cellIdx=0, ret = RFAILED;
1391    Inst      inst = pst->dstInst - SCH_INST_START;
1392    SchMacRsp result= RSP_OK;
1393    
1394 #ifdef CALL_FLOW_DEBUG_LOG
1395    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_CELL_DELETE_REQ_TO_SCH\n");
1396 #endif   
1397
1398    if(!cellDelete)
1399    {
1400       DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): Ue Delete request failed");
1401    }
1402    else
1403    {
1404       GET_CELL_IDX(cellDelete->cellId, cellIdx);
1405       if(schCb[inst].cells[cellIdx] == NULLP)
1406       { 
1407          DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): cell Id[%d] is not available", cellDelete->cellId);
1408          result = RSP_NOK;
1409       }
1410       else
1411       {
1412          if(schCb[inst].cells[cellIdx]->cellId == cellDelete->cellId)
1413          {
1414             deleteSchCellCb(schCb[inst].cells[cellIdx]);
1415             result = RSP_OK;
1416             ret = ROK;
1417             SCH_FREE(schCb[inst].cells[cellIdx], sizeof(SchCellCb));
1418             DU_LOG("\nINFO   -->  SCH : Sending Cell Delete response to MAC");
1419          }
1420          else
1421          {
1422             DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): cell Id[%d] is not available",cellDelete->cellId);
1423             result = RSP_NOK;
1424          }
1425       }
1426
1427       if(SchSendCellDeleteRspToMac(cellDelete, inst, result)!=ROK)
1428       {
1429          DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): failed to send Cell Delete response");
1430          ret =  RFAILED;
1431       }
1432    }
1433    return ret;   
1434 }
1435 /*******************************************************************
1436  *
1437  * @brief Function updates DL HARQ Feedback
1438  *
1439  * @details
1440  *
1441  *    Function : schUpdateHarqFdbk
1442  *
1443  *    Functionality: Function updates DL HARQ feedback
1444  *
1445  * @params[in] SchUeCb *ueCb, UE cb struct pointer
1446  * @params[in] uint8_t numHarq, number of HARQ processes in feedback 
1447  * @params[in] uint8_t *harqPayload, harq feedback payload received
1448  * @params[in] SlotTimingInfo *slotInd, slot timing information
1449  * @return void
1450  *
1451  * ****************************************************************/
1452 void schUpdateHarqFdbk(SchUeCb *ueCb, uint8_t numHarq, uint8_t *harqPayload, SlotTimingInfo *slotInd)
1453 {
1454    SchDlHqProcCb *hqP;
1455    SchHqDlMap *hqDlMap;
1456    CmLList  *node;
1457    uint8_t fdbkPos = 0;
1458
1459    hqDlMap = ueCb->hqDlmap[slotInd->slot];
1460
1461    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState == SCH_RA_STATE_MSG2_HANDLE)
1462    {
1463       return;
1464    }
1465    if (ueCb->cellCb->raCb[ueCb->ueId-1].raState != SCH_RA_STATE_MSG4_PENDING)
1466    {
1467       node = hqDlMap->hqList.first;
1468       while(node)
1469       {
1470          hqP = (SchDlHqProcCb*)node->node;
1471          node = node->next;
1472          cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1473          /* 
1474             Decode harq feedback if needed post FAPI message decoding also or check how to decode this FAPI msg.
1475             case 1 semi static harq Ack/Nack codebook //Supported
1476             case 2 dynamic harq ACK/NACK codebook //Not supported
1477          */
1478          schDlHqFeedbackUpdate(hqP, harqPayload[fdbkPos++], HQ_TB_ACKED);//Marking 2nd TB as ACKED for now as only one TB to be used
1479       }
1480    }
1481    else
1482    {
1483       node = hqDlMap->hqList.first;
1484       hqP = (SchDlHqProcCb*)node->node;
1485       cmLListDelFrm(&hqDlMap->hqList, &hqP->ulSlotLnk);
1486       schMsg4FeedbackUpdate(hqP, harqPayload[fdbkPos++]);
1487    }
1488 }
1489 /**********************************************************************
1490   End of file
1491  **********************************************************************/