[EPIC-ID: ODUHIGH-488][TASK-ID: ODUHIGH-494]Framework to support for slice based...
[o-du/l2.git] / src / 5gnrsch / sch_slice_based.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
19 /************************************************************************
20
21 Name:     5G NR SCH layer
22
23 Type:     C source file
24
25 Desc:     C source code for Slice based scheduling algorithm
26
27 File:     sch_slice_based.c
28
29  **********************************************************************/
30
31 /** @file sch_slot_ind.c
32   @brief This module processes slot indications
33  */
34 #include "common_def.h"
35 #include "tfu.h"
36 #include "lrg.h"
37 #include "tfu.x"
38 #include "lrg.x"
39 #include "du_log.h"
40 #include "du_app_mac_inf.h"
41 #include "mac_sch_interface.h"
42 #include "sch.h"
43 #include "sch_utils.h"
44 #include "sch_slice_based.h"
45 #ifdef NR_DRX 
46 #include "sch_drx.h"
47 #endif
48
49 /*******************************************************************
50  *
51  * @brief Function to handle Cell configuration request
52  *
53  * @details
54  *
55  *    Function : schSliceBasedCellCfgReq
56  *
57  *    Functionality: This function configures cell paremeters
58  *       required for Slice Based scheduling
59  *
60  * @params[in] SchCellCb *cellCb, Cell control block
61  * @return ROK
62  *         RFAILED
63  *
64  * ****************************************************************/
65 uint8_t schSliceBasedCellCfgReq(SchCellCb *cellCb)
66 {
67    SchSliceBasedCellCb *schSpcCellCb = NULLP;
68    
69    SCH_ALLOC(schSpcCellCb, sizeof(SchSliceBasedCellCb));
70    if(!schSpcCellCb)
71    {
72       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedCellCfgReq");
73       return RFAILED;
74    }
75    cmLListInit(&schSpcCellCb->ueToBeScheduled);
76    cellCb->schSpcCell = (void *)schSpcCellCb;
77    return ROK;
78 }
79
80 /*******************************************************************
81  *
82  * @brief Function to handle Cell configuration request
83  *
84  * @details
85  *
86  *    Function : schSliceBasedCellDelReq
87  *
88  *    Functionality: This function deletes/frees cell params
89  *       specific to Slice Based scheduling
90  *
91  * @params[in] Pointer to Cell control block
92  * @return void
93  *
94  * ****************************************************************/
95 void schSliceBasedCellDelReq(SchCellCb *cellCb)
96 {
97    SchSliceBasedCellCb *schSpcCellCb = NULLP;
98    CmLList *node=NULL, *next=NULL;
99
100    schSpcCellCb = (SchSliceBasedCellCb *)cellCb->schSpcCell;
101    /* Remove all UE from ueToBeScheduled list and deallocate */
102    node = schSpcCellCb->ueToBeScheduled.first;
103    while(node)
104    {
105       next = node->next;
106       SCH_FREE(node->node, sizeof(uint8_t));
107       cmLListDelFrm(&schSpcCellCb->ueToBeScheduled, node);
108       SCH_FREE(node, sizeof(CmLList));
109       node = next;
110    }
111    SCH_FREE(schSpcCellCb, sizeof(SchSliceBasedCellCb));
112    cellCb->schSpcCell = NULLP;
113 }
114
115 /*******************************************************************
116  *
117  * @brief Function to handle UE configuration request
118  *
119  * @details
120  *
121  *    Function : SchSliceBasedAddUeConfigReq
122  *
123  *    Functionality: Adds/Configures UE parameters required for
124  *       Slice Based scheduling
125  *
126  * @params[in] Pointer to UE control block
127  * @return ROK
128  *         RFAILED
129  *
130  * ****************************************************************/
131 uint8_t SchSliceBasedAddUeConfigReq(SchUeCb *ueCb)
132 {
133    SchSliceBasedUeCb *ueSliceBasedCb;
134
135    SCH_ALLOC(ueSliceBasedCb, sizeof(SchSliceBasedHqCb));
136    if(!ueSliceBasedCb)
137    {
138       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in SchSliceBasedAddUeConfigReq");
139       return RFAILED;
140    }
141    
142    cmLListInit(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
143    cmLListInit(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
144    ueCb->schSpcUeCb = (void *)ueSliceBasedCb;
145    
146    return ROK;
147 }
148
149 /*******************************************************************
150  *
151  * @brief Handles UE reconfiguration request
152  *
153  * @details
154  *
155  *    Function : SchSliceBasedModUeConfigReq
156  *
157  *    Functionality: 
158  *
159  * @params[in] Pointer to UE control block
160  * @return void
161  *
162  * ****************************************************************/
163 void SchSliceBasedModUeConfigReq(SchUeCb *ueCb)
164 {
165    /*TBD: No action required for Slice Based*/
166    return;
167 }
168
169 /*******************************************************************
170  *
171  * @brief Handles UE Delete Request
172  *
173  * @details
174  *
175  *    Function : SchSliceBasedUeDeleteReq 
176  *
177  *    Functionality: Deletes/Frees UE parameters specific to 
178  *       Slice Based scheduling
179  *
180  * @params[in] Pointer to UE control block
181  * @return void
182  *
183  * ****************************************************************/
184 void SchSliceBasedUeDeleteReq(SchUeCb *ueCb)
185 {
186    SchSliceBasedCellCb *schSpcCellCb = NULLP;
187    SchSliceBasedUeCb *ueSliceBasedCb = NULLP;
188    CmLList *node=NULL, *next=NULL;
189    uint8_t ueId = 0;
190
191    schSpcCellCb = (SchSliceBasedCellCb *)ueCb->cellCb->schSpcCell;
192    /* Remove all UE from ueToBeScheduled list and deallocate */
193    node = schSpcCellCb->ueToBeScheduled.first;
194    while(node)
195    {
196       next = node->next;
197       ueId = *(uint8_t *)node->node;
198       if(ueId == ueCb->ueId)
199       {
200         SCH_FREE(node->node, sizeof(uint8_t));
201         cmLListDelFrm(&schSpcCellCb->ueToBeScheduled, node);
202         SCH_FREE(node, sizeof(CmLList));
203         break;
204       }
205       node = next;
206    }
207    
208    ueSliceBasedCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
209    cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.ulRetxHqList);
210    cmLListDeleteLList(&ueSliceBasedCb->hqRetxCb.dlRetxHqList);
211
212    SCH_FREE(ueSliceBasedCb, sizeof(SchSliceBasedUeCb));
213    ueCb->schSpcUeCb = NULLP;
214    return;
215 }
216
217 /*******************************************************************
218  *
219  * @brief Intializes HARQ Process control block
220  *
221  * @details
222  *
223  *    Function : schSliceBasedInitDlHqProcCb
224  *
225  *    Functionality: Intitialized parameters of HARQ process control
226  *       block specific to Slice Based scheduling in Downlink
227  *
228  * @params[in] Pointer to Downlink HARQ Process control block
229  * @return ROK
230  *         RFAILED
231  *
232  * ****************************************************************/
233 uint8_t schSliceBasedInitDlHqProcCb(SchDlHqProcCb *hqP)
234 {
235    SchSliceBasedHqProcCb *schSpcHqP;
236
237    SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
238    if(!schSpcHqP)
239    {
240       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedInitDlHqProcCb");
241       return RFAILED;
242    }
243
244    cmLListInit(&schSpcHqP->lcCb.dedLcList);
245    cmLListInit(&schSpcHqP->lcCb.defLcList);
246    hqP->schSpcDlHqProcCb = (void *)schSpcHqP;
247
248    return ROK;
249 }
250
251 /*******************************************************************
252  *
253  * @brief Handles HARQ Process delete request
254  *
255  * @details 
256  *
257  *    Function : schSliceBasedDeleteDlHqProcCb
258  *
259  *    Functionality: Deletes HARQ Process parameters specific to 
260  *       Slice Based scheduling in Downlink
261  *
262  * @params[in] Pointer to Downlink HARQ Process control block
263  * @return void
264  *
265  * ****************************************************************/
266 void schSliceBasedDeleteDlHqProcCb(SchDlHqProcCb *hqP)
267 {
268    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
269    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
270    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
271    SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
272    hqP->schSpcDlHqProcCb = NULLP;
273 }
274
275 /*******************************************************************
276  *
277  * @brief Intializes HARQ Process control block
278  *
279  * @details
280  *
281  *    Function : schSliceBasedInitUlHqProcCb
282  *
283  *    Functionality: Intitialized parameters of HARQ process control
284  *       block specific to Slice Based scheduling in Uplink
285  *
286  * @params[in] Pointer to Uplink HARQ Process control block
287  * @return ROK
288  *         RFAILED
289  *
290  * ****************************************************************/
291 uint8_t schSliceBasedInitUlHqProcCb(SchUlHqProcCb *hqP)
292 {
293    SchSliceBasedHqProcCb *schSpcHqP;
294
295    SCH_ALLOC(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
296    if(!schSpcHqP)
297    {
298       DU_LOG("\nERROR  -->  SCH: Memory allocation failed in schSliceBasedInitUlHqProcCb");
299       return RFAILED;
300    }
301    cmLListInit(&schSpcHqP->lcCb.dedLcList);
302    cmLListInit(&schSpcHqP->lcCb.defLcList);
303    hqP->schSpcUlHqProcCb = (void *)schSpcHqP;
304  
305    return ROK;
306 }
307
308 /*******************************************************************
309  *
310  * @brief Handled Deletion of HARQ Process control block
311  *
312  * @details
313  *
314  *    Function : schSliceBasedDeleteUlHqProcCb
315  *
316  *    Functionality: Deletes HARQ Process parameters specific to 
317  *       Slice Based scheduling in Uplink
318  *
319  * @params[in] Pointer to Uplink HARQ Process Control block
320  * @return void
321  *
322  * ****************************************************************/
323 void schSliceBasedDeleteUlHqProcCb(SchUlHqProcCb *hqP)
324 {
325    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
326    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
327    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
328    SCH_FREE(schSpcHqP, sizeof(SchSliceBasedHqProcCb));
329    hqP->schSpcUlHqProcCb = NULLP;
330 }
331
332 /*******************************************************************
333  *
334  * @brief Handles freeing of HARQ Process
335  *
336  * @details
337  *
338  *    Function : schSliceBasedFreeDlHqProcCb
339  *
340  *    Functionality: Frees HARQ Process parameters specific to 
341  *       Slice Based scheduling in Downlink when HARQ process becomes free
342  *
343  * @params[in] Pointer to HARQ process control block
344  * @return void
345  *
346  * ****************************************************************/
347 void schSliceBasedFreeDlHqProcCb(SchDlHqProcCb *hqP)
348 {
349    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcDlHqProcCb;
350
351    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
352    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
353 }
354
355 /*******************************************************************
356  *
357  * @brief Handles freeing of HARQ Process
358  *
359  * @details
360  *
361  *    Function : schSliceBasedFreeUlHqProcCb
362  *
363  *    Functionality: Frees HARQ Process parameters specific to 
364  *       Slice Based scheduling in Uplink when HARQ process becomes free
365  *
366  * @params[in] Pointer to HARQ process control block
367  * @return void
368  *
369  * ****************************************************************/
370 void schSliceBasedFreeUlHqProcCb(SchUlHqProcCb *hqP)
371 {
372    SchSliceBasedHqProcCb *schSpcHqP = (SchSliceBasedHqProcCb *)hqP->schSpcUlHqProcCb;
373
374    cmLListDeleteLList(&schSpcHqP->lcCb.dedLcList);
375    cmLListDeleteLList(&schSpcHqP->lcCb.defLcList);
376 }
377
378 /*******************************************************************
379  *
380  * @brief Adds HARQ process to retransmission list
381  *
382  * @details
383  *
384  *    Function : schSliceBasedAddToDlHqRetxList
385  *
386  *    Functionality: Adds HARQ process to retransmission list
387  *
388  * @params[in] Pointer to Downlink HARQ Process 
389  * @return void
390  *
391  * ****************************************************************/
392 void schSliceBasedAddToDlHqRetxList(SchDlHqProcCb *hqP)
393 {
394    SchSliceBasedUeCb *schSpcUeCb;
395
396    schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
397    cmLListAdd2Tail(&(schSpcUeCb->hqRetxCb.dlRetxHqList),&hqP->dlHqProcLink);  
398 #ifdef NR_DRX
399    if(hqP->hqEnt->ue->ueDrxInfoPres == true)
400    {
401       schDrxStrtDlHqRttTmr(hqP);
402    }
403    else
404 #endif
405    {
406       schSliceBasedAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
407    }
408 }
409
410 /*******************************************************************
411  *
412  * @brief Adds HARQ process to retransmission list
413  *
414  * @details
415  *
416  *    Function : schSliceBasedAddToUlHqRetxList
417  *
418  *    Functionality: Adds HARQ process to retransmission list
419  *
420  * @params[in] Pointer to Uplink HARQ Process 
421  * @return void
422  *
423  * ****************************************************************/
424 void schSliceBasedAddToUlHqRetxList(SchUlHqProcCb *hqP)
425 {
426    SchSliceBasedUeCb *schSpcUeCb;
427
428    schSpcUeCb = (SchSliceBasedUeCb *)hqP->hqEnt->ue->schSpcUeCb;
429    cmLListAdd2Tail(&(schSpcUeCb->hqRetxCb.ulRetxHqList),&hqP->ulHqProcLink);  
430 #ifdef NR_DRX
431    if(hqP->hqEnt->ue->ueDrxInfoPres == true)
432    {
433       schDrxStrtUlHqRttTmr(hqP);
434    }
435    else
436 #endif
437    {
438       schSliceBasedAddUeToSchedule(hqP->hqEnt->cell, hqP->hqEnt->ue->ueId);
439    }   
440 }
441
442 /*******************************************************************
443  *
444  * @brief Add UE to ueToBeScheduled List
445  *
446  * @details
447  *
448  *    Function : schSliceBasedAddUeToSchedule
449  *
450  *    Functionality:
451  *      Search if UE entry present in the list
452  *      If yes, return.
453  *      If no, add UE to the list
454  *
455  * @params[in] Cell control block
456  *             Ue Id to be added
457  *
458  * @return ROK     - success
459  *         RFAILED - failure
460  *
461  * ****************************************************************/
462 uint8_t schSliceBasedAddUeToSchedule(SchCellCb *cellCb, uint16_t ueIdToAdd)
463 {
464    SchSliceBasedCellCb *schSpcCellCb = NULLP;
465    uint8_t *ueId;
466    CmLList *node;
467
468    schSpcCellCb = (SchSliceBasedCellCb *)cellCb->schSpcCell;
469    /* Search if UE entry is already present in ueToBeScheduled list.
470     * If yes, another entry for same UE not needed. Hence, return */
471    node = schSpcCellCb->ueToBeScheduled.first;
472    while(node)
473    {
474       ueId = (uint8_t *)node->node;
475       if(*ueId == ueIdToAdd)
476          return ROK;
477       node = node->next;
478    }
479
480    /* If UE entry not present already, add UE to the end of ueToBeScheduled list */
481    SCH_ALLOC(ueId, sizeof(uint8_t));
482    if(!ueId)
483    {
484       DU_LOG("\nERROR  -->  SCH : Memory allocation failure in schSliceBasedAddUeToSchedule");
485       return RFAILED;
486    }
487    *ueId = ueIdToAdd;
488    if(addNodeToLList(&schSpcCellCb->ueToBeScheduled, ueId, NULLP) != ROK)
489    {
490       DU_LOG("\nERROR  --> SCH : Failed to add ueId [%d] to cell->ueToBeScheduled list", *ueId);
491       return RFAILED;
492    }
493    return ROK;
494 }
495
496 /*******************************************************************
497  *
498  * @brief Handled CRC Indication
499  *
500  * @details
501  *
502  *    Function : schSliceBasedProcessCrcInd
503  *
504  *    Functionality: Processes CRC Indication as required for Slice Based
505  *       scheduling
506  *
507  * @params[in] Pointer to Cell control block
508  *             UE Id
509  * @return void
510  *
511  * ****************************************************************/
512 void schSliceBasedProcessCrcInd(SchCellCb *cellCb, uint16_t ueId)
513 {
514    schSliceBasedAddUeToSchedule(cellCb, ueId);   
515 }
516
517 /*******************************************************************
518  *
519  * @brief Processes Buffer Occupancy report from RLC
520  *
521  * @details
522  *
523  *    Function : schSliceBasedDlRlcBoInfo
524  *
525  *    Functionality: Process buffer occupany report 
526  *
527  * @params[in]
528  * @return
529  *
530  * ****************************************************************/
531 void schSliceBasedDlRlcBoInfo(SchCellCb *cellCb, uint16_t ueId)
532 {
533    schSliceBasedAddUeToSchedule(cellCb, ueId);   
534 }
535
536 /*******************************************************************
537  *
538  * @brief Processes BSR request
539  *
540  * @details
541  *
542  *    Function : schSliceBasedBsr
543  *
544  *    Functionality: Processes BSR as per Slice Based scheduling
545  *
546  * @params[in] Pointer to Cell 
547  *             UE ID
548  * @return void
549  *
550  * ****************************************************************/
551 void schSliceBasedBsr(SchCellCb *cellCb, uint16_t ueId)
552 {
553    schSliceBasedAddUeToSchedule(cellCb, ueId);   
554 }
555
556 /*******************************************************************
557  *
558  * @brief Processed UCI Indication
559  *
560  * @details
561  *
562  *    Function : schSliceBasedSrUciInd
563  *
564  *    Functionality: Processing of UCI indication specific to 
565  *       Slice Based scheduling
566  *
567  * @params[in] Pointer to Cell
568  *             UE Id
569  * @return void
570  *
571  * ****************************************************************/
572 void schSliceBasedSrUciInd(SchCellCb *cellCb, uint16_t ueId)
573 {
574    schSliceBasedAddUeToSchedule(cellCb, ueId);   
575 }
576
577 /*******************************************************************
578  *
579  * @brief Processing of RACH Indication
580  *
581  * @details
582  *
583  *    Function : schSliceBasedProcessRachInd
584  *
585  *    Functionality: Processing of RACH Indication specific to 
586  *       Slice Based scheduling
587  *
588  * @params[in] Pointer to Cell Cb
589  *             UE Id
590  * @return void
591  *
592  * ****************************************************************/
593 void schSliceBasedProcessRachInd(SchCellCb *cellCb, uint16_t ueId)
594 {
595    schSliceBasedAddUeToSchedule(cellCb, ueId);   
596 }
597
598 /*******************************************************************
599  *
600  * @brief Processing of DL HARQ Indication
601  *
602  * @details
603  *
604  *    Function : SchSliceBasedDlHarqInd
605  *
606  *    Functionality:
607  *
608  * @params[in] 
609  * @return void
610  *
611  * ****************************************************************/
612 void SchSliceBasedDlHarqInd()
613 {
614    return;
615 }
616
617 /*******************************************************************
618  *
619  * @brief Processing of Paging indication
620  *
621  * @details
622  *
623  *    Function : schSliceBasedPagingInd
624  *
625  *    Functionality:
626  *
627  * @params[in]
628  * @return void
629  *
630  * ****************************************************************/
631 void schSliceBasedPagingInd()
632 {
633    return;
634 }
635
636 /*******************************************************************
637  *
638  * @brief Processing of RACH Resource Request
639  *
640  * @details
641  *
642  *    Function : schSliceBasedRachRsrcReq
643  *
644  *    Functionality:
645  *
646  * @params[in]
647  * @return void
648  *
649  * ****************************************************************/
650 void schSliceBasedRachRsrcReq()
651 {
652    return;
653 }
654
655 /*******************************************************************
656  *
657  * @brief Processing of RACH Resource Release
658  *
659  * @details
660  *
661  *    Function : schSliceBasedRachRsrcRel
662  *
663  *    Functionality:
664  *
665  * @params[in]
666  * @return void
667  *
668  * ****************************************************************/
669 void schSliceBasedRachRsrcRel()
670 {
671    return;
672 }
673
674 /*******************************************************************
675  *
676  * @brief Remove entry from HARQ retransmission list
677  *
678  * @details
679  *
680  *    Function : schSliceBasedRemoveFrmDlHqRetxList
681  *
682  *    Functionality: Remove entry from HARQ retransmission list
683  *
684  * @params[in] Pointer to UE
685  *             Node to be deleted
686  * @return void
687  *
688  * ****************************************************************/
689 void schSliceBasedRemoveFrmDlHqRetxList(SchUeCb *ueCb, CmLList *node)
690 {
691    SchSliceBasedUeCb *schSpcUeCb;
692
693    schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
694    cmLListDelFrm(&schSpcUeCb->hqRetxCb.dlRetxHqList, node);
695 }
696
697 /*******************************************************************
698  *
699  * @brief Remove entry from HARQ retransmission list
700  *
701  * @details
702  *
703  *    Function : schSliceBasedRemoveFrmUlHqRetxList
704  *
705  *    Functionality: Remove entry from HARQ retransmission list
706  *
707  * @params[in] Pointer to UE
708  *             Node to be deleted
709  * @return void
710  *
711  * ****************************************************************/
712 void schSliceBasedRemoveFrmUlHqRetxList(SchUeCb *ueCb, CmLList *node)
713 {
714    SchSliceBasedUeCb *schSpcUeCb;
715
716    schSpcUeCb = (SchSliceBasedUeCb *)ueCb->schSpcUeCb;
717    cmLListDelFrm(&schSpcUeCb->hqRetxCb.ulRetxHqList, node);
718 }
719
720 /*******************************************************************
721  *
722  * @brief Remove UE from Scheduling List
723  *
724  * @details
725  *
726  *    Function : schSliceBasedRemoveUeFrmScheduleLst
727  *
728  *    Functionality: Remove UE from Scheduling List
729  *
730  * @params[in] Pointer to Cell
731  *             Node to be removed
732  * @return void
733  *
734  * ****************************************************************/
735 void schSliceBasedRemoveUeFrmScheduleLst(SchCellCb *cell, CmLList *node)
736 {
737    SchSliceBasedCellCb *schSpcCell;
738
739    schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
740    SCH_FREE(node->node, sizeof(uint8_t));
741    deleteNodeFromLList(&schSpcCell->ueToBeScheduled, node);
742 }
743
744 /*******************************************************************
745  *
746  * @brief  Handler to calculate TBS size for BSR requested
747  *
748  * @details
749  *
750  *    Function :  schSliceBasedCalculateUlTbs
751  *
752  *    Functionality: Function will note the required TBS for each LCGIDX and use
753  *    the Priority LCG List and RRM policy to allocate the TBS size
754  *
755  * @params [in] ueCb (Pointer to UE CB)
756  *         [in] puschTime (Time slot where PUSCH will be sent)
757  *         [in] symbLen (No of Symbols used for PUSCH transmission)
758  *         [out] startPrb(Pointer to startPRB which will be calculated while
759  *         finding the best Free Block)
760  *         [out] totTBS(Pointer to total TBS size)
761  *         [in] isRetx (to indicate retransmission)
762  *         [in] hqP (UL Harq process pointer)
763  *
764  * @return uint8_t : ROK > Scheduling of UL grant is successful
765  *                   RFAILED > vice versa
766  *
767  * ****************************************************************/
768 uint8_t schSliceBasedCalculateUlTbs(SchUeCb *ueCb, SlotTimingInfo puschTime, uint8_t symbLen,\
769                           uint16_t *startPrb, uint32_t *totTBS, bool isRetx, SchUlHqProcCb *hqP, SchSliceBasedHqProcCb *schSpcHqP)
770 {
771    uint16_t mcsIdx = 0;
772    CmLListCp *lcLL = NULLP;
773    uint16_t lcgIdx = 0, lcId =0, maxFreePRB = 0;
774    uint16_t rsvdDedicatedPRB;
775    *startPrb = 0;
776    *totTBS = 0;
777
778    /* check for BSR */
779    for(lcgIdx=0; lcgIdx<MAX_NUM_LOGICAL_CHANNEL_GROUPS; lcgIdx++)
780    {
781       if(ueCb->bsrInfo[lcgIdx].dataVol == 0)
782       {
783          continue;
784       }
785
786       /*TODO: lcgIdx and LCID has been implemented as one to one mapping.
787        * Need to check the mapping to figure out the LCID and lcgIdx once L2
788        * spec specifies any logic*/
789       lcId = lcgIdx;
790       if(ueCb->ulInfo.ulLcCtxt[lcId].isDedicated)
791       {
792          lcLL = &(schSpcHqP->lcCb.dedLcList);
793          rsvdDedicatedPRB = ueCb->ulInfo.ulLcCtxt[lcId].rsvdDedicatedPRB;
794       }
795       else
796       {
797          lcLL = &(schSpcHqP->lcCb.defLcList);
798       }
799
800       /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
801       if(updateLcListReqPRB(lcLL, lcId, ueCb->bsrInfo[lcgIdx].dataVol) != ROK)
802       {
803          DU_LOG("\nERROR  --> SCH: LcgId:%d updation failed",lcId);         
804          return RFAILED;
805       }
806    }
807
808    if ((schSpcHqP->lcCb.defLcList.count == 0) && (schSpcHqP->lcCb.dedLcList.count == 0))
809    {
810       if( (ueCb->srRcvd) || (isRetx) )
811       {
812          *startPrb = MAX_NUM_RB;
813          *totTBS = schCalcTbSize(UL_GRANT_SIZE);
814       }
815       /*Returning true when NO Grant is there for UE as this is not scheduling
816        * error*/      
817       return ROK;
818    }
819
820    maxFreePRB = searchLargestFreeBlock(ueCb->cellCb, puschTime, startPrb, DIR_UL);
821
822    /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
823     * the list based on RRM policy*/
824
825    /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
826     * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
827    if(maxFreePRB != 0)
828    {
829       mcsIdx = ueCb->ueCfg.ulModInfo.mcsIndex;
830       if((schSpcHqP->lcCb.dedLcList.count == 0) || ((maxFreePRB < rsvdDedicatedPRB)))
831       {
832          schSpcHqP->lcCb.sharedNumPrb = maxFreePRB;
833          DU_LOG("\nDEBUG  -->  SCH : UL Only Default Slice is scheduled, sharedPRB Count:%d",\
834                schSpcHqP->lcCb.sharedNumPrb);
835
836          /*PRB Alloc for Default LCs*/
837          prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen,\
838                &(schSpcHqP->lcCb.sharedNumPrb), NULLP, NULLP,&(ueCb->srRcvd));
839       }
840       else
841       {
842          schSpcHqP->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
843
844          /*PRB Alloc for Dedicated LCs*/
845          prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.dedLcList), TRUE, mcsIdx, symbLen,\
846                &(schSpcHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
847                NULLP, &(ueCb->srRcvd));
848
849          /*PRB Alloc for Default LCs*/
850          prbAllocUsingRRMPolicy(&(schSpcHqP->lcCb.defLcList), FALSE, mcsIdx, symbLen, \
851                &(schSpcHqP->lcCb.sharedNumPrb), &(rsvdDedicatedPRB),\
852                NULLP,&(ueCb->srRcvd));
853       }
854    }
855    /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
856     * using allocated BO per LC and Update dlMsgAlloc(BO report for MAC*/ 
857    if(schSpcHqP->lcCb.dedLcList.count != 0)
858       updateGrantSizeForBoRpt(&(schSpcHqP->lcCb.dedLcList), NULLP, ueCb->bsrInfo, totTBS);
859
860    updateGrantSizeForBoRpt(&(schSpcHqP->lcCb.defLcList), NULLP, ueCb->bsrInfo, totTBS);
861
862    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
863    if (*totTBS == 0)
864    {
865       if(maxFreePRB == 0)
866       {
867          DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
868       }
869       else
870       {
871          /*Schedule the LC for next slot*/
872          DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
873       }      
874       return RFAILED;
875    }   
876    return ROK;
877 }
878
879 /*******************************************************************
880  *
881  * @brief Grants resources to LC in uplink
882  *
883  * @details
884  *
885  *    Function : schProcessSrOrBsrReq
886  *
887  *    Functionality:
888  *       Grants resources to LC in uplink
889  *
890  * @params[in] PDCCH Time
891  *             PUSCH Time
892  *             Start Symbol
893  *             Number of symbols
894  *             Is retransmission
895  *             HARQ process
896  * @return ROK
897  *         RFAILED
898  *
899  *******************************************************************/
900 uint8_t schSliceBasedScheduleUlLc(SlotTimingInfo dciTime, SlotTimingInfo puschTime, uint8_t startSymb , uint8_t symbLen, bool isRetx, SchUlHqProcCb **hqP)
901 {
902    SchCellCb *cell;
903    SchSliceBasedHqProcCb *schSpcHqProcCb;
904    uint8_t ret = RFAILED;
905    uint16_t startPrb = 0;
906    uint32_t totDataReq = 0; /* in bytes */
907    SchUeCb *ueCb;
908    SchPuschInfo *puschInfo;
909    DciInfo  *dciInfo = NULLP;
910
911    cell = (*hqP)->hqEnt->cell;
912    ueCb = (*hqP)->hqEnt->ue;
913    schSpcHqProcCb = (SchSliceBasedHqProcCb *)(*hqP)->schSpcUlHqProcCb;
914    ret = schSliceBasedCalculateUlTbs(ueCb, puschTime, symbLen, &startPrb, &totDataReq, isRetx, *hqP, schSpcHqProcCb);
915
916    if(totDataReq > 0 && ret == ROK)
917    {
918       SCH_ALLOC(dciInfo, sizeof(DciInfo));
919       if(!dciInfo)
920       {
921          DU_LOG("\nERROR  -->  SCH : Memory Allocation failed for dciInfo alloc");
922          if(isRetx != TRUE)
923          {
924             if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
925                updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
926
927             updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
928          }
929          return RFAILED;
930       }
931       cell->schDlSlotInfo[dciTime.slot]->ulGrant = dciInfo;
932       memset(dciInfo,0,sizeof(DciInfo));
933
934       /* Update PUSCH allocation */
935       if(schFillPuschAlloc(ueCb, puschTime, totDataReq, startSymb, symbLen, startPrb, isRetx, *hqP) == ROK)
936       {
937          if(cell->schUlSlotInfo[puschTime.slot]->schPuschInfo)
938          {
939             puschInfo = cell->schUlSlotInfo[puschTime.slot]->schPuschInfo;
940             if(puschInfo != NULLP)
941             {
942                /* Fill DCI for UL grant */
943                schFillUlDci(ueCb, puschInfo, dciInfo, isRetx, *hqP);
944                memcpy(&dciInfo->slotIndInfo, &dciTime, sizeof(SlotTimingInfo));
945                ueCb->srRcvd = false;
946                ueCb->bsrRcvd = false;
947                cell->schUlSlotInfo[puschTime.slot]->puschUe = ueCb->ueId;
948                if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
949                   updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, ROK);
950                updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, ROK);
951                cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk);                  
952                return ROK;
953             }
954          }
955       }
956       if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
957          updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
958       updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
959    }
960    return ROK;
961 }
962
963 /*******************************************************************
964  *
965  * @brief Grants resources to LC in downlink 
966  *
967  * @details
968  *
969  *    Function : schSliceBasedScheduleDlLc 
970  *
971  *    Functionality: Grants resources to LC in uplink
972  *
973  * @params[in] PDCCH Time
974  *
975  * @return ROK
976  *         RFAILED
977  *
978  * ****************************************************************/
979 uint32_t schSliceBasedScheduleDlLc(SlotTimingInfo pdcchTime, SlotTimingInfo pdschTime, uint8_t pdschNumSymbols, bool isRetx, SchDlHqProcCb **hqP)
980 {
981    SchSliceBasedHqProcCb *schSpcHqProcCb;
982    SchUeCb *ueCb;
983    uint8_t lcIdx = 0;
984    uint16_t startPrb = 0, maxFreePRB = 0;
985    uint16_t mcsIdx = 0;
986    uint32_t accumalatedSize = 0;
987    CmLListCp *lcLL = NULLP;
988    uint16_t rsvdDedicatedPRB = 0;
989    DlMsgAlloc *dciSlotAlloc;
990
991    /* TX_PAYLOAD_HDR_LEN: Overhead which is to be Added once for any UE while estimating Accumulated TB Size
992     * Following flag added to keep the record whether TX_PAYLOAD_HDR_LEN is added to the first Node getting allocated.
993     * If both Dedicated and Default LC lists are present then First LC in Dedicated List will include this overhead
994     * else if only Default list is present then first node in this List will add this overhead len*/
995    bool isTxPayloadLenAdded = FALSE;
996
997    ueCb = (*hqP)->hqEnt->ue;
998    dciSlotAlloc = (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1];
999    schSpcHqProcCb = (SchSliceBasedHqProcCb *)((*hqP)->schSpcDlHqProcCb);
1000
1001    if (isRetx == FALSE)
1002    {
1003       /*Re-Initalization per UE*/
1004       /* scheduled LC data fill */
1005       dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo].numLc = 0;
1006       isTxPayloadLenAdded = FALSE; /*Re-initlaize the flag for every UE*/
1007       accumalatedSize = 0;
1008
1009       for(lcIdx = 0; lcIdx < MAX_NUM_LC; lcIdx++)
1010       {
1011          if(ueCb->dlInfo.dlLcCtxt[lcIdx].bo)
1012          {
1013             /*Check the LC is Dedicated or default and accordingly LCList will
1014             * be used*/
1015             if(ueCb->dlInfo.dlLcCtxt[lcIdx].isDedicated)
1016             {
1017                lcLL = &(schSpcHqProcCb->lcCb.dedLcList);
1018                rsvdDedicatedPRB = ueCb->dlInfo.dlLcCtxt[lcIdx].rsvdDedicatedPRB;
1019             }
1020             else
1021             {
1022                lcLL = &(schSpcHqProcCb->lcCb.defLcList);
1023             }
1024
1025             /*[Step2]: Update the reqPRB and Payloadsize for this LC in the appropriate List*/
1026             if(updateLcListReqPRB(lcLL, ueCb->dlInfo.dlLcCtxt[lcIdx].lcId,\
1027                      (ueCb->dlInfo.dlLcCtxt[lcIdx].bo + MAC_HDR_SIZE)) != ROK)
1028             {
1029                DU_LOG("\nERROR  --> SCH : Updation in LC List Failed");
1030                /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1031                if(dciSlotAlloc->numSchedInfo == 0)
1032                {
1033                   SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
1034                   (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1035                }
1036                else
1037                   memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
1038                return false;
1039             }
1040          }
1041          ueCb->dlInfo.dlLcCtxt[lcIdx].bo = 0;
1042       }//End of for loop
1043
1044       if ((schSpcHqProcCb->lcCb.defLcList.count == 0) && (schSpcHqProcCb->lcCb.dedLcList.count == 0))
1045       {
1046          DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
1047          UNSET_ONE_BIT((*hqP)->hqEnt->ue->ueId, (*hqP)->hqEnt->cell->boIndBitMap);
1048
1049          /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1050          if(dciSlotAlloc->numSchedInfo == 0)
1051          {
1052             SCH_FREE(dciSlotAlloc, sizeof(DlMsgAlloc));
1053             (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1054          }
1055          else
1056             memset(&dciSlotAlloc->dlMsgSchedInfo[dciSlotAlloc->numSchedInfo], 0, sizeof(DlMsgSchInfo));
1057
1058          /*TRUE because this UE has nothing to be scheduled*/
1059          return true;
1060       }
1061    }
1062
1063    /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
1064    maxFreePRB = searchLargestFreeBlock((*hqP)->hqEnt->cell, pdschTime, &startPrb, DIR_DL);
1065
1066    /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
1067     * the list based on RRM policy*/
1068
1069    /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
1070     * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
1071    if(isRetx == FALSE)
1072    {
1073       if(maxFreePRB != 0)
1074       {
1075          mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
1076
1077          if((schSpcHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
1078          { 
1079             schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
1080             DU_LOG("\nDEBUG  --> SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
1081                   schSpcHqProcCb->lcCb.sharedNumPrb);
1082
1083             /*PRB Alloc for Default LCs*/
1084             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
1085                   &(schSpcHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
1086          }
1087          else
1088          {
1089             schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
1090             /*PRB Alloc for Dedicated LCs*/
1091             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
1092                   &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1093
1094             /*PRB Alloc for Default LCs*/
1095             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
1096                   &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1097          }
1098       }
1099    }
1100
1101    /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
1102     * using allocated BO per LC and Update dlMsgAlloc BO report for MAC */
1103    if (isRetx == FALSE)
1104    {
1105       if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
1106          updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1107
1108       updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1109    }
1110    else
1111    {
1112       accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
1113    }
1114
1115    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
1116    if (!accumalatedSize)
1117    {
1118       if(maxFreePRB == 0)
1119       {
1120          DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
1121       }
1122       else
1123       {
1124          /*Schedule the LC for next slot*/
1125          DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
1126       }
1127       /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
1128        * Allocation can be done in next slot*/
1129       accumalatedSize = 0;
1130    }
1131
1132    return accumalatedSize;
1133 }
1134
1135 /*******************************************************************
1136  *
1137  * @brief Scheduling of Slots in UL And DL 
1138  *
1139  * @details
1140  *
1141  *    Function : schSliceBasedScheduleSlot
1142  *
1143  *    Functionality: Scheduling of slots in UL and DL specific to 
1144  *       Slice Based scheduling
1145  *
1146  * @params[in] Pointer to Cell
1147  *             Slot timing info
1148  *             Scheduler instance
1149  * @return void
1150  *
1151  * ****************************************************************/
1152 void schSliceBasedScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
1153 {
1154    SchSliceBasedCellCb  *schSpcCell;
1155    SchSliceBasedUeCb    *schSpcUeCb;
1156    SchDlHqProcCb  *hqP = NULLP;
1157    SchUlHqProcCb  *ulHqP = NULLP;
1158    CmLList        *pendingUeNode;
1159    CmLList        *node;
1160    uint8_t        ueId;
1161    bool           isRarPending = false, isRarScheduled = false;
1162    bool           isMsg4Pending = false, isMsg4Scheduled = false;
1163    bool           isDlMsgPending = false, isDlMsgScheduled = false;
1164    bool           isUlGrantPending = false, isUlGrantScheduled = false;
1165
1166    schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
1167    
1168    /* Select first UE in the linked list to be scheduled next */
1169    pendingUeNode = schSpcCell->ueToBeScheduled.first;
1170    if(pendingUeNode)
1171    {
1172       if(pendingUeNode->node)
1173       {
1174          ueId = *(uint8_t *)(pendingUeNode->node);
1175          schSpcUeCb = (SchSliceBasedUeCb *)cell->ueCb[ueId-1].schSpcUeCb;
1176
1177          /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and 
1178           * PUSCH to receive MSG3 as per k0-k2 configuration*/
1179          if(cell->raReq[ueId-1] != NULLP)
1180          {
1181             isRarPending = true;
1182             isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
1183          }
1184
1185          /*MSG3 retransmisson*/
1186          if(cell->raCb[ueId-1].retxMsg3HqProc)
1187          {            
1188             schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
1189          }
1190
1191          /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
1192           * PUCCH to receive UL msg as per k0-k1 configuration  */
1193          if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
1194          {
1195             /* Retransmission of MSG4 */
1196             isMsg4Pending = true;
1197             if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
1198                isMsg4Scheduled = true;
1199          }
1200          else
1201          {
1202             /* First transmission of MSG4 */
1203             if(cell->raCb[ueId-1].msg4recvd)
1204             {
1205                isMsg4Pending = true;
1206                if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4HqProc) == ROK)
1207                   isMsg4Scheduled = true;
1208
1209                /* If MSG4 scheduling failed, free the newly assigned HARQ process */
1210                if(!isMsg4Scheduled)
1211                   schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4HqProc);
1212             }
1213          }
1214
1215          if(isRarPending || isMsg4Pending)
1216          {
1217             /* If RAR or MSG is successfully scheduled then
1218              * remove UE from linked list since no pending msgs for this UE */
1219             if(isRarScheduled || isMsg4Scheduled)
1220             {
1221                schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
1222             }
1223             /* If RAR/MSG4 is pending but couldnt be scheduled then,
1224              * put this UE at the end of linked list to be scheduled later */
1225             else
1226             {
1227                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1228             }
1229          }
1230
1231 #ifdef NR_DRX 
1232          if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
1233          {
1234             if(pendingUeNode->node)
1235             {
1236                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1237             }
1238          }
1239          else 
1240 #endif
1241          {
1242
1243             /* DL Data */
1244             node = NULLP;
1245             if(schSpcUeCb)
1246                node = schSpcUeCb->hqRetxCb.dlRetxHqList.first;
1247             if(node != NULLP)
1248             {
1249                /* DL Data ReTransmisson */
1250                isDlMsgPending = true;
1251                isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
1252                if(isDlMsgScheduled)
1253                {
1254 #ifdef NR_DRX 
1255                   schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
1256 #endif
1257                   schSliceBasedRemoveFrmDlHqRetxList(&cell->ueCb[ueId-1], node);
1258                }
1259             }
1260             else
1261             {
1262                /* DL Data new transmission */
1263                if((cell->boIndBitMap) & (1<<ueId))
1264                {
1265                   isDlMsgPending = true;               
1266                   isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
1267
1268                   /* If DL scheduling failed, free the newly assigned HARQ process */
1269                   if(!isDlMsgScheduled)
1270                      schDlReleaseHqProcess(hqP);
1271                   else
1272                   {
1273 #ifdef NR_DRX
1274                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
1275 #endif
1276                   }
1277                }
1278             }
1279
1280             /* Scheduling of UL grant */
1281             node = NULLP;
1282             if(schSpcUeCb)
1283                node = schSpcUeCb->hqRetxCb.ulRetxHqList.first;
1284             if(node != NULLP)
1285             {
1286                /* UL Data ReTransmisson */
1287                isUlGrantPending = true;
1288                isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
1289                if(isUlGrantScheduled)
1290                {
1291 #ifdef NR_DRX 
1292                   schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
1293 #endif
1294                   schSliceBasedRemoveFrmUlHqRetxList(&cell->ueCb[ueId-1], node);
1295                }
1296             }
1297             else
1298             {
1299                /* UL Data new transmission */
1300                if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
1301                {
1302                   isUlGrantPending = true;
1303                   isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
1304                   if(!isUlGrantScheduled)
1305                      schUlReleaseHqProcess(ulHqP, FALSE);
1306                   else
1307                   {
1308 #ifdef NR_DRX
1309                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
1310 #endif
1311                   }
1312                }
1313             }
1314
1315             if(!isUlGrantPending && !isDlMsgPending)
1316             {
1317                /* No action required */  
1318             }
1319             else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
1320             {
1321                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1322             }
1323             else
1324             {
1325                schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
1326             }
1327          }
1328       }
1329    }
1330 }
1331
1332 /*******************************************************************
1333  *
1334  * @brief Initializes all function pointers to Slice Based function handler
1335  *
1336  * @details
1337  *
1338  *    Function : schSliceBasedAllApisInit
1339  *
1340  *    Functionality: Initializes all function pointers to Slice Based 
1341  *       function handler
1342  *
1343  * @params[in] Function pointer array
1344  * @return void
1345  *
1346  * ****************************************************************/
1347 void schSliceBasedAllApisInit(SchAllApis *allSliceBasedApi)
1348 {
1349     /* Interface API function pointers */
1350     allSliceBasedApi->SchCellCfgReq = schSliceBasedCellCfgReq;
1351     allSliceBasedApi->SchCellDeleteReq = schSliceBasedCellDelReq;
1352     allSliceBasedApi->SchAddUeConfigReq = SchSliceBasedAddUeConfigReq;
1353     allSliceBasedApi->SchModUeConfigReq = SchSliceBasedModUeConfigReq;
1354     allSliceBasedApi->SchUeDeleteReq = SchSliceBasedUeDeleteReq; 
1355     allSliceBasedApi->SchDlHarqInd = SchSliceBasedDlHarqInd; 
1356     allSliceBasedApi->SchCrcInd = schSliceBasedProcessCrcInd;
1357     allSliceBasedApi->SchRachInd = schSliceBasedProcessRachInd;
1358     allSliceBasedApi->SchPagingInd = schSliceBasedPagingInd;
1359     allSliceBasedApi->SchRachRsrcReq = schSliceBasedRachRsrcReq; 
1360     allSliceBasedApi->SchRachRsrcRel = schSliceBasedRachRsrcRel;
1361     allSliceBasedApi->SchDlRlcBoInfo = schSliceBasedDlRlcBoInfo;
1362     allSliceBasedApi->SchSrUciInd = schSliceBasedSrUciInd;
1363     allSliceBasedApi->SchBsr = schSliceBasedBsr;
1364
1365     /* Internal API function pointers */
1366     allSliceBasedApi->SchAddToDlHqRetxList = schSliceBasedAddToDlHqRetxList;
1367     allSliceBasedApi->SchAddToUlHqRetxList = schSliceBasedAddToUlHqRetxList;
1368     allSliceBasedApi->SchRemoveFrmDlHqRetxList = schSliceBasedRemoveFrmDlHqRetxList;
1369     allSliceBasedApi->SchRemoveFrmUlHqRetxList = schSliceBasedRemoveFrmUlHqRetxList;
1370     allSliceBasedApi->SchAddUeToSchedule = schSliceBasedAddUeToSchedule;
1371     allSliceBasedApi->SchRemoveUeFrmScheduleLst = schSliceBasedRemoveUeFrmScheduleLst;
1372     allSliceBasedApi->SchInitDlHqProcCb = schSliceBasedInitDlHqProcCb;
1373     allSliceBasedApi->SchInitUlHqProcCb = schSliceBasedInitUlHqProcCb;
1374     allSliceBasedApi->SchFreeDlHqProcCb = schSliceBasedFreeDlHqProcCb;
1375     allSliceBasedApi->SchFreeUlHqProcCb = schSliceBasedFreeUlHqProcCb;
1376     allSliceBasedApi->SchDeleteDlHqProcCb = schSliceBasedDeleteDlHqProcCb;
1377     allSliceBasedApi->SchDeleteUlHqProcCb = schSliceBasedDeleteUlHqProcCb;
1378     allSliceBasedApi->SchScheduleSlot = schSliceBasedScheduleSlot;
1379     allSliceBasedApi->SchScheduleDlLc = schSliceBasedScheduleDlLc;
1380     allSliceBasedApi->SchScheduleUlLc = schSliceBasedScheduleUlLc;
1381 }
1382 /**********************************************************************
1383     End of file
1384 **********************************************************************/
1385