[Epic-ID: ODUHIGH-406][Task-ID: ODUHIGH-450] PAGING memory fixes
[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, SchLcPrbEstimate *lcPrbEst, 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(lcPrbEst->dedLcInfo == NULLP)
207             {
208                SCH_ALLOC(lcPrbEst->dedLcInfo, sizeof(DedicatedLCInfo));
209                if(lcPrbEst->dedLcInfo == NULLP)
210                {
211                   DU_LOG("\nINFO  -->  SCH : Memory Allocation Failed");
212                   return RFAILED;
213                }
214             }
215             if(sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo)
216             {
217                /*Updating latest RrmPolicy*/
218                lcPrbEst->dedLcInfo->rsvdDedicatedPRB = \
219                (uint16_t)(((sliceCfg.listOfConfirguration[sliceCfgIdx]->rrmPolicyRatioInfo->policyDedicatedRatio)*(MAX_NUM_RB))/100);
220                *isDedicated = TRUE;
221                DU_LOG("\nINFO  -->  SCH : Updated RRM policy, reservedPOOL:%d",lcPrbEst->dedLcInfo->rsvdDedicatedPRB);
222             }
223          }
224       }
225       /*case: This LcCtxt  is either a Default LC or this LC is part of someother RRM_MemberList*/
226       if(*isDedicated != TRUE) 
227       {
228          DU_LOG("\nINFO  -->  SCH : This SNSSAI is not a part of this RRMPolicy");
229       }
230    }
231    return ROK;   
232 }
233
234 /*******************************************************************
235  *
236  * @brief Function to fill SchUeCb
237  *
238  * @details
239  *
240  *    Function : fillSchUeCb
241  *
242  *    Functionality: Function to fill SchUeCb
243  *
244  * @params[in] Scheduler instance,
245  *             SchUeCb pointer,
246  *             SchUeCfg pointer
247  * @return ROK/RFAILED
248  *
249  * ****************************************************************/
250
251 uint8_t fillSchUeCb(Inst inst, SchUeCb *ueCb, SchUeCfg *ueCfg)
252 {
253    uint8_t   lcIdx, ueLcIdx;
254    uint8_t   freqDomainResource[FREQ_DOM_RSRC_SIZE] = {0};
255    SchPdschCfgCmn pdschCfg;
256    SchPucchDlDataToUlAck *dlDataToUlAck;
257    CmLListCp *lcLL = NULLP;
258    uint8_t retDL = ROK, retUL = ROK;
259    bool isLcIdValid = FALSE;
260
261    ueCb->ueCfg.cellId = ueCfg->cellId;
262    ueCb->ueCfg.ueId = ueCfg->ueId;
263    ueCb->ueCfg.crnti = ueCfg->crnti;
264    ueCb->ueCfg.dataTransmissionAction = ueCfg->dataTransmissionInfo;
265    if(ueCfg->macCellGrpCfgPres == true)
266    {
267       memcpy(&ueCb->ueCfg.macCellGrpCfg , &ueCfg->macCellGrpCfg, sizeof(SchMacCellGrpCfg)); 
268       ueCb->ueCfg.macCellGrpCfgPres = true;
269    }
270
271    if(ueCfg->phyCellGrpCfgPres == true)
272    {
273       memcpy(&ueCb->ueCfg.phyCellGrpCfg ,  &ueCfg->phyCellGrpCfg, sizeof(SchPhyCellGrpCfg));
274       ueCb->ueCfg.phyCellGrpCfgPres = true;
275    }
276
277    if(ueCfg->spCellCfgPres == true)
278    {
279       if(ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfgPres == true)
280       {
281          if(ueCb->ueCfg.spCellCfgPres && ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfgPres == true)
282          {
283             for(uint8_t idx = 0; idx < ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.numTimeDomRsrcAlloc; idx++)
284             {
285                if(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0 && ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0)
286                {
287                    SCH_FREE(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg.timeDomRsrcAllociList[idx].k0, sizeof(uint8_t));  
288                }
289             }
290          }
291       }
292       memcpy(&ueCb->ueCfg.spCellCfg , &ueCfg->spCellCfg, sizeof(SchSpCellCfg));
293
294       covertFreqDomRsrcMapToIAPIFormat(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc,\
295             freqDomainResource);
296       memset(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, 0, FREQ_DOM_RSRC_SIZE);
297       memcpy(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0].freqDomainRsrc, freqDomainResource, FREQ_DOM_RSRC_SIZE);
298
299       ueCb->ueCfg.spCellCfgPres = true;
300       dlDataToUlAck = ueCfg->spCellCfg.servCellCfg.initUlBwp.pucchCfg.dlDataToUlAck;
301       if(ueCb->cellCb)
302       {
303          if(dlDataToUlAck)
304          {
305             BuildK0K1Table(ueCb->cellCb, &ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1InfoTbl, false, pdschCfg,\
306                   ueCfg->spCellCfg.servCellCfg.initDlBwp.pdschCfg, dlDataToUlAck->dlDataToUlAckListCount,\
307                   dlDataToUlAck->dlDataToUlAckList);
308             ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.k0K1TblPrsnt = true;
309             BuildK2InfoTable(ueCb->cellCb, ueCfg->spCellCfg.servCellCfg.initUlBwp.puschCfg.timeDomRsrcAllocList,\
310                   ueCfg->spCellCfg.servCellCfg.initUlBwp.puschCfg.numTimeDomRsrcAlloc,\
311                   NULLP, &ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.k2InfoTbl);
312                   ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.k2TblPrsnt = true;
313          }
314       }
315    }
316
317    if(ueCfg->ambrCfg)
318    {
319       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
320       ueCb->ueCfg.ambrCfg =  ueCfg->ambrCfg;
321    }
322    memcpy(&ueCb->ueCfg.dlModInfo,  &ueCfg->dlModInfo , sizeof(SchModulationInfo));
323    memcpy(&ueCb->ueCfg.ulModInfo,  &ueCfg->ulModInfo , sizeof(SchModulationInfo));
324
325    //Updating SchUlCb and SchDlCb DB in SchUeCb
326    for(lcIdx = 0; lcIdx < ueCfg->numLcs; lcIdx++)
327    {
328       isLcIdValid = FALSE; /*Re-Initializing*/
329
330       ueLcIdx = ueCfg->schLcCfg[lcIdx].lcId;
331       CHECK_LCID(ueLcIdx, isLcIdValid);
332       if(isLcIdValid == FALSE)
333       {
334          DU_LOG("ERROR --> SCH: LCID:%d is not Valid",ueLcIdx);
335          continue;
336       }
337       if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_ADD)
338       {
339          fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
340          fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
341
342          /*Checking whether this LC belong to Dedicated S-NSSAI 
343           * and Create the Dedicated LC List & Update the Reserve PRB number*/
344          if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP)
345          {
346             retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlLcPrbEst),\
347                   &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated));
348          }
349          if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP)
350          {
351             retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulLcPrbEst),\
352                   &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated));
353          }
354
355          if(retUL == RFAILED  || retDL == RFAILED)/*FATAL error*/
356          {
357             DU_LOG("\nERROR  -->  SCH : Failure in updateDedLcInfo");
358             return RFAILED;
359          }
360       }
361       else
362       {
363          if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].lcId == ueCfg->schLcCfg[lcIdx].lcId)
364          {
365             if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_MOD)
366             {
367                fillSchUlLcCtxt(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
368                /*Updating the RRM reserved pool PRB count*/
369                if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai != NULLP)
370                {
371                   retUL =  updateDedLcInfo(inst, ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, &(ueCb->ulLcPrbEst),\
372                         &(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated));
373                }
374                if(retUL == RFAILED)
375                {
376                   DU_LOG("\nERROR  -->  SCH : Failed in updating Ded Lc info");
377                   return RFAILED;
378                }
379             }
380             if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_DEL)
381             {
382                /*Delete the LC node from the UL LC List*/
383                if(ueCb->ulInfo.ulLcCtxt[ueLcIdx].isDedicated)
384                {
385                   if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
386                   {
387                      lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList);
388                      handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
389                      if(lcLL->count == 0)/*IF No Node in DedicateLCList to be deleted*/
390                      {
391                         /*Free the Dedicated LC Info structure*/
392                         SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
393                      }
394                   }
395                }
396                else/*Default LC list*/
397                {
398                   lcLL = &(ueCb->ulLcPrbEst.defLcList);
399                   handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
400                }
401                SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
402                memset(&ueCb->ulInfo.ulLcCtxt[ueLcIdx], 0, sizeof(SchUlLcCtxt));
403             }
404          }/*End of UL LC Ctxt*/
405
406          if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].lcId == ueCfg->schLcCfg[lcIdx].lcId)
407          {
408             if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_MOD)
409             {
410                fillSchDlLcCtxt(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], &ueCfg->schLcCfg[lcIdx]);
411                /*Updating the RRM policy*/
412                if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai != NULLP)
413                {
414                   retDL = updateDedLcInfo(inst, ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, &(ueCb->dlLcPrbEst), \
415                         &(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated));
416                }
417                if(retDL == RFAILED)
418                {
419                   DU_LOG("\nERROR  -->  SCH : Failed in updating Ded Lc info");
420                   return RFAILED;
421                }
422             }
423             if(ueCfg->schLcCfg[lcIdx].configType == CONFIG_DEL)
424             {
425                /*Delete the LC node from the DL LC List*/
426                if(ueCb->dlInfo.dlLcCtxt[ueLcIdx].isDedicated)
427                {
428                   if(ueCb->dlLcPrbEst.dedLcInfo != NULLP)
429                   {
430                      lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
431                      handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
432                      if(lcLL->count == 0)/*Last Node in DedicateLCList to be deleted*/
433                      {
434                         /*Free the Dedicated LC Info structure*/
435                         SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
436                      }
437                   }
438                }
439                else
440                {
441                   lcLL = &(ueCb->dlLcPrbEst.defLcList);
442                   handleLcLList(lcLL, ueCfg->schLcCfg[lcIdx].lcId, DELETE);
443                }
444                SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
445                memset(&ueCb->dlInfo.dlLcCtxt[ueLcIdx], 0, sizeof(SchDlLcCtxt));
446             }
447          }/*End of DL LC ctxt*/
448       }
449
450       SCH_FREE(ueCfg->schLcCfg[lcIdx].drbQos, sizeof(SchDrbQosInfo));
451       SCH_FREE(ueCfg->schLcCfg[lcIdx].snssai, sizeof(Snssai));
452
453    }/* End of outer for loop */
454    return ROK;
455 }
456
457 /*******************************************************************
458  *
459  * @brief Function to get SCH Cell Cb
460  *
461  * @details
462  *
463  *    Function : getSchCellCb
464  *
465  *    Functionality: Function to get SCH Cell Cb
466  *
467  * @params[in] event, SchUeCfg pointer 
468  * @return schUeCb pointer  - success
469  *         NULLP - failure
470  *
471  * ****************************************************************/
472
473 SchCellCb *getSchCellCb(uint16_t srcEvent, Inst inst, SchUeCfg *ueCfg)
474 {
475    uint8_t      idx;
476    SchCellCb    *cellCb = NULLP;
477    SchUeCfgRsp  cfgRsp;
478    memset(&cfgRsp, 0, sizeof(SchUeCfgRsp));
479
480    /* Search of cell cb */
481    for(idx = 0; idx < MAX_NUM_CELL; idx++)
482    {
483       cellCb = schCb[inst].cells[idx];
484       if(cellCb->cellId == ueCfg->cellId)
485          break;
486    }
487    if(idx == MAX_NUM_CELL)
488    {
489       DU_LOG("\nERROR  -->  SCH : Ue create request failed. Invalid cell id %d", ueCfg->cellId);
490       SchSendUeCfgRspToMac(srcEvent, ueCfg, inst, RSP_NOK, &cfgRsp);
491       return NULLP;
492    }
493
494    /* Check if max number of UE configured */
495    if(cellCb->numActvUe > MAX_NUM_UE)
496    {
497       DU_LOG("\nERROR  -->  SCH :  Max number of UE [%d] already configured", MAX_NUM_UE);
498       SchSendUeCfgRspToMac(srcEvent, ueCfg, inst, RSP_NOK, &cfgRsp);
499       return NULLP;
500    }
501    return cellCb;
502 }
503
504
505 /*******************************************************************
506  *
507  * @brief Function to Add Ue Config Request from MAC
508  *
509  * @details
510  *
511  *    Function : MacSchAddUeConfigReq
512  *
513  *    Functionality: Function to Add Ue config request from MAC
514  *
515  * @params[in] 
516  * @return ROK     - success
517  *         RFAILED - failure
518  *
519  * ****************************************************************/
520 uint8_t MacSchAddUeConfigReq(Pst *pst, SchUeCfg *ueCfg)
521 {
522    uint8_t      lcIdx = 0, ret = ROK;
523    SchCellCb    *cellCb = NULLP;
524    SchUeCb      *ueCb = NULLP;
525    SchUeCfgRsp  cfgRsp;
526    Inst         inst = pst->dstInst - SCH_INST_START;
527    memset(&cfgRsp, 0, sizeof(SchUeCfgRsp));
528   
529 #ifdef CALL_FLOW_DEBUG_LOG
530    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_ADD_UE_CONFIG_REQ_TO_SCH\n");
531 #endif
532
533    if(!ueCfg)
534    {
535       DU_LOG("\nERROR  -->  SCH :  Adding UE Config Request failed at MacSchAddUeConfigReq()");
536       return RFAILED;
537    }
538    DU_LOG("\nDEBUG  -->  SCH :  Adding UE Config Request for CRNTI[%d]", ueCfg->crnti);
539    cellCb = getSchCellCb(pst->event, inst, ueCfg);
540
541    /* Search if UE already configured */
542    ueCb = &cellCb->ueCb[ueCfg->ueId - 1];
543
544    if((ueCb->crnti == ueCfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
545    {
546       DU_LOG("\nDEBUG  -->  SCH : CRNTI %d already configured ", ueCfg->crnti);
547       SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_OK, &cfgRsp);
548       return ROK;
549    }
550
551    /* Fill received Ue Configuration in UeCb */
552    memset(ueCb, 0, sizeof(SchUeCb));
553    ueCb->ueId = ueCfg->ueId;
554    ueCb->crnti = ueCfg->crnti;
555
556    ret = fillSchUeCb(inst, ueCb, ueCfg);
557    if(ret == ROK)
558    {
559       /* If UE has initiated RACH and then UE context is created, it means UE is
560        * active now.
561        * Else if UE context is created before RACH, this means that UE is being
562        * handed-in from source DU */
563       if(cellCb->raCb[ueCb->ueId-1].tcrnti == ueCb->crnti)
564       {
565          cellCb->numActvUe++;
566          SET_ONE_BIT(ueCb->ueId, cellCb->actvUeBitMap);
567          ueCb->state = SCH_UE_STATE_ACTIVE;
568       }
569       else
570       {
571          ueCb->state = SCH_UE_HANDIN_IN_PROGRESS;
572       }
573
574       ueCb->cellCb = cellCb;
575       ueCb->srRcvd = false;
576       ueCb->bsrRcvd = false;
577       for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
578          ueCb->bsrInfo[lcIdx].dataVol = 0;
579
580       SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_OK, &cfgRsp);
581    }
582    return ret;
583 }
584
585 /*******************************************************************
586 *
587 * @brief Fills PUSCH UL allocation
588 *
589 * @details
590 *
591 *    Function : schFillPuschAlloc
592 *
593 *    Functionality: fills PUSCH info
594 *
595 * @params[in]
596 * @return ROK     - success
597 *         RFAILED - failure
598 *
599 * ****************************************************************/
600 uint8_t schFillPuschAlloc(SchUeCb *ueCb, SlotTimingInfo puschTime, uint32_t tbSize, 
601                             uint8_t startSymb, uint8_t symbLen, uint16_t startPrb)
602 {
603   uint8_t  numRb          = 0;
604   SchCellCb *cellCb       = NULLP;
605   SchUlSlotInfo *schUlSlotInfo = NULLP;
606   SchPuschInfo puschInfo;
607   
608   if(ueCb == NULLP)
609   {
610     DU_LOG("\nERROR --> SCH: UE CB is empty");
611     return RFAILED;
612   }
613
614   cellCb = ueCb->cellCb;
615   if(cellCb == NULLP)
616   {
617     DU_LOG("\nERROR --> SCH: CELL CB is empty");
618     return RFAILED;
619   }
620
621   tbSize  +=  UL_TX_BUFFER_SIZE; /*  2 bytes header + some buffer */
622   numRb   = schCalcNumPrb(tbSize, ueCb->ueCfg.ulModInfo.mcsIndex, symbLen);
623   allocatePrbUl(cellCb, puschTime, startSymb, symbLen, &startPrb, numRb);
624
625   puschInfo.crnti             = ueCb->crnti; 
626   puschInfo.harqProcId        = SCH_HARQ_PROC_ID;
627   puschInfo.resAllocType      = SCH_ALLOC_TYPE_1;
628   puschInfo.fdAlloc.startPrb  = startPrb;
629   puschInfo.fdAlloc.numPrb    = numRb;
630   puschInfo.tdAlloc.startSymb = startSymb;
631   puschInfo.tdAlloc.numSymb   = symbLen;
632   puschInfo.tbInfo.qamOrder   = ueCb->ueCfg.ulModInfo.modOrder;
633   puschInfo.tbInfo.mcs        = ueCb->ueCfg.ulModInfo.mcsIndex;
634   puschInfo.tbInfo.mcsTable   = ueCb->ueCfg.ulModInfo.mcsTable;
635   puschInfo.tbInfo.ndi        = 1; /* new transmission */
636   puschInfo.tbInfo.rv         = 0;
637   puschInfo.tbInfo.tbSize     = tbSize;
638   puschInfo.dmrsMappingType   = DMRS_MAP_TYPE_A;  /* Setting Type-A */
639   puschInfo.nrOfDmrsSymbols   = NUM_DMRS_SYMBOLS;
640   puschInfo.dmrsAddPos        = DMRS_ADDITIONAL_POS;
641
642   schUlSlotInfo = cellCb->schUlSlotInfo[puschTime.slot];
643   SCH_ALLOC(schUlSlotInfo->schPuschInfo, sizeof(SchPuschInfo));
644   if(!schUlSlotInfo->schPuschInfo)
645   {
646      DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schAllocMsg3Pusch");
647      return RFAILED;
648   }
649   memcpy(schUlSlotInfo->schPuschInfo, &puschInfo, sizeof(SchPuschInfo));
650
651   return ROK;
652 }
653
654 /*******************************************************************
655  *
656  * @brief Fills DCI for UL grant
657  *
658  * @details
659  *
660  *    Function : schFillUlDci
661  *
662  *    Functionality: fills DCI for UL grant in response to BSR
663  *
664  * @params[in]
665  * @return ROK     - success
666  *         RFAILED - failure
667  *
668  * ****************************************************************/
669 uint8_t schFillUlDci(SchUeCb *ueCb, SchPuschInfo *puschInfo, DciInfo *dciInfo)
670 {
671    SchCellCb         *cellCb  = ueCb->cellCb;
672    SchControlRsrcSet coreset1 ;
673   
674    memset(&coreset1, 0, sizeof(SchControlRsrcSet));
675    if(ueCb->ueCfg.spCellCfgPres == true)
676    {
677      coreset1 = ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdcchCfg.cRSetToAddModList[0];
678    }
679    
680    dciInfo->cellId = cellCb->cellId;
681    dciInfo->crnti  = ueCb->crnti;
682
683    /* fill bwp cfg */
684    dciInfo->bwpCfg.subcarrierSpacing  = cellCb->cellCfg.sib1SchCfg.bwp.subcarrierSpacing;
685    dciInfo->bwpCfg.cyclicPrefix       = cellCb->cellCfg.sib1SchCfg.bwp.cyclicPrefix;
686    dciInfo->bwpCfg.freqAlloc.startPrb = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb;
687    dciInfo->bwpCfg.freqAlloc.numPrb   = cellCb->cellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb; 
688
689    /*fill coreset cfg */
690    //Considering number of RBs in coreset1 is same as coreset0
691    dciInfo->coresetCfg.coreSetSize      = coresetIdxTable[0][1];
692    //Considering coreset1 also starts from same symbol as coreset0
693    dciInfo->coresetCfg.startSymbolIndex = searchSpaceIdxTable[0][3];
694    dciInfo->coresetCfg.durationSymbols  = coreset1.duration;
695    memcpy(dciInfo->coresetCfg.freqDomainResource, coreset1.freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
696    
697    dciInfo->coresetCfg.cceRegMappingType   = coreset1.cceRegMappingType; /* non-interleaved */
698    dciInfo->coresetCfg.regBundleSize       = 6; /* must be 6 for non-interleaved */
699    dciInfo->coresetCfg.interleaverSize     = 0; /* NA for non-interleaved */
700    dciInfo->coresetCfg.coreSetType         = 1; /* non PBCH coreset */
701    dciInfo->coresetCfg.shiftIndex          = cellCb->cellCfg.phyCellId;
702    dciInfo->coresetCfg.precoderGranularity = coreset1.precoderGranularity;
703    dciInfo->coresetCfg.cceIndex            = 0; /* 0-3 for UL and 4-7 for DL */
704    dciInfo->coresetCfg.aggregationLevel    = 4; /* same as for sib1 */
705    
706    dciInfo->formatType = FORMAT0_0;
707    
708    /* fill UL grant */
709    dciInfo->format.format0_0.resourceAllocType   = puschInfo->resAllocType;
710    dciInfo->format.format0_0.freqAlloc.startPrb  = puschInfo->fdAlloc.startPrb;
711    dciInfo->format.format0_0.freqAlloc.numPrb    = puschInfo->fdAlloc.numPrb;
712    dciInfo->format.format0_0.timeAlloc.startSymb = puschInfo->tdAlloc.startSymb;
713    dciInfo->format.format0_0.timeAlloc.numSymb   = puschInfo->tdAlloc.numSymb;
714    dciInfo->format.format0_0.rowIndex            = 0; /* row Index */
715    dciInfo->format.format0_0.mcs                 = puschInfo->tbInfo.mcs;
716    dciInfo->format.format0_0.harqProcId          = puschInfo->harqProcId;
717    dciInfo->format.format0_0.puschHopFlag        = FALSE; /* disabled */
718    dciInfo->format.format0_0.freqHopFlag         = FALSE; /* disabled */
719    dciInfo->format.format0_0.ndi                 = puschInfo->tbInfo.ndi; /* new transmission */
720    dciInfo->format.format0_0.rv                  = puschInfo->tbInfo.rv;
721    dciInfo->format.format0_0.tpcCmd              = 0; //Sphoorthi TODO: check
722    dciInfo->format.format0_0.sUlCfgd             = FALSE; /* SUL not configured */
723    
724    /* Fill DCI Structure */
725    dciInfo->dciInfo.rnti                              = ueCb->crnti;
726    dciInfo->dciInfo.scramblingId                      = cellCb->cellCfg.phyCellId;
727    dciInfo->dciInfo.scramblingRnti                    = 0;
728    dciInfo->dciInfo.cceIndex                          = 0; /* 0-3 for UL and 4-7 for DL */
729    dciInfo->dciInfo.aggregLevel                       = 4;
730    dciInfo->dciInfo.beamPdcchInfo.numPrgs             = 1;
731    dciInfo->dciInfo.beamPdcchInfo.prgSize             = 1;
732    dciInfo->dciInfo.beamPdcchInfo.digBfInterfaces     = 0;
733    dciInfo->dciInfo.beamPdcchInfo.prg[0].pmIdx        = 0;
734    dciInfo->dciInfo.beamPdcchInfo.prg[0].beamIdx[0]   = 0;
735    dciInfo->dciInfo.txPdcchPower.powerValue           = 0;
736    dciInfo->dciInfo.txPdcchPower.powerControlOffsetSS = 0;
737    dciInfo->dciInfo.pdschCfg                          = NULL; /* No DL data being sent */
738
739    return ROK;
740 }
741
742 /*******************************************************************
743  *
744  * @brief Function to Modify Ue Config request from MAC
745  *
746  * @details
747  *
748  *    Function : MacSchModUeConfigReq
749  *
750  *    Functionality: Function to modify Ue Config request from MAC
751  *
752  * @params[in] 
753  * @return ROK     - success
754  *         RFAILED - failure
755  *
756  * ****************************************************************/
757 uint8_t MacSchModUeConfigReq(Pst *pst, SchUeCfg *ueCfg)
758 {
759    uint8_t ueId, lcIdx, ret = ROK;
760    SchCellCb    *cellCb = NULLP;
761    SchUeCb      *ueCb = NULLP;
762    SchUeCfgRsp  cfgRsp;
763    Inst         inst = pst->dstInst - SCH_INST_START;
764    memset(&cfgRsp, 0, sizeof(SchUeCfgRsp));
765   
766 #ifdef CALL_FLOW_DEBUG_LOG
767    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_MODIFY_UE_CONFIG_REQ_TO_SCH\n");
768 #endif
769
770    if(!ueCfg)
771    {
772       DU_LOG("\nERROR  -->  SCH : Modifying Ue Config request failed at MacSchModUeConfigReq()");
773       return RFAILED;
774    }
775    DU_LOG("\nDEBUG  -->  SCH : Modifying Ue Config Request for CRNTI[%d]", ueCfg->crnti);
776    cellCb = getSchCellCb(pst->event, inst, ueCfg);
777
778    /* Search if UE already configured */
779    GET_UE_ID(ueCfg->crnti, ueId);
780    ueCb = &cellCb->ueCb[ueId -1];
781    
782    if(!ueCb)
783    {
784       DU_LOG("\nERROR  -->  SCH : SchUeCb not found at MacSchModUeConfigReq() ");
785       SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_NOK, &cfgRsp);
786       return RFAILED;
787    }
788    if((ueCb->crnti == ueCfg->crnti) && (ueCb->state == SCH_UE_STATE_ACTIVE))
789    {
790       /* Found the UeCb to Reconfig */
791       ret = fillSchUeCb(inst, ueCb, ueCfg);
792       if(ret == ROK)
793       {
794          ueCb->cellCb = cellCb;
795          ueCb->srRcvd = false;
796          ueCb->bsrRcvd = false;
797          for(lcIdx=0; lcIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcIdx++)
798             ueCb->bsrInfo[lcIdx].dataVol = 0;
799
800          SchSendUeCfgRspToMac(pst->event, ueCfg, inst, RSP_OK, &cfgRsp);
801       }
802    }
803    return ret;
804 }
805
806 /*******************************************************************
807 *
808 * @brief Fill and send UE delete response to MAC
809 *
810 * @details
811 *
812 *    Function :  SchSendUeDeleteRspToMac
813 *
814 *    Functionality: Fill and send UE delete response to MAC
815 *
816 * @params[in] Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, 
817 *              ErrorCause cause
818 * @return ROK     - success
819 *         RFAILED - failure
820 *
821 * ****************************************************************/
822 void SchSendUeDeleteRspToMac(Inst inst, SchUeDelete  *ueDelete, SchMacRsp result, ErrorCause cause)
823 {
824     Pst rspPst;
825     SchUeDeleteRsp  delRsp;
826     
827     memset(&delRsp, 0, sizeof(SchUeDeleteRsp));
828     delRsp.cellId = ueDelete->cellId;
829     delRsp.crnti = ueDelete->crnti;
830     delRsp.rsp = result; 
831     delRsp.cause = cause; 
832
833     /* Filling response post */
834     memset(&rspPst, 0, sizeof(Pst));
835     FILL_PST_SCH_TO_MAC(rspPst, inst);
836     rspPst.event = EVENT_UE_DELETE_RSP_TO_MAC;
837     SchUeDeleteRspOpts[rspPst.selector](&rspPst, &delRsp);
838 }
839
840 /*******************************************************************
841 *
842 * @brief Function to delete Sch Pucch ResrcCfg
843 *
844 * @details
845 *
846 *    Function : deleteSchPucchResrcCfg 
847 *
848 *    Functionality: Function to delete Sch Pucch ResrcCfg
849 *
850 * @params[in] SchPucchResrcCfg *resrc
851 * @return void 
852 *
853 * ****************************************************************/
854
855 void deleteSchPucchResrcCfg(SchPucchResrcCfg *resrc)
856 {
857    uint8_t rsrcIdx=0;
858    for(rsrcIdx=0; rsrcIdx < resrc->resrcToAddModListCount; rsrcIdx++)
859    {
860       switch(resrc->resrcToAddModList[rsrcIdx].pucchFormat)
861       {
862          case PUCCH_FORMAT_0:
863          {
864             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format0,\
865             sizeof(SchPucchFormat0));
866             break;
867          }
868          case PUCCH_FORMAT_1:
869          {
870             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format1,\
871             sizeof(SchPucchFormat1));
872             break;
873          }
874          case PUCCH_FORMAT_2:
875          {
876             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format2,\
877             sizeof(SchPucchFormat2_3));
878             break;
879          }
880          case PUCCH_FORMAT_3:
881          {
882             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format3,\
883             sizeof(SchPucchFormat2_3));
884             break;
885          }
886          case PUCCH_FORMAT_4:
887          {
888             SCH_FREE(resrc->resrcToAddModList[rsrcIdx].SchPucchFormat.format4,\
889             sizeof(SchPucchFormat4));
890             break;
891          }
892       }
893    }
894 }
895
896 /*******************************************************************
897 *
898 * @brief Function to delete SCH Pdsch ServCellCfg
899 *
900 * @details
901 *
902 *    Function : deleteSchPdschServCellCfg
903 *
904 *    Functionality: Function to delete SCH Pdsch ServCellCfg
905 *
906 * @params[in] SchPdschServCellCfg *pdschServCellCfg
907 * @return void 
908 *
909 * ****************************************************************/
910
911 void deleteSchPdschServCellCfg(SchPdschServCellCfg *pdschServCellCfg)
912 {
913    SCH_FREE(pdschServCellCfg->maxMimoLayers, sizeof(uint8_t));
914    SCH_FREE(pdschServCellCfg->maxCodeBlkGrpPerTb, sizeof(SchMaxCodeBlkGrpPerTB));
915    SCH_FREE(pdschServCellCfg->codeBlkGrpFlushInd, sizeof(bool));
916    SCH_FREE(pdschServCellCfg->xOverhead, sizeof(SchPdschXOverhead));
917 }
918
919 /*******************************************************************
920 *
921 * @brief Function to  delete SCH UeCb
922 *
923 * @details
924 *
925 *    Function : deleteSchUeCb 
926 *
927 *    Functionality: Function to delete SCH UeCb
928 *
929 * @params[in]
930 * @return ROK     - success
931 *         RFAILED - failure
932 *
933 * ****************************************************************/
934 void deleteSchUeCb(SchUeCb *ueCb) 
935 {
936    uint8_t timeDomRsrcIdx = 0, ueLcIdx = 0;
937    SchPucchCfg *pucchCfg = NULLP;
938    SchPdschConfig *pdschCfg = NULLP;
939    CmLListCp *lcLL  = NULLP;
940
941    if(ueCb)
942    {
943       SCH_FREE(ueCb->ueCfg.ambrCfg, sizeof(SchAmbrCfg));
944       if(ueCb->ueCfg.spCellCfgPres)
945       {
946          if(ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfgPres == true)
947          {
948             pdschCfg = &ueCb->ueCfg.spCellCfg.servCellCfg.initDlBwp.pdschCfg;
949             for(timeDomRsrcIdx = 0; timeDomRsrcIdx < pdschCfg->numTimeDomRsrcAlloc; timeDomRsrcIdx++)
950                SCH_FREE(pdschCfg->timeDomRsrcAllociList[timeDomRsrcIdx].k0, sizeof(uint8_t));
951          }
952
953          if(ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfgPres == true)
954          {
955             pucchCfg = &ueCb->ueCfg.spCellCfg.servCellCfg.initUlBwp.pucchCfg;
956             SCH_FREE(pucchCfg->resrcSet,sizeof(SchPucchResrcSetCfg));
957             if(pucchCfg->resrc)
958             {
959                deleteSchPucchResrcCfg(pucchCfg->resrc);
960                SCH_FREE(pucchCfg->resrc, sizeof(SchPucchResrcCfg));
961             }
962             SCH_FREE(pucchCfg->format1, sizeof(SchPucchFormatCfg));
963             SCH_FREE(pucchCfg->format2, sizeof(SchPucchFormatCfg));
964             SCH_FREE(pucchCfg->format3, sizeof(SchPucchFormatCfg));
965             SCH_FREE(pucchCfg->format4, sizeof(SchPucchFormatCfg));
966             SCH_FREE(pucchCfg->schedReq, sizeof(SchPucchSchedReqCfg));
967             SCH_FREE(pucchCfg->multiCsiCfg, sizeof(SchPucchMultiCsiCfg));
968             SCH_FREE(pucchCfg->spatialInfo, sizeof(SchPucchSpatialCfg));  
969             SCH_FREE(pucchCfg->dlDataToUlAck, sizeof(SchPucchDlDataToUlAck));
970             SCH_FREE(pucchCfg->powerControl,sizeof(SchPucchPowerControl));
971          }
972          SCH_FREE(ueCb->ueCfg.spCellCfg.servCellCfg.bwpInactivityTmr, sizeof(uint8_t));
973          deleteSchPdschServCellCfg(&ueCb->ueCfg.spCellCfg.servCellCfg.pdschServCellCfg);
974       }
975       /*Need to Free the memory allocated for S-NSSAI*/
976       for(ueLcIdx = 0; ueLcIdx < MAX_NUM_LC; ueLcIdx++)
977       {
978          SCH_FREE(ueCb->ulInfo.ulLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
979          SCH_FREE(ueCb->dlInfo.dlLcCtxt[ueLcIdx].snssai, sizeof(Snssai));
980       }
981
982       /*Clearing out Dedicated LC list*/
983       if(ueCb->dlLcPrbEst.dedLcInfo != NULLP)
984       {
985          lcLL = &(ueCb->dlLcPrbEst.dedLcInfo->dedLcList);
986          deleteLcLL(lcLL);
987          SCH_FREE(ueCb->dlLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
988       }
989       if(ueCb->ulLcPrbEst.dedLcInfo != NULLP)
990       {
991          lcLL = &(ueCb->ulLcPrbEst.dedLcInfo->dedLcList);
992          deleteLcLL(lcLL);
993          SCH_FREE(ueCb->ulLcPrbEst.dedLcInfo, sizeof(DedicatedLCInfo));
994       }
995       /*Deleteing the Default LC list*/
996       lcLL = &(ueCb->dlLcPrbEst.defLcList);
997       deleteLcLL(lcLL);
998
999       lcLL = &(ueCb->ulLcPrbEst.defLcList);
1000       deleteLcLL(lcLL);
1001
1002       memset(ueCb, 0, sizeof(SchUeCb));
1003    }
1004 }
1005
1006 /*******************************************************************
1007 *
1008 * @brief Function for Ue Delete request from MAC to SCH
1009 *
1010 * @details
1011 *
1012 *    Function : MacSchUeDeleteReq 
1013 *
1014 *    Functionality: Function for Ue Delete request from MAC to SCH
1015 *
1016 * @params[in] Pst *pst, SchUeDelete  *ueDelete
1017 * @return ROK     - success
1018 *         RFAILED - failure
1019 *
1020 * ****************************************************************/
1021 uint8_t MacSchUeDeleteReq(Pst *pst, SchUeDelete  *ueDelete)
1022 {
1023     uint8_t      idx=0, ueId=0, ueIdToDel=0, ret=ROK;
1024     ErrorCause   result;
1025     SchCellCb    *cellCb = NULLP;
1026     Inst         inst = pst->dstInst - SCH_INST_START;
1027     CmLList      *node = NULL, *next = NULL;
1028    
1029 #ifdef CALL_FLOW_DEBUG_LOG
1030     DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_UE_DELETE_REQ_TO_SCH\n");
1031 #endif
1032
1033     if(!ueDelete)
1034     {
1035        DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): Ue Delete request failed");
1036        ret = RFAILED;
1037     }
1038     DU_LOG("\nDEBUG  -->  SCH : Ue Delete request received for crnti[%d]", ueDelete->crnti);
1039     
1040     cellCb = schCb[inst].cells[idx];
1041
1042     if(cellCb->cellId != ueDelete->cellId)
1043     {
1044        DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): cell Id is not available");
1045        result =  INVALID_CELLID;
1046     }
1047     else
1048     {
1049        GET_UE_ID(ueDelete->crnti, ueId);
1050        if(( cellCb->ueCb[ueId-1].crnti == ueDelete->crnti) && ( cellCb->ueCb[ueId-1].state == SCH_UE_STATE_ACTIVE))
1051        {
1052           deleteSchUeCb(&cellCb->ueCb[ueId-1]);
1053           ueIdToDel  = ueId;
1054           /* Remove UE from ueToBeScheduled list */
1055           node = cellCb->ueToBeScheduled.first;
1056           while(node)
1057           {
1058              next = node->next;
1059              ueId = *(uint8_t *)node->node;
1060              if(ueId == ueIdToDel)
1061              {
1062                 SCH_FREE(node->node, sizeof(uint8_t));
1063                 deleteNodeFromLList(&cellCb->ueToBeScheduled, node);
1064                 break;
1065              }
1066              node = next;
1067           }
1068           cellCb->numActvUe--;
1069           result = NOT_APPLICABLE;
1070        }
1071        else
1072        {
1073           DU_LOG("\nERROR  -->  SCH : MacSchUeDeleteReq(): SchUeCb not found");
1074           result =  INVALID_UEID;
1075        }
1076     }
1077     
1078     if(result == NOT_APPLICABLE)
1079     {
1080        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_OK, result);
1081     }
1082     else
1083     {
1084        SchSendUeDeleteRspToMac(inst, ueDelete, RSP_NOK, result);
1085        ret = RFAILED;
1086     }
1087     return ret;
1088 }
1089
1090 /*******************************************************************
1091  *
1092  * @brief Fill and send Cell delete response to MAC
1093  *
1094  * @details
1095  *
1096  *    Function :  SchSendCellDeleteRspToMac
1097  *
1098  *    Functionality: Fill and send Cell delete response to MAC
1099  *
1100  * @params[in] SchCellDelete  *ueDelete, Inst inst, SchMacRsp result
1101  * @return ROK     - success
1102  *         RFAILED - failure
1103  *
1104  * ****************************************************************/
1105 uint8_t SchSendCellDeleteRspToMac(SchCellDelete  *ueDelete, Inst inst, SchMacRsp result)
1106 {
1107    Pst rspPst;
1108    uint8_t ret=0;
1109    
1110    SchCellDeleteRsp  delRsp;
1111
1112    DU_LOG("\nINFO   --> SCH : Filling Cell Delete response");
1113    memset(&delRsp, 0, sizeof(SchCellDeleteRsp));
1114    delRsp.cellId = ueDelete->cellId;
1115    delRsp.rsp = result;
1116
1117    /* Filling response post */
1118    memset(&rspPst, 0, sizeof(Pst));
1119    FILL_PST_SCH_TO_MAC(rspPst, inst);
1120    rspPst.event = EVENT_CELL_DELETE_RSP_TO_MAC;
1121    ret =  SchCellDeleteRspOpts[rspPst.selector](&rspPst, &delRsp);
1122    if(ret == RFAILED)
1123    {
1124       DU_LOG("\nERROR  -->  SCH : SchSendCellDeleteRspToMac(): failed to send the Cell Delete response");
1125       return ret;
1126    }
1127    return ret;
1128 }
1129
1130 /*******************************************************************
1131  *
1132  * @brief Function for cellCb Deletion 
1133  *
1134  * @details
1135  *
1136  *    Function : deleteSchCellCb 
1137  *
1138  *    Functionality: Function for cellCb Deletion 
1139  *
1140  * @params[in] SchCellDelete  *cellDelete
1141  * @return ROK     - success
1142  *         RFAILED - failure
1143  *
1144  * ****************************************************************/
1145 void deleteSchCellCb(SchCellCb *cellCb)
1146 {
1147    uint8_t sliceIdx=0, slotIdx=0;
1148    CmLListCp *list=NULL;
1149    CmLList *node=NULL, *next=NULL;
1150    SchPageInfo *tempNode = NULLP;
1151
1152    if(cellCb->schDlSlotInfo)
1153    {
1154       for(slotIdx=0; slotIdx<cellCb->numSlots; slotIdx++)
1155       {
1156          list = &cellCb->schDlSlotInfo[slotIdx]->prbAlloc.freePrbBlockList;
1157          node = list->first;
1158          while(node)
1159          {
1160             next = node->next;
1161             SCH_FREE(node->node, sizeof(FreePrbBlock));
1162             deleteNodeFromLList(list, node);
1163             node = next;
1164          }
1165          SCH_FREE(cellCb->schDlSlotInfo[slotIdx], sizeof(SchDlSlotInfo));
1166       }
1167       SCH_FREE(cellCb->schDlSlotInfo, cellCb->numSlots *sizeof(SchDlSlotInfo*));
1168    }
1169
1170    if(cellCb->schUlSlotInfo)
1171    {
1172       for(slotIdx=0; slotIdx<cellCb->numSlots; slotIdx++)
1173       {
1174          list = &cellCb->schUlSlotInfo[slotIdx]->prbAlloc.freePrbBlockList;
1175          node = list->first;
1176          while(node)
1177          {
1178             next = node->next;
1179             SCH_FREE(node->node, sizeof(FreePrbBlock));
1180             deleteNodeFromLList(list, node);
1181             node = next;
1182          }
1183          SCH_FREE(cellCb->schUlSlotInfo[slotIdx], sizeof(SchUlSlotInfo));  
1184       }
1185       SCH_FREE(cellCb->schUlSlotInfo,  cellCb->numSlots * sizeof(SchUlSlotInfo*));
1186    }
1187
1188    if(cellCb->cellCfg.plmnInfoList.snssai)
1189    {
1190       for(sliceIdx=0; sliceIdx<cellCb->cellCfg.plmnInfoList.numSliceSupport; sliceIdx++)
1191       {
1192          SCH_FREE(cellCb->cellCfg.plmnInfoList.snssai[sliceIdx], sizeof(Snssai));
1193       }
1194       SCH_FREE(cellCb->cellCfg.plmnInfoList.snssai, cellCb->cellCfg.plmnInfoList.numSliceSupport*sizeof(Snssai*));
1195    }
1196    
1197    for(uint16_t idx =0; idx<MAX_SFN; idx++)
1198    {
1199       list = &cellCb->pageCb.pageIndInfoRecord[idx];
1200       node = list->first;
1201       while(node)
1202       {
1203          next = node->next;
1204          if(node->node)
1205          {
1206             tempNode = (SchPageInfo*)(node->node);
1207             SCH_FREE(tempNode->pagePdu, tempNode->msgLen);
1208             SCH_FREE(node->node,  sizeof(SchPageInfo));
1209          }
1210          deleteNodeFromLList(list, node);
1211          node = next;
1212       }
1213    }
1214
1215    /* Remove all UE from ueToBeScheduled list and deallocate */
1216    node = cellCb->ueToBeScheduled.first;
1217    while(node)
1218    {
1219       next = node->next;
1220       SCH_FREE(node->node, sizeof(uint8_t));
1221       cmLListDelFrm(&cellCb->ueToBeScheduled, node);
1222       SCH_FREE(node, sizeof(CmLList));
1223       node = next;
1224    }
1225
1226    memset(cellCb, 0, sizeof(SchCellCb));
1227
1228 }
1229
1230 /*******************************************************************
1231  *
1232  * @brief Function for cell Delete request from MAC to SCH
1233  *
1234  * @details
1235  *
1236  *    Function : MacSchCellDeleteReq
1237  *
1238  *    Functionality: Function for cell Delete request from MAC to SCH
1239  *
1240  * @params[in] Pst *pst, SchCellDelete  *cellDelete
1241  * @return ROK     - success
1242  *         RFAILED - failure
1243  *
1244  * ****************************************************************/
1245
1246 uint8_t MacSchCellDeleteReq(Pst *pst, SchCellDelete  *cellDelete)
1247 {
1248    uint8_t   cellIdx=0, ret = RFAILED;
1249    Inst      inst = pst->dstInst - SCH_INST_START;
1250    SchMacRsp result= RSP_OK;
1251    
1252 #ifdef CALL_FLOW_DEBUG_LOG
1253    DU_LOG("\nCall Flow: ENTMAC -> ENTSCH : EVENT_CELL_DELETE_REQ_TO_SCH\n");
1254 #endif   
1255
1256    if(!cellDelete)
1257    {
1258       DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): Ue Delete request failed");
1259    }
1260    else
1261    {
1262       GET_CELL_IDX(cellDelete->cellId, cellIdx);
1263       if(schCb[inst].cells[cellIdx] == NULLP)
1264       { 
1265          DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): cell Id[%d] is not available", cellDelete->cellId);
1266          result = RSP_NOK;
1267       }
1268       else
1269       {
1270          if(schCb[inst].cells[cellIdx]->cellId == cellDelete->cellId)
1271          {
1272             deleteSchCellCb(schCb[inst].cells[cellIdx]);
1273             result = RSP_OK;
1274             ret = ROK;
1275             SCH_FREE(schCb[inst].cells[cellIdx], sizeof(SchCellCb));
1276             DU_LOG("\nINFO   -->  SCH : Sending Cell Delete response to MAC");
1277          }
1278          else
1279          {
1280             DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): cell Id[%d] is not available",cellDelete->cellId);
1281             result = RSP_NOK;
1282          }
1283       }
1284
1285       if(SchSendCellDeleteRspToMac(cellDelete, inst, result)!=ROK)
1286       {
1287          DU_LOG("\nERROR  -->  SCH : MacSchCellDeleteReq(): failed to send Cell Delete response");
1288          ret =  RFAILED;
1289       }
1290
1291    }
1292    return ret;   
1293 }
1294
1295 /**********************************************************************
1296   End of file
1297  **********************************************************************/