f901ce944c7959f9cb5f2100a66827dc8d787424
[o-du/l2.git] / src / 5gnrmac / mac_ue_mgr.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17  *******************************************************************************/
18
19 /* This file contains UE management handling functionality for MAC */
20
21 /* header include files (.h) */
22 #include "common_def.h"
23 #include "lrg.h"
24 #include "lrg.x"
25 #include "du_app_mac_inf.h"
26 #include "mac_sch_interface.h"
27 #include "lwr_mac_upr_inf.h"
28 #include "mac.h"
29 #include "mac_utils.h"
30
31 /* function pointers for packing slot ind from mac to sch */
32 MacSchUeCreateReqFunc macSchUeCreateReqOpts[] =
33 {
34    packMacSchUeCreateReq,    /* packing for loosely coupled */
35    MacSchUeCreateReq,        /* packing for tightly coupled */
36    packMacSchUeCreateReq     /* packing for light weight loosely coupled */
37 };
38
39 DuMacUeCreateRspFunc DuMacUeCreateRspOpts[] =
40 {
41    packDuMacUeCreateRsp,     /* packing for loosely coupled */
42    DuHandleMacUeCreateRsp,   /* packing for tightly coupled */
43    packDuMacUeCreateRsp,     /* packing for light weight loosly coupled */
44 };
45
46 /*******************************************************************
47  *
48  * @brief Fills mac cell group config to be sent to scheduler
49  *
50  * @details
51  *
52  *    Function : fillMacCellGroupCfg
53  *
54  *    Functionality: Fills mac cell group config to be sent to sch
55  *
56  * @params[in] macCellGrp : mac cell group config at MAC
57  *             *macCellGrpCfg : mac cell group cfg to be filled
58  * @return ROK     - success
59  *         RFAILED - failure
60  *
61  * ****************************************************************/
62 uint8_t fillMacCellGroupCfg(MacCellGrpCfg macCellGrp, SchMacCellGrpCfg  *macCellGrpCfg)
63 {
64    uint8_t           idx;
65    SchSchedReqCfg    *schedReqCfg;
66    SchTagCfg         *tagCfg;
67
68    /* Copy scheduling request config */
69    schedReqCfg = &macCellGrpCfg->schedReqCfg;
70    schedReqCfg->addModListCount = macCellGrp.schReqCfg.addModListCount;
71    if(schedReqCfg->addModListCount > MAX_NUM_SR_CFG_PER_CELL_GRP)
72    {
73       DU_LOG("\nMAC : Scheduling Request Add/Mod Count %d exceeds max limit %d", \
74             schedReqCfg->addModListCount, MAX_NUM_SR_CFG_PER_CELL_GRP);
75       return RFAILED;
76    }
77    for(idx = 0; idx < schedReqCfg->addModListCount; idx++)
78    {
79       schedReqCfg->addModList[idx].schedReqId = \
80          macCellGrp.schReqCfg.addModList[idx].schedReqId;
81       schedReqCfg->addModList[idx].srProhibitTmr = \
82          macCellGrp.schReqCfg.addModList[idx].srProhibitTmr;
83       schedReqCfg->addModList[idx].srTransMax = \
84          macCellGrp.schReqCfg.addModList[idx].srTransMax;
85    }
86    schedReqCfg->relListCount = macCellGrp.schReqCfg.relListCount;
87
88    /* copy TAG config */
89    tagCfg = &macCellGrpCfg->tagCfg;
90    tagCfg->addModListCount = macCellGrp.tagCfg.addModListCount;
91    if(tagCfg->addModListCount > MAX_NUM_TAGS)
92    {
93       DU_LOG("\nMAC : Scheduling Request Add/Mod Count %d exceeds max limit %d", \
94             tagCfg->addModListCount, MAX_NUM_TAGS);
95       return RFAILED;
96    }
97    for(idx = 0; idx < tagCfg->addModListCount; idx++)
98    {
99       tagCfg->addModList[idx].tagId = \
100          macCellGrp.tagCfg.addModList[idx].tagId;
101       tagCfg->addModList[idx].timeAlignmentTmr = \
102          macCellGrp.tagCfg.addModList[idx].timeAlignTimer;
103    }
104    tagCfg->relListCount = macCellGrp.tagCfg.relListCount;
105
106    /* Copy PHR config */
107    if(macCellGrp.phrCfgSetupPres)
108    {
109       macCellGrpCfg->phrCfg.periodicTmr = macCellGrp.phrCfg.periodicTimer;
110       macCellGrpCfg->phrCfg.prohibitTmr =  macCellGrp.phrCfg.prohibitTimer;
111       macCellGrpCfg->phrCfg.txpowerFactorChange = macCellGrp.phrCfg.txPowerFactor;
112       macCellGrpCfg->phrCfg.multiplePhr = macCellGrp.phrCfg.multiplePHR;
113       macCellGrpCfg->phrCfg.dummy = macCellGrp.phrCfg.dummy;
114       macCellGrpCfg->phrCfg.type2OtherCell = macCellGrp.phrCfg.phrType2OtherCell;
115       macCellGrpCfg->phrCfg.modeOtherCG = macCellGrp.phrCfg.phrOtherCG;
116    }
117
118    return ROK;
119 }
120
121 /*******************************************************************
122  *
123  * @brief Fills phy cell group config to be sent to scheduler
124  *
125  * @details
126  *
127  *    Function : fillPhyCellGroupCfg
128  *
129  *    Functionality: Fills phy cell group config to be sent to sch
130  *
131  * @params[in] macUeCfg : Phy cell group config at MAC
132  *             *schPhyCellGrp : phy cell group config to be filled
133  * @return ROK     - success
134  *         RFAILED - failure
135  *
136  * ****************************************************************/
137 uint8_t fillPhyCellGroupCfg(PhyCellGrpCfg macUeCfg, SchPhyCellGrpCfg *schPhyCellGrp)
138 {
139    schPhyCellGrp->pdschHarqAckCodebook = macUeCfg.pdschHarqAckCodebook;
140    schPhyCellGrp->pNrFr1 = macUeCfg.pNrFr1;
141
142    return ROK;
143 }
144
145 /*******************************************************************
146  *
147  * @brief Fills PDSCh serving cell config to send to scheduler
148  *
149  * @details
150  *
151  *    Function : fillPdschServCellCfg 
152  *
153  *    Functionality: Fills PDSCh serving cell config to send to scheduler
154  *
155  * @params[in] macPdschCfg : Pdsch serving cell config at MAC
156  *             *schPdschCfg : Pdsch serving cell config to be filled
157  * @return ROK     - success
158  *         RFAILED - failure
159  *
160  * ****************************************************************/
161 uint8_t fillPdschServCellCfg(PdschServCellCfg macPdschCfg, SchPdschServCellCfg *schPdschCfg) 
162 {
163    schPdschCfg->maxMimoLayers = NULL;
164    if(macPdschCfg.maxMimoLayers)
165    {
166       /* TODO : Optional parameter */
167    }
168
169    schPdschCfg->numHarqProcForPdsch = \
170       macPdschCfg.numHarqProcForPdsch;
171
172    schPdschCfg->maxCodeBlkGrpPerTb = NULL;
173    if(macPdschCfg.maxCodeBlkGrpPerTb)
174    {
175       /* TODO : Optional parameter */
176    }
177
178    schPdschCfg->codeBlkGrpFlushInd = NULL;
179    if(macPdschCfg.codeBlkGrpFlushInd)
180    {
181       /* TODO : Optional parameter */
182    }
183
184    schPdschCfg->xOverhead = NULL;
185    if(macPdschCfg.xOverhead)
186    {
187       /* TODO : Optional parameter */
188    }
189
190    return ROK;
191 }
192
193 /*******************************************************************
194  *
195  * @brief Fills PUSCH cofig in initial UL BWP config for SCH UE Cfg
196  *
197  * @details
198  *
199  *    Function : fillInitalUlBwpPuschCfg
200  *
201  *    Functionality:
202  *       Fills PUSCH cofig in initial UL BWP config for SCH UE Cfg
203  *
204  * @params[in] macPuschCfg : Initial UL-BWP PUSCH cfg at MAC
205  *             schPuschCfg : Initial UL-BWP PUSCH cfg to be filled
206  * @return ROK     - success
207  *         RFAILED - failure
208  *
209  * ****************************************************************/
210 uint8_t fillInitalUlBwpPuschCfg(PuschCfg macPuschCfg, SchPuschCfg *schPuschCfg)
211 {
212    uint8_t   idx;
213
214    schPuschCfg->dmrsUlCfgForPuschMapTypeA.addPos = \
215       macPuschCfg.dmrsUlCfgForPuschMapTypeA.addPos;
216    schPuschCfg->dmrsUlCfgForPuschMapTypeA.transPrecodDisabled.scramblingId0 = \
217       macPuschCfg.dmrsUlCfgForPuschMapTypeA.transPrecodDisabled.scramblingId0;
218    schPuschCfg->resourceAllocType = macPuschCfg.resourceAllocType;
219
220    schPuschCfg->numTimeDomRsrcAlloc = macPuschCfg.numTimeDomRsrcAlloc;
221    if(schPuschCfg->numTimeDomRsrcAlloc > MAX_NUM_UL_ALLOC)
222    {
223       DU_LOG("\nMAC : Number of Time domain resource allocation [%d] exceeds max limit [%d]",\
224             schPuschCfg->numTimeDomRsrcAlloc, MAX_NUM_UL_ALLOC);
225       return RFAILED;
226    }    
227    for(idx = 0; idx < schPuschCfg->numTimeDomRsrcAlloc; idx++)
228    {
229       schPuschCfg->timeDomRsrcAllocList[idx].k2 = \
230          macPuschCfg.timeDomRsrcAllocList[idx].k2;
231       schPuschCfg->timeDomRsrcAllocList[idx].mappingType = \
232          macPuschCfg.timeDomRsrcAllocList[idx].mappingType;
233       schPuschCfg->timeDomRsrcAllocList[idx].startSymbol = \
234          macPuschCfg.timeDomRsrcAllocList[idx].startSymbol; 
235       schPuschCfg->timeDomRsrcAllocList[idx].symbolLength = \
236          macPuschCfg.timeDomRsrcAllocList[idx].symbolLength;
237    }
238
239    schPuschCfg->transformPrecoder = macPuschCfg.transformPrecoder;
240    return ROK;
241 }
242
243 /*******************************************************************
244  *
245  * @brief Fills initail UL BWP config to send to scheduler
246  *
247  * @details
248  *
249  *    Function : fillInitialUlBwp
250  *
251  *    Functionality: Fills initail UL BWP config to send to sch
252  *
253  * @params[in] macInitUlBwp : Initial UL BWP cfg at MAC
254  *             schInitUlBwp : Initial UL BWP cfg to be filled
255  * @return ROK     - success
256  *         RFAILED - failure
257  *
258  * ****************************************************************/
259 uint8_t fillInitialUlBwp(InitialUlBwp macInitUlBwp, SchInitialUlBwp *schInitUlBwp)
260 {
261    schInitUlBwp->pucchCfgPres = macInitUlBwp.pucchPresent;
262    if(schInitUlBwp->pucchCfgPres)
263    {
264       /* TODO : Optional parameter */
265    }
266
267    schInitUlBwp->puschCfgPres = macInitUlBwp.puschPresent;
268    if(schInitUlBwp->puschCfgPres)
269    {
270       if(fillInitalUlBwpPuschCfg(macInitUlBwp.puschCfg, &schInitUlBwp->puschCfg) != ROK)
271       {
272          DU_LOG("\nMAC : fillInitalUlBwpPuschCfg() failed");
273          return RFAILED;
274       }
275    }
276    return ROK;
277 }
278
279 /*******************************************************************
280  *
281  * @brief Fill PDCCH cfg in Initial DL BWP for UE Cfg in Scheduler
282  *
283  * @details
284  *
285  *    Function : fillInitDlBwpPdcchCfg
286  *
287  *    Functionality:
288  *        Fill PDCCH cfg in Initial DL BWP for UE Cfg in Scheduler
289  *
290  * @params[in] macPdcchCfg : Inital DL BWP PDCCH cfg in MAC
291  *             schPdcchCfg : Inital DL BWP PDCCH cfg to be filled
292  * @return ROK     - success
293  *         RFAILED - failure
294  *
295  * ****************************************************************/
296 uint8_t fillInitDlBwpPdcchCfg(PdcchConfig macPdcchCfg, SchPdcchConfig *schPdcchCfg)
297 {
298    uint8_t idx;
299
300    /* Fill CORESET info */
301    schPdcchCfg->numCRsetToAddMod = macPdcchCfg.numCRsetToAddMod;
302    if(schPdcchCfg->numCRsetToAddMod > MAX_NUM_CRSET)
303    {
304       DU_LOG("\nMAC : Number of CORESET to ADD/MOD [%d] exceeds max limit [%d]",\
305             schPdcchCfg->numCRsetToAddMod, MAX_NUM_CRSET);
306       return RFAILED;
307    }
308
309    for(idx = 0; idx < schPdcchCfg->numCRsetToAddMod; idx++)
310    {
311       schPdcchCfg->cRSetToAddModList[idx].cRSetId = \
312          macPdcchCfg.cRSetToAddModList[idx].cRSetId;
313       memcpy(&schPdcchCfg->cRSetToAddModList[idx].freqDomainRsrc,\
314          &macPdcchCfg.cRSetToAddModList[idx].freqDomainRsrc, FREQ_DOM_RSRC_SIZE);
315       schPdcchCfg->cRSetToAddModList[idx].duration = \
316          macPdcchCfg.cRSetToAddModList[idx].duration;
317       schPdcchCfg->cRSetToAddModList[idx].cceRegMappingType = \
318          macPdcchCfg.cRSetToAddModList[idx].cceRegMappingType;
319       schPdcchCfg->cRSetToAddModList[idx].precoderGranularity = \
320          macPdcchCfg.cRSetToAddModList[idx].precoderGranularity;
321       schPdcchCfg->cRSetToAddModList[idx].dmrsScramblingId = \
322          macPdcchCfg.cRSetToAddModList[idx].dmrsScramblingId;
323    }
324
325    schPdcchCfg->numCRsetToRel = macPdcchCfg.numCRsetToRel;
326    if(schPdcchCfg->numCRsetToAddMod > MAX_NUM_CRSET)
327    {
328       DU_LOG("\nMAC : Number of CORESET to release [%d] exceeds max limit [%d]",\
329             schPdcchCfg->numCRsetToRel, MAX_NUM_CRSET);
330       return RFAILED;
331    }
332
333    for(idx = 0; idx < schPdcchCfg->numCRsetToRel; idx++)
334    {
335       /* TODO */
336    }
337
338    /* Fill Search space info */
339    schPdcchCfg->numSearchSpcToAddMod = macPdcchCfg.numSearchSpcToAddMod;
340    if(schPdcchCfg->numSearchSpcToAddMod > MAX_NUM_SEARCH_SPC)
341    {
342       DU_LOG("\nMAC : Number of search space to ADD/MOD [%d] exceeds max [%d]", \
343             schPdcchCfg->numSearchSpcToAddMod, MAX_NUM_SEARCH_SPC);
344       return RFAILED;
345    }
346    for(idx = 0; idx < schPdcchCfg->numSearchSpcToAddMod; idx++)
347    {
348       schPdcchCfg->searchSpcToAddModList[idx].searchSpaceId = \
349          macPdcchCfg.searchSpcToAddModList[idx].searchSpaceId;
350       schPdcchCfg->searchSpcToAddModList[idx].cRSetId = \
351          macPdcchCfg.searchSpcToAddModList[idx].cRSetId;
352       schPdcchCfg->searchSpcToAddModList[idx].mSlotPeriodicityAndOffset = \
353          macPdcchCfg.searchSpcToAddModList[idx].mSlotPeriodicityAndOffset;
354       memcpy(&schPdcchCfg->searchSpcToAddModList[idx].mSymbolsWithinSlot,
355          &macPdcchCfg.searchSpcToAddModList[idx].mSymbolsWithinSlot, \
356          MONITORING_SYMB_WITHIN_SLOT_SIZE);
357       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel1 = \
358          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel1;
359       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel2 = \
360          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel2;
361       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel4 = \
362          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel4;
363       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel8 = \
364          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel8;
365       schPdcchCfg->searchSpcToAddModList[idx].numCandidatesAggLevel16 = \
366          macPdcchCfg.searchSpcToAddModList[idx].numCandidatesAggLevel16;
367       schPdcchCfg->searchSpcToAddModList[idx].searchSpaceType = \
368          macPdcchCfg.searchSpcToAddModList[idx].searchSpaceType;
369       schPdcchCfg->searchSpcToAddModList[idx].ueSpecificDciFormat = \
370          macPdcchCfg.searchSpcToAddModList[idx].ueSpecificDciFormat;
371    }
372
373    schPdcchCfg->numSearchSpcToRel = macPdcchCfg.numSearchSpcToRel;
374    if(schPdcchCfg->numSearchSpcToRel > MAX_NUM_SEARCH_SPC)
375    {
376       DU_LOG("\nMAC : Number of search space to release [%d] exceeds max [%d]", \
377             schPdcchCfg->numSearchSpcToRel, MAX_NUM_SEARCH_SPC);
378       return RFAILED;
379    }
380    for(idx = 0; idx < schPdcchCfg->numSearchSpcToRel; idx++)
381    {
382       /* TODO */
383    }
384
385    return ROK;
386 }
387
388 /*******************************************************************
389  *
390  * @brief Fill PDSCH cfg in Initial DL BWP for UE Cfg in Scheduler
391  *
392  * @details
393  *
394  *    Function : fillInitDlBwpPdschCfg
395  *
396  *    Functionality:
397  *        Fill PDSCH cfg in Initial DL BWP for UE Cfg in Scheduler
398  *
399  * @params[in] macPdschCfg : Inital DL BWP PDSCH cfg at  MAC
400  *             schPdschCfg : Inital DL BWP PDSCH cfg to be filled
401  * @return ROK     - success
402  *         RFAILED - failure
403  *
404  * ****************************************************************/
405 uint8_t fillInitDlBwpPdschCfg(PdschConfig macPdschCfg, SchPdschConfig *schPdschCfg)
406 {
407    uint8_t   idx;
408
409    schPdschCfg->dmrsDlCfgForPdschMapTypeA.addPos = \
410        macPdschCfg.dmrsDlCfgForPdschMapTypeA.addPos;
411    schPdschCfg->resourceAllocType = macPdschCfg.resourceAllocType;
412    schPdschCfg->numTimeDomRsrcAlloc = macPdschCfg.numTimeDomRsrcAlloc;
413    if(schPdschCfg->numTimeDomRsrcAlloc > MAX_NUM_DL_ALLOC)
414    {
415       DU_LOG("\nMAC : Number of time domain resource allocation [%d], exceeds\
416             max limit [%d]", schPdschCfg->numTimeDomRsrcAlloc, MAX_NUM_DL_ALLOC);
417       return RFAILED;
418    }
419
420    for(idx = 0; idx < schPdschCfg->numTimeDomRsrcAlloc; idx++)
421    {
422       schPdschCfg->timeDomRsrcAllociList[idx].mappingType = \
423          macPdschCfg.timeDomRsrcAllociList[idx].mappingType;
424       schPdschCfg->timeDomRsrcAllociList[idx].startSymbol = \
425          macPdschCfg.timeDomRsrcAllociList[idx].startSymbol;
426       schPdschCfg->timeDomRsrcAllociList[idx].symbolLength = \
427          macPdschCfg.timeDomRsrcAllociList[idx].symbolLength;
428    }
429
430    schPdschCfg->rbgSize = macPdschCfg.rbgSize;
431    schPdschCfg->numCodeWordsSchByDci = macPdschCfg.numCodeWordsSchByDci;
432    schPdschCfg->bundlingType = macPdschCfg.bundlingType;
433
434    return ROK;
435 }
436
437 /*******************************************************************
438  *
439  * @brief Fill Initial DL BWP for SCH UE config
440  *
441  * @details
442  *
443  *    Function : fillInitialDlBwp
444  *
445  *    Functionality: Fill Initial DL BWP for SCH UE config
446  *
447  * @params[in] macInitDlBwp : Inital DL BWP cfg at MAC
448  *             schInitDlBwp : Inital DL BWP cfg to be filled
449  * @return ROK     - success
450  *         RFAILED - failure
451  *
452  * ****************************************************************/
453 uint8_t fillInitialDlBwp(InitialDlBwp macInitDlBwp, SchInitalDlBwp *schInitDlBwp)
454 {
455    schInitDlBwp->pdcchCfgPres = macInitDlBwp.pdcchPresent;
456    if(schInitDlBwp->pdcchCfgPres)
457    {
458       if(fillInitDlBwpPdcchCfg(macInitDlBwp.pdcchCfg, &schInitDlBwp->pdcchCfg) != ROK)
459       {
460          DU_LOG("\nMAC : fillInitDlBwpPdcchCfg() failed");
461          return RFAILED;
462       }
463    }
464
465    schInitDlBwp->pdschCfgPres = macInitDlBwp.pdschPresent;
466    if(schInitDlBwp->pdschCfgPres)
467    {
468       if(fillInitDlBwpPdschCfg(macInitDlBwp.pdschCfg,&schInitDlBwp->pdschCfg) != ROK)
469       {
470          DU_LOG("\nMAC : fillInitDlBwpPdschCfg() failed");
471          return RFAILED;
472       }
473    }
474    return ROK;
475 }
476
477 /*******************************************************************
478  *
479  * @brief Fills Sp Cell config to be sent to scheduler
480  *
481  * @details
482  *
483  *    Function : fillSpCellCfg 
484  *
485  *    Functionality: Fills Sp Cell config to be sent to scheduler
486  *
487  * @params[in] macSpCellCfg : SP cell cfg at MAC
488  *             schSpCellCfg : SP cell cfg to be filled
489  * @return ROK     - success
490  *         RFAILED - failure
491  *
492  * ****************************************************************/
493 uint8_t fillSpCellCfg(SpCellCfg macSpCellCfg, SchSpCellCfg *schSpCellCfg)
494 {
495    uint8_t   idx;
496    SchServCellCfgInfo   *servCellCfg;
497
498    schSpCellCfg->servCellIdx = macSpCellCfg.servCellIdx;
499    servCellCfg = &schSpCellCfg->servCellCfg;
500
501    /* Fill initial DL BWP */
502    if(fillInitialDlBwp(macSpCellCfg.servCellCfg.initDlBwp, \
503             &servCellCfg->initDlBwp) != ROK )
504    {
505       DU_LOG("\nMAC : fillInitialDlBwp() failed");
506       return RFAILED;
507    }
508
509    servCellCfg->numDlBwpToAdd = macSpCellCfg.servCellCfg.numDlBwpToAdd;
510    if(servCellCfg->numDlBwpToAdd > MAX_NUM_BWP)
511    {
512       DU_LOG("\nMAC : Number of DL BWP to ADD/MOD [%d] exceeds max limit [%d]",\
513             servCellCfg->numDlBwpToAdd, MAX_NUM_BWP);
514       return RFAILED;
515    }
516    for(idx = 0; idx < servCellCfg->numDlBwpToAdd; idx++)
517    {
518       /* TODO : As of now numDlBwpToAdd = 0 */
519    }
520
521    servCellCfg->firstActvDlBwpId =  macSpCellCfg.servCellCfg.firstActvDlBwpId;
522    servCellCfg->defaultDlBwpId = macSpCellCfg.servCellCfg.defaultDlBwpId;
523    servCellCfg->bwpInactivityTmr = NULL;
524    if(macSpCellCfg.servCellCfg.bwpInactivityTmr)
525    {
526       /* TODO : This is an optional parameter, not filled currently */
527    }
528
529    /* Fill PDSCH serving cell config */
530    if(fillPdschServCellCfg(macSpCellCfg.servCellCfg.pdschServCellCfg, \
531             &servCellCfg->pdschServCellCfg) != ROK)
532    {
533       DU_LOG("\nMAC : fillPdschServCellCfg() failed");
534       return RFAILED;
535    }
536
537    /* Fill Initail UL BWP */
538    if(fillInitialUlBwp(macSpCellCfg.servCellCfg.initUlBwp, \
539             &servCellCfg->initUlBwp) != ROK)
540    {
541       DU_LOG("\nMAC : fillInitialUlBwp() failed");
542       return RFAILED;
543    }
544
545    servCellCfg->numUlBwpToAdd = macSpCellCfg.servCellCfg.numUlBwpToAdd;
546    if(servCellCfg->numUlBwpToAdd > MAX_NUM_BWP)
547    {
548       DU_LOG("\nMAC : Number of UL BWP to ADD/MOD [%d] exceeds max limit [%d]",\
549             servCellCfg->numUlBwpToAdd, MAX_NUM_BWP);
550       return RFAILED;
551    }
552    for(idx = 0; idx < servCellCfg->numUlBwpToAdd; idx++)
553    {
554       /* TODO : As of now numDlBwpToAdd = 0 */
555    }
556    servCellCfg->firstActvUlBwpId =  macSpCellCfg.servCellCfg.firstActvUlBwpId;
557
558    return ROK;
559 }
560
561
562 /*******************************************************************
563  *
564  * @brief Fill logical channel configuration
565  *
566  * @details
567  *
568  *    Function : fillLogicalChannelCfg
569  *
570  *    Functionality: Fill logical channel configuration
571  *
572  * @params[in] macLcCfg : Logical channel Cfg at MAC
573  *             schLcCfg : LC cfg to fill at scheduler
574  * @return ROK     - success
575  *         RFAILED - failure
576  *
577  * ****************************************************************/
578 uint8_t fillLogicalChannelCfg(LcCfg macLcCfg, SchLcCfg *schLcCfg)
579 {
580    schLcCfg->lcId = macLcCfg.lcId;
581    schLcCfg->dlLcCfg.lcp = macLcCfg.dlLcCfg.lcp;
582
583    schLcCfg->drbQos = NULL;
584    if(macLcCfg.drbQos)
585    {
586       /* TODO : Optional Parameter */
587    } 
588
589    schLcCfg->snssai = NULL;
590    if(macLcCfg.snssai)
591    {
592       /* TODO : Optional Parameter */
593    }
594
595    schLcCfg->ulLcCfg = NULL;
596    if(macLcCfg.ulLcCfg)
597    {
598       /* TODO : Optional Parameter */
599    }
600
601    return ROK;
602 }
603
604 /*******************************************************************
605  *
606  * @brief Fills and sends UE configuration to Scheduler
607  *
608  * @details
609  *
610  *    Function : sendAddUeCreateReqToSch
611  *
612  *    Functionality: Fills and sends UE configuration to Scheduler
613  *
614  * @params[in] Ue configuration from DU APP
615  * @return ROK     - success
616  *         RFAILED - failure
617  *
618  * ****************************************************************/
619 uint8_t sendAddUeCreateReqToSch(MacUeCfg *ueCfg)
620 {
621    Pst pst;
622    uint8_t    idx;
623    SchUeCfg   schUeCfg;
624
625    schUeCfg.cellId = ueCfg->cellId;
626    schUeCfg.crnti = ueCfg->crnti;
627
628    /* Copy MAC cell group config */
629    memset(&schUeCfg.macCellGrpCfg, 0, sizeof(SchMacCellGrpCfg));
630    if(fillMacCellGroupCfg(ueCfg->macCellGrpCfg, &schUeCfg.macCellGrpCfg) != ROK)
631    {
632       DU_LOG("\nMAC : fillMacCellGroupCfg() failed");
633       return RFAILED;
634    }
635
636    /* Copy Physical cell group config */
637    memset(&schUeCfg.phyCellGrpCfg, 0,sizeof(SchPhyCellGrpCfg));
638    if(fillPhyCellGroupCfg(ueCfg->phyCellGrpCfg, &schUeCfg.phyCellGrpCfg) != ROK)
639    {
640       DU_LOG("\nMAC : fillPhyCellGroupCfg() failed");
641       return RFAILED;
642    }
643
644    /* Copy sp cell config */
645    memset(&schUeCfg.spCellCfg, 0, sizeof(SchSpCellCfg));
646    if(fillSpCellCfg(ueCfg->spCellCfg, &schUeCfg.spCellCfg) != ROK)
647    {
648       DU_LOG("\nMAC : fillSpCellCfg() failed");
649       return RFAILED;
650    }
651
652    schUeCfg.aggrMaxBitRate = NULL;
653    if(ueCfg->maxAggrBitRate != NULL)
654    {
655
656       MAC_ALLOC(schUeCfg.aggrMaxBitRate, sizeof(SchAggrMaxBitRate));
657       if(!schUeCfg.aggrMaxBitRate)
658       {
659          DU_LOG("\nMAC : Memory allocation failed in sendAddUeCreateReqToSch");
660          return RFAILED;
661       }
662       schUeCfg.aggrMaxBitRate->ulBitRate = ueCfg->maxAggrBitRate->ulBits;
663       schUeCfg.aggrMaxBitRate->dlBitRate = ueCfg->maxAggrBitRate->dlBits;
664    }
665
666    schUeCfg.numLc = ueCfg->numLcs;
667    if(schUeCfg.numLc > MAX_NUM_LC)
668    {
669       DU_LOG("\nMAC : Number of Logical channels %d exceeds max limit %d",\
670             schUeCfg.numLc, MAX_NUM_LC);
671    }  
672    for(idx = 0; idx < schUeCfg.numLc; idx++)
673    {
674       if(fillLogicalChannelCfg(ueCfg->lcCfgList[idx], &schUeCfg.lcCfgList[idx]) != ROK)
675       {
676          DU_LOG("\nMAC : fillLogicalChannelCfg() failed");
677          return RFAILED;
678       }
679    }
680
681    /* Fill event and send UE create request to SCH */
682    FILL_PST_MAC_TO_SCH(pst, EVENT_UE_CREATE_REQ_TO_SCH);
683    return(*macSchUeCreateReqOpts[pst.selector])(&pst, &schUeCfg);
684 }
685
686 /*******************************************************************
687  *
688  * @brief Creates UE Cb and fills ueCfg
689  *
690  * @details
691  *
692  *    Function : createUeCb
693  *
694  *    Functionality: Creates UE Cb and fills ueCfg
695  *
696  * @params[in] MAC UE Configuration
697  * @return ROK     - success
698  *         RFAILED - failure
699  *
700  * ****************************************************************/
701 uint8_t createUeCb(MacUeCfg *ueCfg)
702 {
703    uint16_t  ueIdx, lcIdx, cellIdx;
704    MacUeCb   *ueCb;
705
706    GET_CELL_IDX(ueCfg->cellId, cellIdx);
707
708    /* Validate cell id */
709    if(macCb.macCell[cellIdx]->cellId != ueCfg->cellId)
710    {
711       DU_LOG("\nMAC : Cell Id %d not configured", ueCfg->cellId);
712       return RFAILED;
713    }
714
715    /* Check if max number of UE configured */
716    if(macCb.macCell[cellIdx]->numActvUe > MAX_NUM_UE)
717    {
718       DU_LOG("MAC : Max number of UE [%d] already configured", MAX_NUM_UE);
719       return RFAILED;
720    }
721
722    /* Check if UE already configured */
723    ueCb = &macCb.macCell[cellIdx]->ueCb[ueCfg->ueIdx -1];
724    if(ueCb)
725    {
726       if((ueCb->ueIdx == ueCfg->ueIdx) && (ueCb->crnti == ueCfg->crnti) &&\
727             (ueCb->state == UE_STATE_ACTIVE))
728       {
729          DU_LOG("\n MAC : CRNTI %d already configured ", ueCfg->crnti);
730          return ROKDUP;
731       }
732    }
733
734    /* Fill received Ue Configuration in UeCb */
735    memset(ueCb, 0, sizeof(MacUeCb));
736
737    ueCb->crnti = ueCfg->crnti;
738    ueCb->cellCb = macCb.macCell[cellIdx];
739    ueCb->dlInfo.dlHarqEnt.numHarqProcs = \
740       ueCfg->spCellCfg.servCellCfg.pdschServCellCfg.numHarqProcForPdsch; 
741    ueCb->state = UE_STATE_ACTIVE;
742
743    /* Fill BSR info */
744    switch(ueCfg->macCellGrpCfg.bsrTmrCfg.periodicTimer)
745    {
746       case 0:
747          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_1MS;
748          break;
749       case 1:
750          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_5MS;
751          break;
752       case 2:
753          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_10MS;
754          break;
755       case 3:
756          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_16MS;
757          break;
758       case 4:
759          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_20MS;
760          break;
761       case 5:
762          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_32MS;
763          break;
764       case 6:
765          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_40MS;
766          break;
767       case 7:
768          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_60MS;
769          break;
770       case 8:
771          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_80MS;
772          break;
773       case 9:
774          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_128MS;
775          break;
776       case 10:
777          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_160MS;
778          break;
779       case 11:
780          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_320MS;
781          break;
782       case 12:
783          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_640MS;
784          break;
785       case 13:
786          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_1280MS;
787          break;
788       case 14:
789          ueCb->bsrTmrCfg.periodicTimer = PERIODIC_BSR_TMR_2560MS;
790          break;
791       default:
792          DU_LOG("\nMAC : Invalid BSR Periodic Timer");
793          return RFAILED;
794    }
795
796    switch(ueCfg->macCellGrpCfg.bsrTmrCfg.retxTimer)
797    {   
798       case 0:
799          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_10MS;
800          break;
801       case 1:
802          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_20MS;
803          break;
804       case 2:
805          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_40MS;
806          break;
807       case 3:
808          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_80MS;
809          break;
810       case 4:
811          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_160MS;
812          break;
813       case 5:
814          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_320MS;
815          break;
816       case 6:
817          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_640MS;
818          break;
819       case 7:
820          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_1280MS;
821          break;
822       case 8:
823          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_2560MS;
824          break;
825       case 9:
826          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_5120MS;
827          break;
828       case 10:
829          ueCb->bsrTmrCfg.retxTimer = RETX_BSR_TMR_10240MS;
830          break;
831       default:
832          DU_LOG("\nMAC : Invalid BSR retransmission timer");
833          break;
834    }
835
836    switch(ueCfg->macCellGrpCfg.bsrTmrCfg.srDelayTimer)
837    {
838       case 0:
839          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_20MS;
840          break;
841       case 1:
842          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_40MS;
843          break;
844       case 2:
845          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_64MS;
846          break;
847       case 3:
848          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_128MS;
849          break;
850       case 4:
851          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_512MS;
852          break;
853       case 5:
854          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_1024MS;
855          break;
856       case 6:
857          ueCb->bsrTmrCfg.srDelayTimer = SR_DELAY_TMR_2560MS;
858          break;
859       default:
860          DU_LOG("\nMAC : Invalid SR delay timer");
861          return RFAILED;
862    }
863
864    /* Fill SRB1 info */
865    if(ueCfg->numLcs > MAX_NUM_LC)
866    {
867       DU_LOG("\nMAC : Number of LC to configure[%d] exceeds limit[%d]",\
868             ueCfg->numLcs, MAX_NUM_LC);
869       return RFAILED;
870    }
871
872    for(lcIdx = 0; lcIdx < ueCfg->numLcs; lcIdx++)
873    {
874       ueCb->dlInfo.lcCb[ueCb->dlInfo.numDlLc].lcId = ueCfg->lcCfgList[lcIdx].lcId;
875       ueCb->dlInfo.lcCb[ueCb->dlInfo.numDlLc].lcState = MAC_LC_STATE_ACTIVE;
876       ueCb->dlInfo.numDlLc++;
877    }
878
879    /* Copy RA Cb */
880    for(ueIdx = 0; ueIdx < MAX_NUM_UE; ueIdx++)
881    {
882       if(macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti == ueCb->crnti)
883       {
884          ueCb->raCb = &macCb.macCell[cellIdx]->macRaCb[ueIdx];
885          break;
886       }
887    }
888
889    macCb.macCell[cellIdx]->numActvUe++;
890
891    return ROK;
892 }
893
894 /*******************************************************************
895  *
896  * @brief Handles UE create requst from DU APP
897  *
898  * @details
899  *
900  *    Function : MacProcUeCreateReq
901  *
902  *    Functionality: Handles UE create requst from DU APP
903  *
904  * @params[in] 
905  * @return ROK     - success
906  *         RFAILED - failure
907  *
908  * ****************************************************************/
909 uint8_t MacProcUeCreateReq(Pst *pst, MacUeCfg *ueCfg)
910 {
911    uint8_t ret;
912
913    DU_LOG("\nMAC : UE Create Request for CRNTI[%d]", ueCfg->crnti);
914
915    if(ueCfg)
916    {
917       ret = createUeCb(ueCfg);
918       if(ret == ROK)
919       {
920          ret = sendAddUeCreateReqToSch(ueCfg);
921          if(ret != ROK)
922          {
923             DU_LOG("\nMAC : Failed to send UE Create request to scheduler");
924          }
925       }
926       else 
927       {
928          DU_LOG("\nMAC : Failed to create MAC UE Cb ");
929       }
930    }
931    else
932    {
933       DU_LOG("\nMAC : MAC UE Create request processing failed");
934       ret = RFAILED;
935    }
936    /* FREE shared memory */
937    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, ueCfg, sizeof(MacUeCfg));
938
939    return ret;
940 }
941
942 /*******************************************************************
943  *
944  * @brief Fill and Send UE create response from MAC to DU APP
945  *
946  * @details
947  *
948  *    Function : MacSendUeCreateRsp
949  *
950  *    Functionality: Fill and Send UE create response from MAC to DUAPP
951  *
952  * @params[in] MAC UE create result
953  *             SCH UE create response
954  * @return ROK     - success
955  *         RFAILED - failure
956  *
957  * ****************************************************************/
958 uint8_t MacSendUeCreateRsp(MacRsp result, SchUeCfgRsp *schCfgRsp)
959 {
960    MacUeCfgRsp   *cfgRsp;
961    Pst        rspPst;
962
963    MAC_ALLOC_SHRABL_BUF(cfgRsp, sizeof(MacUeCfgRsp));
964    if(!cfgRsp)
965    {
966       DU_LOG("\nMAC: Memory allocation for UE config response failed");
967       return RFAILED;
968    }
969
970    /* Filling UE Config response */
971    memset(cfgRsp, 0, sizeof(MacUeCfgRsp));
972    cfgRsp->cellId = schCfgRsp->cellId;
973    cfgRsp->ueIdx = schCfgRsp->ueIdx;
974    cfgRsp->result = result;
975
976    /* Fill Post structure and send UE Create response*/
977    memset(&rspPst, 0, sizeof(Pst));
978    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_UE_CREATE_RSP);
979    return DuMacUeCreateRspOpts[rspPst.selector](&rspPst, cfgRsp); 
980
981 }
982
983
984 /*******************************************************************
985  *
986  * @brief  Processes UE create response from scheduler
987  *
988  * @details
989  *
990  *    Function : MacProcSchUeCfgRsp
991  *
992  *    Functionality:
993  *      Processes UE create response from scheduler
994  *      Sends UE create response to DU APP
995  *
996  * @params[in] Pst : Post structure
997  *             schCfgRsp : Scheduler UE cfg response
998  * @return ROK     - success
999  *         RFAILED - failure
1000  *
1001  * ****************************************************************/
1002 uint8_t MacProcSchUeCfgRsp(Pst *pst, SchUeCfgRsp *schCfgRsp)
1003 {
1004    uint8_t result = MAC_DU_APP_RSP_NOK;
1005    uint8_t ret = ROK;
1006    uint16_t cellIdx;
1007
1008    GET_CELL_IDX(schCfgRsp->cellId, cellIdx);
1009
1010    if(schCfgRsp->rsp == RSP_NOK)
1011    {
1012       DU_LOG("\nMAC : SCH UE Create Response : FAILURE [CRNTI %d]", schCfgRsp->crnti);
1013       memset(&macCb.macCell[cellIdx]->ueCb[schCfgRsp->ueIdx -1], 0, sizeof(MacUeCb));
1014       macCb.macCell[cellIdx]->numActvUe--;
1015       result = MAC_DU_APP_RSP_NOK;
1016    }
1017    else
1018    {
1019       DU_LOG("\nMAC : SCH UE Create Response : SUCCESS [CRNTI %d]", schCfgRsp->crnti);
1020       result = MAC_DU_APP_RSP_OK;
1021    }
1022    ret = MacSendUeCreateRsp(result, schCfgRsp);
1023    return ret; 
1024 }
1025
1026
1027 /**********************************************************************
1028   End of file
1029  **********************************************************************/