[Epic-ID: ODUHIGH-488][Task-ID: ODUHIGH-498] StartPRb fix in Dl data flow
[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                ueCb->srRcvd = false;
945                ueCb->bsrRcvd = false;
946                cell->schUlSlotInfo[puschTime.slot]->puschUe = ueCb->ueId;
947                if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
948                   updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, ROK);
949                updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, ROK);
950                cmLListAdd2Tail(&(ueCb->hqUlmap[puschTime.slot]->hqList), &(*hqP)->ulSlotLnk);                  
951                return ROK;
952             }
953          }
954       }
955       if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
956          updateBsrAndLcList(&(schSpcHqProcCb->lcCb.dedLcList), ueCb->bsrInfo, RFAILED);
957       updateBsrAndLcList(&(schSpcHqProcCb->lcCb.defLcList), ueCb->bsrInfo, RFAILED);
958    }
959    return ROK;
960 }
961
962 /*******************************************************************
963  *
964  * @brief Grants resources to LC in downlink 
965  *
966  * @details
967  *
968  *    Function : schSliceBasedScheduleDlLc 
969  *
970  *    Functionality: Grants resources to LC in uplink
971  *
972  * @params[in] PDCCH Time
973  *
974  * @return ROK
975  *         RFAILED
976  *
977  * ****************************************************************/
978 uint32_t schSliceBasedScheduleDlLc(SlotTimingInfo pdcchTime, SlotTimingInfo pdschTime, uint8_t pdschNumSymbols,\
979                                     uint16_t *startPrb, bool isRetx, SchDlHqProcCb **hqP)
980 {
981    SchSliceBasedHqProcCb *schSpcHqProcCb;
982    SchUeCb *ueCb;
983    uint8_t lcIdx = 0;
984    uint16_t maxFreePRB = 0;
985    uint16_t mcsIdx = 0;
986    uint32_t accumalatedSize = 0;
987    CmLListCp *lcLL = NULLP;
988    uint16_t rsvdDedicatedPRB = 0;
989    DlMsgSchInfo *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->transportBlock[0].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->dlMsgPdschCfg)
1032                {
1033                   SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1034                   (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1035                }
1036                return accumalatedSize;
1037             }
1038          }
1039       }//End of for loop
1040
1041       if ((schSpcHqProcCb->lcCb.defLcList.count == 0) && (schSpcHqProcCb->lcCb.dedLcList.count == 0))
1042       {
1043          DU_LOG("\nDEBUG  -->  SCH : No pending BO for any LC id\n");
1044          UNSET_ONE_BIT((*hqP)->hqEnt->ue->ueId, (*hqP)->hqEnt->cell->boIndBitMap);
1045
1046          /* Free the dl ded msg info allocated in macSchDlRlcBoInfo */
1047          if(!dciSlotAlloc->dlMsgPdschCfg)
1048          {
1049             SCH_FREE(dciSlotAlloc, sizeof(DlMsgSchInfo));
1050             (*hqP)->hqEnt->cell->schDlSlotInfo[pdcchTime.slot]->dlMsgAlloc[ueCb->ueId -1] = NULL;
1051          }
1052          /*TRUE because this UE has nothing to be scheduled*/
1053          return accumalatedSize;
1054       }
1055    }
1056
1057    /*[Step3]: Calculate Best FREE BLOCK with MAX PRB count*/
1058    maxFreePRB = searchLargestFreeBlock((*hqP)->hqEnt->cell, pdschTime, startPrb, DIR_DL);
1059
1060    /*[Step4]: Estimation of PRB and BO which can be allocated to each LC in
1061     * the list based on RRM policy*/
1062
1063    /*Either this UE contains no reservedPRB pool fir dedicated S-NSSAI or 
1064     * Num of Free PRB available is not enough to reserve Dedicated PRBs*/
1065    if(isRetx == FALSE)
1066    {
1067       if(maxFreePRB != 0)
1068       {
1069          mcsIdx = ueCb->ueCfg.dlModInfo.mcsIndex;
1070
1071          if((schSpcHqProcCb->lcCb.dedLcList.count == NULLP) || ((maxFreePRB < rsvdDedicatedPRB)))
1072          { 
1073             schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB;
1074             DU_LOG("\nDEBUG  -->  SCH : DL Only Default Slice is scheduled, sharedPRB Count:%d",\
1075                   schSpcHqProcCb->lcCb.sharedNumPrb);
1076
1077             /*PRB Alloc for Default LCs*/
1078             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols,\
1079                   &(schSpcHqProcCb->lcCb.sharedNumPrb), NULLP, &isTxPayloadLenAdded, NULLP);
1080          }
1081          else
1082          {
1083             schSpcHqProcCb->lcCb.sharedNumPrb = maxFreePRB - rsvdDedicatedPRB;
1084             /*PRB Alloc for Dedicated LCs*/
1085             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.dedLcList), TRUE, mcsIdx, pdschNumSymbols,\
1086                   &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1087
1088             /*PRB Alloc for Default LCs*/
1089             prbAllocUsingRRMPolicy(&(schSpcHqProcCb->lcCb.defLcList), FALSE, mcsIdx, pdschNumSymbols, \
1090                   &(schSpcHqProcCb->lcCb.sharedNumPrb), &(rsvdDedicatedPRB), &isTxPayloadLenAdded, NULLP);
1091          }
1092       }
1093    }
1094
1095    /*[Step5]:Traverse each LCID in LcList to calculate the exact Scheduled Bytes
1096     * using allocated BO per LC and Update dlMsgAlloc BO report for MAC */
1097    if (isRetx == FALSE)
1098    {
1099       if(schSpcHqProcCb->lcCb.dedLcList.count != 0)
1100          updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.dedLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1101
1102       updateGrantSizeForBoRpt(&(schSpcHqProcCb->lcCb.defLcList), dciSlotAlloc, NULLP, &(accumalatedSize));
1103    }
1104    else
1105    {
1106       accumalatedSize = (*hqP)->tbInfo[0].tbSzReq;
1107    }
1108
1109    /*Below case will hit if NO LC(s) are allocated due to resource crunch*/
1110    if (!accumalatedSize)
1111    {
1112       if(maxFreePRB == 0)
1113       {
1114          DU_LOG("\nERROR  --> SCH : NO FREE PRB!!");
1115       }
1116       else
1117       {
1118          /*Schedule the LC for next slot*/
1119          DU_LOG("\nDEBUG  -->  SCH : No LC has been scheduled");
1120       }
1121       /* Not Freeing dlMsgAlloc as ZERO BO REPORT to be sent to RLC so that
1122        * Allocation can be done in next slot*/
1123       accumalatedSize = 0;
1124    }
1125
1126    return accumalatedSize;
1127 }
1128
1129 /*******************************************************************
1130  *
1131  * @brief Scheduling of Slots in UL And DL 
1132  *
1133  * @details
1134  *
1135  *    Function : schSliceBasedScheduleSlot
1136  *
1137  *    Functionality: Scheduling of slots in UL and DL specific to 
1138  *       Slice Based scheduling
1139  *
1140  * @params[in] Pointer to Cell
1141  *             Slot timing info
1142  *             Scheduler instance
1143  * @return void
1144  *
1145  * ****************************************************************/
1146 void schSliceBasedScheduleSlot(SchCellCb *cell, SlotTimingInfo *slotInd, Inst schInst)
1147 {
1148    SchSliceBasedCellCb  *schSpcCell;
1149    SchSliceBasedUeCb    *schSpcUeCb;
1150    SchDlHqProcCb  *hqP = NULLP;
1151    SchUlHqProcCb  *ulHqP = NULLP;
1152    CmLList        *pendingUeNode;
1153    CmLList        *node;
1154    uint8_t        ueId;
1155    bool           isRarPending = false, isRarScheduled = false;
1156    bool           isMsg4Pending = false, isMsg4Scheduled = false;
1157    bool           isDlMsgPending = false, isDlMsgScheduled = false;
1158    bool           isUlGrantPending = false, isUlGrantScheduled = false;
1159
1160    schSpcCell = (SchSliceBasedCellCb *)cell->schSpcCell;
1161    
1162    /* Select first UE in the linked list to be scheduled next */
1163    pendingUeNode = schSpcCell->ueToBeScheduled.first;
1164    if(pendingUeNode)
1165    {
1166       if(pendingUeNode->node)
1167       {
1168          ueId = *(uint8_t *)(pendingUeNode->node);
1169          schSpcUeCb = (SchSliceBasedUeCb *)cell->ueCb[ueId-1].schSpcUeCb;
1170
1171          /* If RAR is pending for this UE, schedule PDCCH,PDSCH to send RAR and 
1172           * PUSCH to receive MSG3 as per k0-k2 configuration*/
1173          if(cell->raReq[ueId-1] != NULLP)
1174          {
1175             isRarPending = true;
1176             isRarScheduled = schProcessRaReq(schInst, cell, *slotInd, ueId);
1177          }
1178
1179          /*MSG3 retransmisson*/
1180          if(cell->raCb[ueId-1].retxMsg3HqProc)
1181          {            
1182             schMsg3RetxSchedulingForUe(&(cell->raCb[ueId-1]));
1183          }
1184
1185          /* If MSG4 is pending for this UE, schedule PDCCH,PDSCH to send MSG4 and
1186           * PUCCH to receive UL msg as per k0-k1 configuration  */
1187          if (cell->ueCb[ueId-1].retxMsg4HqProc) //should work from dlmap later tbd
1188          {
1189             /* Retransmission of MSG4 */
1190             isMsg4Pending = true;
1191             if(schProcessMsg4Req(cell, *slotInd, ueId, TRUE, &cell->ueCb[ueId-1].retxMsg4HqProc) == ROK)
1192                isMsg4Scheduled = true;
1193          }
1194          else
1195          {
1196             /* First transmission of MSG4 */
1197             if(cell->raCb[ueId-1].msg4recvd)
1198             {
1199                isMsg4Pending = true;
1200                if(schProcessMsg4Req(cell, *slotInd, ueId, FALSE, &cell->ueCb[ueId-1].msg4HqProc) == ROK)
1201                   isMsg4Scheduled = true;
1202
1203                /* If MSG4 scheduling failed, free the newly assigned HARQ process */
1204                if(!isMsg4Scheduled)
1205                   schDlReleaseHqProcess(cell->ueCb[ueId-1].msg4HqProc);
1206             }
1207          }
1208
1209          if(isRarPending || isMsg4Pending)
1210          {
1211             /* If RAR or MSG is successfully scheduled then
1212              * remove UE from linked list since no pending msgs for this UE */
1213             if(isRarScheduled || isMsg4Scheduled)
1214             {
1215                schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
1216             }
1217             /* If RAR/MSG4 is pending but couldnt be scheduled then,
1218              * put this UE at the end of linked list to be scheduled later */
1219             else
1220             {
1221                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1222             }
1223          }
1224
1225 #ifdef NR_DRX 
1226          if((cell->ueCb[ueId-1].ueDrxInfoPres == true) && (cell->ueCb[ueId-1].drxUeCb.drxDlUeActiveStatus != true))
1227          {
1228             if(pendingUeNode->node)
1229             {
1230                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1231             }
1232          }
1233          else 
1234 #endif
1235          {
1236
1237             /* DL Data */
1238             node = NULLP;
1239             if(schSpcUeCb)
1240                node = schSpcUeCb->hqRetxCb.dlRetxHqList.first;
1241             if(node != NULLP)
1242             {
1243                /* DL Data ReTransmisson */
1244                isDlMsgPending = true;
1245                isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, TRUE, ((SchDlHqProcCb**) &(node->node)));
1246                if(isDlMsgScheduled)
1247                {
1248 #ifdef NR_DRX 
1249                   schDrxStopDlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchDlHqProcCb**) &(node->node)));
1250 #endif
1251                   schSliceBasedRemoveFrmDlHqRetxList(&cell->ueCb[ueId-1], node);
1252                }
1253             }
1254             else
1255             {
1256                /* DL Data new transmission */
1257                if((cell->boIndBitMap) & (1<<ueId))
1258                {
1259                   isDlMsgPending = true;               
1260                   isDlMsgScheduled = schFillBoGrantDlSchedInfo(cell, *slotInd, ueId, FALSE, &hqP);
1261
1262                   /* If DL scheduling failed, free the newly assigned HARQ process */
1263                   if(!isDlMsgScheduled)
1264                      schDlReleaseHqProcess(hqP);
1265                   else
1266                   {
1267 #ifdef NR_DRX
1268                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_DL + SCHED_DELTA);
1269 #endif
1270                   }
1271                }
1272             }
1273
1274             /* Scheduling of UL grant */
1275             node = NULLP;
1276             if(schSpcUeCb)
1277                node = schSpcUeCb->hqRetxCb.ulRetxHqList.first;
1278             if(node != NULLP)
1279             {
1280                /* UL Data ReTransmisson */
1281                isUlGrantPending = true;
1282                isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, TRUE, (SchUlHqProcCb**) &(node->node));
1283                if(isUlGrantScheduled)
1284                {
1285 #ifdef NR_DRX 
1286                   schDrxStopUlHqRetxTmr(cell, &cell->ueCb[ueId-1], ((SchUlHqProcCb**) &(node->node)));
1287 #endif
1288                   schSliceBasedRemoveFrmUlHqRetxList(&cell->ueCb[ueId-1], node);
1289                }
1290             }
1291             else
1292             {
1293                /* UL Data new transmission */
1294                if(cell->ueCb[ueId-1].srRcvd || cell->ueCb[ueId-1].bsrRcvd)
1295                {
1296                   isUlGrantPending = true;
1297                   isUlGrantScheduled = schProcessSrOrBsrReq(cell, *slotInd, ueId, FALSE, &ulHqP);
1298                   if(!isUlGrantScheduled)
1299                      schUlReleaseHqProcess(ulHqP, FALSE);
1300                   else
1301                   {
1302 #ifdef NR_DRX
1303                      schHdlDrxInActvStrtTmr(cell, &cell->ueCb[ueId-1], PHY_DELTA_UL + SCHED_DELTA);
1304 #endif
1305                   }
1306                }
1307             }
1308
1309             if(!isUlGrantPending && !isDlMsgPending)
1310             {
1311                /* No action required */  
1312             }
1313             else if((isUlGrantPending && !isUlGrantScheduled) || (isDlMsgPending && !isDlMsgScheduled))
1314             {
1315                cmLListAdd2Tail(&schSpcCell->ueToBeScheduled, cmLListDelFrm(&schSpcCell->ueToBeScheduled, pendingUeNode));
1316             }
1317             else
1318             {
1319                schSliceBasedRemoveUeFrmScheduleLst(cell, pendingUeNode);
1320             }
1321          }
1322       }
1323    }
1324 }
1325
1326 /*******************************************************************
1327  *
1328  * @brief Initializes all function pointers to Slice Based function handler
1329  *
1330  * @details
1331  *
1332  *    Function : schSliceBasedAllApisInit
1333  *
1334  *    Functionality: Initializes all function pointers to Slice Based 
1335  *       function handler
1336  *
1337  * @params[in] Function pointer array
1338  * @return void
1339  *
1340  * ****************************************************************/
1341 void schSliceBasedAllApisInit(SchAllApis *allSliceBasedApi)
1342 {
1343     /* Interface API function pointers */
1344     allSliceBasedApi->SchCellCfgReq = schSliceBasedCellCfgReq;
1345     allSliceBasedApi->SchCellDeleteReq = schSliceBasedCellDelReq;
1346     allSliceBasedApi->SchAddUeConfigReq = SchSliceBasedAddUeConfigReq;
1347     allSliceBasedApi->SchModUeConfigReq = SchSliceBasedModUeConfigReq;
1348     allSliceBasedApi->SchUeDeleteReq = SchSliceBasedUeDeleteReq; 
1349     allSliceBasedApi->SchDlHarqInd = SchSliceBasedDlHarqInd; 
1350     allSliceBasedApi->SchCrcInd = schSliceBasedProcessCrcInd;
1351     allSliceBasedApi->SchRachInd = schSliceBasedProcessRachInd;
1352     allSliceBasedApi->SchPagingInd = schSliceBasedPagingInd;
1353     allSliceBasedApi->SchRachRsrcReq = schSliceBasedRachRsrcReq; 
1354     allSliceBasedApi->SchRachRsrcRel = schSliceBasedRachRsrcRel;
1355     allSliceBasedApi->SchDlRlcBoInfo = schSliceBasedDlRlcBoInfo;
1356     allSliceBasedApi->SchSrUciInd = schSliceBasedSrUciInd;
1357     allSliceBasedApi->SchBsr = schSliceBasedBsr;
1358
1359     /* Internal API function pointers */
1360     allSliceBasedApi->SchAddToDlHqRetxList = schSliceBasedAddToDlHqRetxList;
1361     allSliceBasedApi->SchAddToUlHqRetxList = schSliceBasedAddToUlHqRetxList;
1362     allSliceBasedApi->SchRemoveFrmDlHqRetxList = schSliceBasedRemoveFrmDlHqRetxList;
1363     allSliceBasedApi->SchRemoveFrmUlHqRetxList = schSliceBasedRemoveFrmUlHqRetxList;
1364     allSliceBasedApi->SchAddUeToSchedule = schSliceBasedAddUeToSchedule;
1365     allSliceBasedApi->SchRemoveUeFrmScheduleLst = schSliceBasedRemoveUeFrmScheduleLst;
1366     allSliceBasedApi->SchInitDlHqProcCb = schSliceBasedInitDlHqProcCb;
1367     allSliceBasedApi->SchInitUlHqProcCb = schSliceBasedInitUlHqProcCb;
1368     allSliceBasedApi->SchFreeDlHqProcCb = schSliceBasedFreeDlHqProcCb;
1369     allSliceBasedApi->SchFreeUlHqProcCb = schSliceBasedFreeUlHqProcCb;
1370     allSliceBasedApi->SchDeleteDlHqProcCb = schSliceBasedDeleteDlHqProcCb;
1371     allSliceBasedApi->SchDeleteUlHqProcCb = schSliceBasedDeleteUlHqProcCb;
1372     allSliceBasedApi->SchScheduleSlot = schSliceBasedScheduleSlot;
1373     allSliceBasedApi->SchScheduleDlLc = schSliceBasedScheduleDlLc;
1374     allSliceBasedApi->SchScheduleUlLc = schSliceBasedScheduleUlLc;
1375 }
1376 /**********************************************************************
1377     End of file
1378 **********************************************************************/
1379