0572fd7819eab0f44a6fcd5cc792f59ab249cf83
[o-du/l2.git] / src / 5gnrmac / mac_cfg_hdl.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18 /* This file stores handler for MAC and SCH configuration requests */
19 /* header include files (.h) */
20 #include "common_def.h"
21 #include "lrg.h"
22 #include "lrg.x"
23 #include "du_app_mac_inf.h"
24 #include "mac_sch_interface.h"
25 #include "lwr_mac_upr_inf.h"
26 #include "mac.h"
27 #include "rlc_mac_inf.h"
28 #include "mac_upr_inf_api.h"
29 #include "lwr_mac.h"
30 #include "lwr_mac_fsm.h"
31 #include "mac_utils.h"
32 #include "lwr_mac_phy.h"
33
34 uint8_t ssbPeriodicity[6] = {5, 10, 20, 40, 80, 160};
35
36 uint8_t MacSchCellCfgReq(Pst *pst, MacCellCfg  *macCellCfg);
37
38 packMacCellCfgConfirm packMacCellCfmOpts[] =
39 {
40    packMacCellCfgCfm,      /* packing for loosely coupled */
41    duHandleMacCellCfgCfm,      /* packing for tightly coupled */
42    packMacCellCfgCfm,    /* packing for light weight loosly coupled */
43 };
44
45 MacDuCellDeleteRspFunc macDuCellDeleteRspOpts[] =
46 {
47    packDuMacCellDeleteRsp,   /* packing for loosely coupled */
48    DuProcMacCellDeleteRsp,   /* packing for tightly coupled */
49    packDuMacCellDeleteRsp   /* packing for light weight loosly coupled */
50 };
51
52 MacDuSliceCfgRspFunc macDuSliceCfgRspOpts[] =
53 {
54    packDuMacSliceCfgRsp,   /* packing for loosely coupled */
55    DuProcMacSliceCfgRsp,   /* packing for tightly coupled */
56    packDuMacSliceCfgRsp   /* packing for light weight loosly coupled */
57 };
58
59 MacDuSliceRecfgRspFunc macDuSliceRecfgRspOpts[] =
60 {
61    packDuMacSliceRecfgRsp,   /* packing for loosely coupled */
62    DuProcMacSliceRecfgRsp,   /* packing for tightly coupled */
63    packDuMacSliceRecfgRsp    /* packing for light weight loosly coupled */
64 };
65
66 MacDuStatsRspFunc macDuStatsRspOpts[] =
67 {
68    packDuMacStatsRsp,   /* packing for loosely coupled */
69    DuProcMacStatsRsp,   /* packing for tightly coupled */
70    packDuMacStatsRsp   /* packing for light weight loosly coupled */
71 };
72
73
74 /**
75  * @brief Layer Manager  Configuration request handler for Scheduler
76  *
77  * @details
78  *
79  *     Function : MacSchGenCfgReq
80  *
81  *     This function receives general configurations for Scheduler
82  *     from DU APP and forwards to Scheduler.
83  *
84  *  @param[in]  Pst *pst, the post structure
85  *  @param[in]  RgMngmt *cfg, the configuration parameter's structure
86  *  @return 
87  *      -# ROK
88  **/
89 uint8_t MacSchGenCfgReq(Pst *pst, RgMngmt *cfg)
90 {
91    Pst schPst;
92
93    DU_LOG("\nINFO  -->  MAC : Received Scheduler gen config at MAC");
94    memset(&schPst, 0, sizeof(Pst));
95    FILL_PST_MAC_TO_SCH(schPst, EVENT_SCH_GEN_CFG);
96    
97    return(SchMessageRouter(&schPst, (void *)cfg));
98 }
99
100 /**
101  * @brief Layer Manager Configuration response from Scheduler
102  *
103  * @details
104  *
105  *     Function : SchSendCfgCfm
106  *
107  *     This function sends general configurations response from
108  *     Scheduler to DU APP.
109  *
110  *  @param[in]  Pst *pst, the post structure
111  *  @param[in]  RgMngmt *cfm, the configuration confirm structure
112  *  @return 
113  *      -# ROK
114  **/
115 uint8_t SchSendCfgCfm(Pst *pst, RgMngmt  *cfm)
116 {
117    DU_LOG("\nDEBUG  -->  MAC : Sending Scheduler config confirm to DU APP");
118    pst->dstEnt = ENTDUAPP;
119    pst->dstInst = 0;
120    pst->srcInst = 0;
121    pst->selector = ODU_SELECTOR_LC;
122    RgMiLrgSchCfgCfm(pst, cfm);
123
124    return ROK;
125 }
126
127 /**
128  * @brief Layer Manager Configuration request handler.
129  *
130  * @details
131  *
132  *     Function : MacProcCellCfgReq
133  *
134  *     This function handles the gNB and cell configuration
135  *     request received from DU APP.
136  *     This API unapcks and forwards the config towards SCH
137  *
138  *  @param[in]  Pst           *pst
139  *  @param[in]  MacCellCfg    *macCellCfg
140  *  @return  
141  *      -# ROK
142  **/
143 uint8_t MacProcCellCfgReq(Pst *pst, MacCellCfg *macCellCfg)
144 {
145    Pst cfmPst;
146    uint16_t cellIdx, scsInKhz = 0;
147    uint8_t ret = ROK, plmnIdx = 0,sliceIdx = 0;
148    MacCellCb     *macCellCb;
149
150    memset((uint8_t *)&cfmPst, 0, sizeof(Pst));
151
152    MAC_ALLOC(macCellCb, sizeof(MacCellCb));
153    if(macCellCb == NULLP)
154    {
155       DU_LOG("\nERROR  -->  MAC : macCellCb is NULL at handling of macCellCfg\n");
156       return RFAILED;
157    }
158    memset(macCellCb, 0, sizeof(MacCellCb));
159
160    GET_CELL_IDX(macCellCfg->cellId, cellIdx);
161    macCb.macCell[cellIdx] = macCellCb;
162    macCb.macCell[cellIdx]->cellId = macCellCfg->cellId;
163    scsInKhz = convertScsEnumValToScsVal(macCellCfg->cellCfg.subCarrSpacing);
164    
165    /*Ref : 3GPP 38.211 Table 4.2-1: SCS = (2 ^ numerology * 15kHz)*/
166    macCb.macCell[cellIdx]->numerology = log2(scsInKhz/BASE_SCS);
167    macCb.macCell[cellIdx]->numOfSlots = 10 * (1 << (macCb.macCell[cellIdx]->numerology));
168    memcpy(&macCb.macCell[cellIdx]->macCellCfg, macCellCfg, sizeof(MacCellCfg));
169
170    MAC_ALLOC(macCb.macCell[cellIdx]->macCellCfg.cellCfg.sib1Cfg.sib1Pdu, \
171          macCb.macCell[cellIdx]->macCellCfg.cellCfg.sib1Cfg.sib1PduLen);
172    if(macCb.macCell[cellIdx]->macCellCfg.cellCfg.sib1Cfg.sib1Pdu == NULLP)
173    {
174       DU_LOG("\nERROR  -->  MAC : macCellCb is NULL at handling of sib1Pdu of macCellCfg\n");
175       return RFAILED;
176    }
177    memcpy(macCb.macCell[cellIdx]->macCellCfg.cellCfg.sib1Cfg.sib1Pdu, macCellCfg->cellCfg.sib1Cfg.sib1Pdu, \
178          macCb.macCell[cellIdx]->macCellCfg.cellCfg.sib1Cfg.sib1PduLen);
179
180    for(plmnIdx = 0; plmnIdx < MAX_PLMN; plmnIdx++)
181    {
182       macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].numSupportedSlice = macCellCfg->cellCfg.plmnInfoList[plmnIdx].numSupportedSlice;
183       MAC_ALLOC(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai, macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].numSupportedSlice\
184             * sizeof(Snssai*));
185       if(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai == NULLP)
186       {
187          DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacProcCellCfgReq");
188          return RFAILED;
189       }
190
191       if(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai)
192       {
193          for(sliceIdx=0; sliceIdx<macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].numSupportedSlice; sliceIdx++)
194          {
195             if(macCellCfg->cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx])
196             {
197                MAC_ALLOC(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx], sizeof(Snssai));
198                if(!macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx])
199                {
200                   DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacProcCellCfgReq");
201                   return RFAILED;
202                }
203                memcpy(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx], macCellCfg->cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx],\
204                      sizeof(Snssai));
205             }
206          }
207       }
208    }
209    /* Send cell cfg to scheduler */
210    ret = MacSchCellCfgReq(pst, macCellCfg);
211    if(ret != ROK)
212    {
213       MacCellCfgCfm macCellCfgCfm;
214       macCellCfgCfm.rsp = RSP_NOK;
215       macCellCfgCfm.cellId = macCellCfg->cellId;
216       /* Fill Pst */
217       FILL_PST_MAC_TO_DUAPP(cfmPst, EVENT_MAC_CELL_CONFIG_CFM);
218       cfmPst.selector  = ODU_SELECTOR_LC;
219
220       ret = (*packMacCellCfmOpts[cfmPst.selector])(&cfmPst,&macCellCfgCfm);
221    }
222    else
223    {
224       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macCellCfg ,sizeof(MacCellCfg));
225    }
226    return ret;
227 } /* end of MacProcCellCfgReq */
228
229 /**
230  * @brief Layer Manager Configuration request handler.
231  *
232  * @details
233  *
234  *     Function : MacSchCellCfgReq
235  *
236  *     This function sends cell configuration to SCH
237  *
238  *  @param[in]  Pst           *pst
239  *  @param[in]  MacCellCfg    *macCellCfg
240  *  @return  
241  *      -# ROK
242  **/
243 uint8_t MacSchCellCfgReq(Pst *pst, MacCellCfg *macCellCfg)
244 {
245    SchCellCfg schCellCfg;
246    Pst        cfgPst;
247    uint8_t    ssbMaskIdx = 0, rsrcListIdx = 0, sliceIdx=0, plmnIdx = 0;
248
249    memset(&cfgPst, 0, sizeof(Pst));
250    memset(&schCellCfg, 0, sizeof(SchCellCfg));
251    schCellCfg.cellId = macCellCfg->cellId;
252    schCellCfg.phyCellId = macCellCfg->cellCfg.phyCellId;
253
254    for(plmnIdx = 0; plmnIdx < MAX_PLMN; plmnIdx++)
255    {
256       schCellCfg.plmnInfoList[plmnIdx].plmn = macCellCfg->cellCfg.plmnInfoList[plmnIdx].plmn;
257       if(macCellCfg->cellCfg.plmnInfoList[plmnIdx].snssai) 
258       {
259          schCellCfg.plmnInfoList[plmnIdx].numSliceSupport = macCellCfg->cellCfg.plmnInfoList[plmnIdx].numSupportedSlice;
260          MAC_ALLOC(schCellCfg.plmnInfoList[plmnIdx].snssai, schCellCfg.plmnInfoList[plmnIdx].numSliceSupport * sizeof(Snssai*));
261          if(!schCellCfg.plmnInfoList[plmnIdx].snssai)
262          {
263             DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacSchCellCfgReq");
264             return RFAILED;
265          }
266          for(sliceIdx=0; sliceIdx<schCellCfg.plmnInfoList[plmnIdx].numSliceSupport; sliceIdx++)
267          {
268             if(macCellCfg->cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx])
269             {
270                MAC_ALLOC(schCellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx], sizeof(Snssai));
271                if(!schCellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx])
272                {
273                   DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacSchCellCfgReq");
274                   return RFAILED;
275                }
276                memcpy(schCellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx], macCellCfg->cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx],  sizeof(Snssai));
277             }
278          }
279       }
280    }
281
282    schCellCfg.dupMode = macCellCfg->cellCfg.dupType;
283    schCellCfg.dlBandwidth = macCellCfg->carrCfg.dlBw;
284    schCellCfg.ulBandwidth = macCellCfg->carrCfg.ulBw;
285
286    schCellCfg.dlCfgCommon.schFreqInfoDlSib.offsetToPointA = macCellCfg->ssbCfg.ssbOffsetPointA;
287    schCellCfg.dlCfgCommon.schFreqInfoDlSib.schSpcCarrier[0].subCarrierSpacing = macCellCfg->ssbCfg.scsCmn;
288
289    /* fill initial DL BWP */
290    schCellCfg.dlCfgCommon.schInitialDlBwp.bwp.freqAlloc.startPrb = macCellCfg->cellCfg.initialDlBwp.bwp.firstPrb;
291    schCellCfg.dlCfgCommon.schInitialDlBwp.bwp.freqAlloc.numPrb = macCellCfg->cellCfg.initialDlBwp.bwp.numPrb;
292    schCellCfg.dlCfgCommon.schInitialDlBwp.bwp.scs = macCellCfg->cellCfg.initialDlBwp.bwp.scs;
293    schCellCfg.dlCfgCommon.schInitialDlBwp.bwp.cyclicPrefix = macCellCfg->cellCfg.initialDlBwp.bwp.cyclicPrefix;
294    
295    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.searchSpaceId =
296       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.searchSpaceId;
297    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.coresetId =
298       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.coresetId;
299    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.monitoringSlot =
300       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.monitoringSlot;
301    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.duration =
302       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.duration;
303    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.monitoringSymbol =
304       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.monitoringSymbol;
305    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel1 =
306       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel1;
307    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel2 =
308       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel2;
309    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel4 =
310       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel4;
311    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel8 =
312       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel8;
313    schCellCfg.dlCfgCommon.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel16 =
314       macCellCfg->cellCfg.initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel16;
315    
316    schCellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.numTimeDomAlloc = macCellCfg->cellCfg.initialDlBwp.pdschCommon.numTimeDomAlloc;
317    for(rsrcListIdx = 0; rsrcListIdx<macCellCfg->cellCfg.initialDlBwp.pdschCommon.numTimeDomAlloc; rsrcListIdx++)
318    {
319       schCellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].k0 = 
320          macCellCfg->cellCfg.initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].k0;
321       schCellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType =
322          macCellCfg->cellCfg.initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType;
323       schCellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol =
324          macCellCfg->cellCfg.initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol;
325       schCellCfg.dlCfgCommon.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].lengthSymbol =
326          macCellCfg->cellCfg.initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].lengthSymbol;
327    }
328
329    /* fill SIB1 scheduler parameters */
330    schCellCfg.dlCfgCommon.schPcchCfg.numPO  =  macCellCfg->cellCfg.sib1Cfg.pagingCfg.numPO;
331    schCellCfg.dlCfgCommon.schPcchCfg.poPresent = macCellCfg->cellCfg.sib1Cfg.pagingCfg.poPresent;
332    if(schCellCfg.dlCfgCommon.schPcchCfg.poPresent)
333    {
334       memcpy(schCellCfg.dlCfgCommon.schPcchCfg.pagingOcc, macCellCfg->cellCfg.sib1Cfg.pagingCfg.pagingOcc, MAX_PO_PER_PF);
335    }
336
337    /* fill initial UL BWP */
338    schCellCfg.ulCfgCommon.schInitialUlBwp.bwp.freqAlloc.startPrb = macCellCfg->cellCfg.initialUlBwp.bwp.firstPrb;
339    schCellCfg.ulCfgCommon.schInitialUlBwp.bwp.freqAlloc.numPrb = macCellCfg->cellCfg.initialUlBwp.bwp.numPrb;
340    schCellCfg.ulCfgCommon.schInitialUlBwp.bwp.scs = macCellCfg->cellCfg.initialUlBwp.bwp.scs;
341    schCellCfg.ulCfgCommon.schInitialUlBwp.bwp.cyclicPrefix = macCellCfg->cellCfg.initialUlBwp.bwp.cyclicPrefix;
342    /* fill RACH config params */
343    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.prachCfgGeneric.prachCfgIdx   = macCellCfg->prachCfg.prachCfgIdx;
344    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.prachCfgGeneric.msg1Fdm       = macCellCfg->prachCfg.msg1Fdm;
345    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.prachCfgGeneric.msg1FreqStart = macCellCfg->prachCfg.msg1FreqStart;
346    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.prachCfgGeneric.zeroCorrZoneCfg = macCellCfg->prachCfg.fdm[0].zeroCorrZoneCfg; 
347    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.prachCfgGeneric.raRspWindow = macCellCfg->prachCfg.raRspWindow;
348
349    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.totalNumRaPreamble = macCellCfg->prachCfg.totalNumRaPreamble;
350    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.ssbPerRach    = macCellCfg->prachCfg.ssbPerRach;
351    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.numCbPreamblePerSsb = macCellCfg->prachCfg.numCbPreamblePerSsb;
352    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.raContResTmr = macCellCfg->prachCfg.raContResTmr;
353    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.rsrpThreshSsb = macCellCfg->prachCfg.rsrpThreshSsb;
354    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.rootSeqIdx    = macCellCfg->prachCfg.fdm[0].rootSeqIdx;
355    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.numRootSeq    = macCellCfg->prachCfg.fdm[0].numRootSeq;
356    schCellCfg.ulCfgCommon.schInitialUlBwp.schRachCfg.msg1SubcSpacing = \
357                                             macCellCfg->prachCfg.prachSubcSpacing;
358
359    schCellCfg.ulCfgCommon.schInitialUlBwp.pucchCommon.pucchResourceCommon = \
360                                                                 macCellCfg->cellCfg.initialUlBwp.pucchCommon.pucchResourceCommon;
361    schCellCfg.ulCfgCommon.schInitialUlBwp.pucchCommon.pucchGroupHopping = \
362                                                                 macCellCfg->cellCfg.initialUlBwp.pucchCommon.pucchGroupHopping;
363    schCellCfg.ulCfgCommon.schInitialUlBwp.puschCommon.numTimeDomRsrcAlloc = \
364                                                                 macCellCfg->cellCfg.initialUlBwp.puschCommon.numTimeDomRsrcAlloc;
365    for(rsrcListIdx = 0; rsrcListIdx < macCellCfg->cellCfg.initialUlBwp.puschCommon.numTimeDomRsrcAlloc; rsrcListIdx++)
366    {
367       schCellCfg.ulCfgCommon.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].k2 = 
368          macCellCfg->cellCfg.initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].k2;
369       schCellCfg.ulCfgCommon.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType =
370          macCellCfg->cellCfg.initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType;
371       schCellCfg.ulCfgCommon.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol =
372          macCellCfg->cellCfg.initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol;
373       schCellCfg.ulCfgCommon.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].symbolLength =
374          macCellCfg->cellCfg.initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].symbolLength;
375    }
376
377 #ifdef NR_TDD
378    memcpy(&schCellCfg.tddCfg, &macCellCfg->tddCfg, sizeof(TDDCfg));
379 #endif
380
381    /* fill ssb scheduler parameters */
382    for(ssbMaskIdx=0; ssbMaskIdx<SSB_MASK_SIZE; ssbMaskIdx++)
383    {
384       schCellCfg.ssbPosInBurst[ssbMaskIdx] = macCellCfg->ssbCfg.ssbMask[ssbMaskIdx];
385    }
386    schCellCfg.ssbPeriod    = ssbPeriodicity[macCellCfg->ssbCfg.ssbPeriod];
387    schCellCfg.ssbFrequency = macCellCfg->cellCfg.ssbFreq;
388    schCellCfg.dmrsTypeAPos = macCellCfg->ssbCfg.dmrsTypeAPos;
389    schCellCfg.ssbScs       = macCellCfg->cellCfg.subCarrSpacing;
390    schCellCfg.pdcchCfgSib1.coresetZeroIndex = macCellCfg->cellCfg.sib1Cfg.pdcchCfgSib1.coresetZeroIndex;
391    schCellCfg.pdcchCfgSib1.searchSpaceZeroIndex = macCellCfg->cellCfg.sib1Cfg.pdcchCfgSib1.searchSpaceZeroIndex;
392    schCellCfg.ssbPbchPwr = macCellCfg->ssbCfg.ssbPbchPwr;
393    schCellCfg.ssbSubcOffset = macCellCfg->ssbCfg.ssbScOffset;
394    schCellCfg.sib1PduLen = macCellCfg->cellCfg.sib1Cfg.sib1PduLen;
395    
396    FILL_PST_MAC_TO_SCH(cfgPst, EVENT_SCH_CELL_CFG);
397
398    return(SchMessageRouter(&cfgPst, (void *)&schCellCfg));
399 } /* end of MacSchCellCfgReq */
400
401
402 /*******************************************************************
403  *
404  * @brief Sends Cell config confirm to DU APP
405  *
406  * @details
407  *
408  *    Function : MacSendCellCfgCfm
409  *
410  *    Functionality:
411  *      Sends Cell config confirm to DU APP
412  *
413  * @params[in] Response status
414  * @return void
415  *
416  * ****************************************************************/
417 void MacSendCellCfgCfm(uint16_t cellId, uint8_t response)
418 {
419    Pst pst;
420    uint16_t   cellIdx;
421    MacCellCfgCfm macCellCfgCfm;
422
423    memset(&pst, 0, sizeof(Pst));
424
425    GET_CELL_IDX(cellId, cellIdx);
426    macCellCfgCfm.cellId = macCb.macCell[cellIdx]->macCellCfg.cellId;
427    macCellCfgCfm.rsp = response;
428
429    /* Fill Pst */
430    FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_CELL_CONFIG_CFM);
431    pst.selector  = ODU_SELECTOR_LC;
432
433    (*packMacCellCfmOpts[pst.selector])(&pst,&macCellCfgCfm);
434 }
435
436
437 /**
438  * @brief Layer Manager Configuration response handler.
439  *
440  * @details
441  *
442  *     Function : MacProcSchCellCfgCfm
443  *
444  *     This function processes cell configuration to SCH
445  *
446  *  @param[in]  Pst           *pst
447  *  @param[in]  SchCellCfgCfm *schCellCfgCfm
448  *  @return  int
449  *      -# ROK
450  **/
451 uint8_t MacProcSchCellCfgCfm(Pst *pst, SchCellCfgCfm *schCellCfgCfm)
452 {
453    uint16_t *cellId = NULLP;
454
455 #ifdef CALL_FLOW_DEBUG_LOG
456    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_SCH_CELL_CFG_CFM\n");
457 #endif
458
459    if(schCellCfgCfm->rsp == RSP_OK)
460    {
461       cellId = &schCellCfgCfm->cellId;
462 #ifdef INTEL_TIMER_MODE
463       sendToLowerMac(UL_IQ_SAMPLE, 0, (void *)cellId);
464 #else
465       sendToLowerMac(CONFIG_REQUEST, 0, (void *)cellId);
466 #endif
467    }
468    else
469    {
470       MacSendCellCfgCfm(schCellCfgCfm->cellId, RSP_NOK);
471    }
472    return ROK;
473 }
474
475 /*******************************************************************
476  *
477  * @brief MAC handler for config response from PHY
478  *
479  * @details
480  *
481  *    Function : fapiMacConfigRsp
482  *
483  *    Functionality:
484  *     Processes config response from PHY and sends cell config
485  *     confirm to DU APP
486  *
487  * @params[in]
488  * @return void
489  *
490  * ****************************************************************/
491 void fapiMacConfigRsp(uint16_t cellId)
492 {
493    /* TODO : Processing of config response from PHY */
494
495    /* Send cell config cfm to DU APP */
496    MacSendCellCfgCfm(cellId, RSP_OK);
497 }
498
499 /*******************************************************************
500  *
501  * @brief Fill and Send Cell Delete response from MAC to DU APP
502  *
503  * @details
504  *
505  *    Function : MacSendCellDeleteRsp
506  *
507  *    Functionality: Fill and Send Cell Delete response from MAC to DUAPP
508  *
509  * @params[in] MAC Cell delete result
510  *             SCH Cell delete response
511  * @return ROK     - success
512  *         RFAILED - failure
513  *
514  * ****************************************************************/
515 uint8_t MacSendCellDeleteRsp(CauseOfResult  status, uint8_t cellId)
516 {
517    MacCellDeleteRsp *deleteRsp=NULLP;
518    Pst            rspPst;
519
520    MAC_ALLOC_SHRABL_BUF(deleteRsp, sizeof(MacCellDeleteRsp));
521    if(!deleteRsp)
522    {
523       DU_LOG("\nERROR  -->  MAC : MacSendCellDeleteRsp(): Memory allocation for Cell delete response failed");
524       return RFAILED;
525    }
526
527    /* Filling CELL delete response */
528    
529    memset(deleteRsp, 0, sizeof(MacCellDeleteRsp));
530    deleteRsp->cellId = cellId;
531    deleteRsp->status = status;
532
533    /* Fill Post structure and send CELL delete response*/
534    memset(&rspPst, 0, sizeof(Pst));
535    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_CELL_DELETE_RSP);
536    return (*macDuCellDeleteRspOpts[rspPst.selector])(&rspPst, deleteRsp);
537 }
538
539 /*******************************************************************
540  *
541  * @brief  Processes CELL delete response from scheduler
542  *
543  * @details
544  *
545  *    Function : MacProcSchCellDeleteRsp
546  *
547  *    Functionality:
548  *      Processes CELL delete from scheduler
549  *
550  * @params[in] Pst : Post structure
551  *             schCellDelRsp : Scheduler CELL delete respons
552  * @return ROK     - success
553  *         RFAILED - failure
554  *
555  * * ****************************************************************/
556 uint8_t MacProcSchCellDeleteRsp(Pst *pst, SchCellDeleteRsp *schCellDelRsp)
557 {
558    uint8_t  ret = ROK, sliceIdx = 0, plmnIdx = 0;
559    uint16_t cellIdx=0;
560    CauseOfResult  cause;
561
562 #ifdef CALL_FLOW_DEBUG_LOG
563    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_CELL_DELETE_RSP_TO_MAC\n");
564 #endif  
565
566    if(schCellDelRsp)
567    {
568       if(schCellDelRsp->rsp == RSP_OK)
569       {
570          DU_LOG("\nINFO   -->  MAC : SCH CELL Delete response for cellId[%d] is successful ", \
571                schCellDelRsp->cellId);
572          GET_CELL_IDX(schCellDelRsp->cellId, cellIdx);
573          if(macCb.macCell[cellIdx])
574          {
575             if(macCb.macCell[cellIdx]->cellId == schCellDelRsp->cellId)
576             {
577                cause = SUCCESSFUL;
578                for(plmnIdx = 0; plmnIdx < MAX_PLMN; plmnIdx++)
579                {
580                   if(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai)
581                   {
582                      for(sliceIdx = 0; sliceIdx<macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].numSupportedSlice; sliceIdx++)
583                      {
584                         MAC_FREE(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai[sliceIdx], sizeof(Snssai));
585                      }
586                      MAC_FREE(macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].snssai, macCb.macCell[cellIdx]->macCellCfg.cellCfg.plmnInfoList[plmnIdx].\
587                            numSupportedSlice * sizeof(Snssai*));
588                   }
589                }
590                MAC_FREE(macCb.macCell[cellIdx]->macCellCfg.cellCfg.sib1Cfg.sib1Pdu, \
591                      macCb.macCell[cellIdx]->macCellCfg.cellCfg.sib1Cfg.sib1PduLen);
592                MAC_FREE(macCb.macCell[cellIdx], sizeof(MacCellCb));
593             }
594             else
595             {
596                DU_LOG("ERROR  -->  MAC : MacProcSchCellDeleteRsp(): CellId[%d] does not exists", schCellDelRsp->cellId);
597                cause = CELLID_INVALID;
598                ret = RFAILED;
599             }
600          }
601          else
602          {
603             DU_LOG("ERROR  -->  MAC : MacProcSchCellDeleteRsp(): CellId[%d] does not exists", schCellDelRsp->cellId);
604             cause = CELLID_INVALID;
605             ret = RFAILED;
606          }
607       }
608       else
609       {
610          DU_LOG("ERROR  -->  MAC : MacProcSchCellDeleteRsp(): CellId[%d] does not exists", schCellDelRsp->cellId);
611          cause = CELLID_INVALID;
612          ret = RFAILED;
613       }
614       if(MacSendCellDeleteRsp(cause, schCellDelRsp->cellId) != ROK)
615       {
616          DU_LOG("\nERROR  -->  MAC: MacProcSchCellDeleteRsp(): Failed to send CELL delete response");
617          ret = RFAILED;
618       }
619
620    }
621    else
622    {
623       DU_LOG("\nERROR  -->  MAC: MacProcSchCellDeleteRsp(): schCellDelRsp is NULL");
624       ret = RFAILED;
625    }
626    return ret;
627 }
628
629 /*******************************************************************
630  *
631  * @brief Sends Cell delete req to Scheduler
632  *
633  * @details
634  *
635  *    Function : sendCellDelReqToSch
636  *
637  *    Functionality: sends Cell delete req to Scheduler
638  *
639  * @params[in]  SchCellDelete *schCellDel
640  * @return ROK     - success
641  *         RFAILED - failure
642  *
643  * ****************************************************************/
644
645 uint8_t sendCellDelReqToSch(SchCellDeleteReq *schCellDelReq)
646 {
647    Pst schPst;
648    FILL_PST_MAC_TO_SCH(schPst, EVENT_CELL_DELETE_REQ_TO_SCH);
649    return(SchMessageRouter(&schPst, (void *)schCellDelReq));
650 }
651
652 /*******************************************************************
653  *
654  * @brief Handles CELL Delete requst from DU APP
655  *
656  * @details
657  *
658  *    Function : MacProcCellDeleteReq
659  *
660  *    Functionality: Handles CELL Delete requst from DU APP
661  *
662  * @params[in] Pst *pst, MacCellDelete *cellDelete
663  * @return ROK     - success
664  *         RFAILED - failure
665  *
666  *
667  * ****************************************************************/
668 uint8_t MacProcCellDeleteReq(Pst *pst, MacCellDeleteReq *cellDelete)
669 {
670    uint8_t ret = ROK, cellIdx=0;
671    SchCellDeleteReq schCellDelete;
672
673    DU_LOG("\nINFO   -->  MAC : Cell Delete Request received for cellId[%d]", cellDelete->cellId);
674
675    if(cellDelete)
676    {
677       GET_CELL_IDX(cellDelete->cellId, cellIdx);
678       if(macCb.macCell[cellIdx])
679       {
680          if(macCb.macCell[cellIdx]->cellId == cellDelete->cellId)
681          {
682             memset(&schCellDelete, 0, sizeof(SchCellDeleteReq ));
683             schCellDelete.cellId =  cellDelete->cellId;
684             ret = sendCellDelReqToSch(&schCellDelete);
685             if(ret != ROK)
686             {
687                DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Failed to send UE Delete Request to SCH");
688                ret = RFAILED;
689             }
690          }
691          else
692          {
693             DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Failed to find the MacUeCb of CellId = %d",\
694             cellDelete->cellId);
695             ret = RFAILED;
696          }
697       }
698       else
699       {
700          DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Failed to find the MacUeCb of CellId = %d",\
701                cellDelete->cellId);
702          ret = RFAILED;
703       }
704
705       if(ret == RFAILED)
706       {
707           DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Sending failure response to DU");
708           if(MacSendCellDeleteRsp(CELLID_INVALID, cellDelete->cellId) != ROK)
709           {
710              DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): failed to send cell delete rsp for cellID[%d]",\
711              cellDelete->cellId);
712           }
713
714       }
715       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cellDelete, sizeof(MacCellDeleteReq));
716    }
717    else
718    {
719       DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Received MacCellDelete is NULL");
720       ret = RFAILED;
721    }
722    return ret;
723 }
724
725 /**
726  * @brief free the temporary slice cfg stored in macCb.
727  *
728  * @details
729  *
730  *     Function : freeMacSliceCfgReq 
731  *
732  *   free the temporary slice cfg stored in macCb
733  *
734  *  @param[in]  
735  *  @return  int
736  *      -# ROK
737  **/
738 void freeMacSliceCfgReq(MacSliceCfgReq *cfgReq,Pst *pst)
739 {
740     uint8_t policyIdx = 0, memberListIdx=0;
741
742     if(cfgReq->numOfRrmPolicy)
743     {
744        if(cfgReq->listOfRrmPolicy)
745        {
746           for(policyIdx = 0; policyIdx<cfgReq->numOfRrmPolicy; policyIdx++)
747           {
748              if(cfgReq->listOfRrmPolicy[policyIdx])
749              {
750                 if(cfgReq->listOfRrmPolicy[policyIdx]->numOfRrmPolicyMem)
751                 {
752                    if(cfgReq->listOfRrmPolicy[policyIdx]->rRMPolicyMemberList)
753                    {
754                       for(memberListIdx = 0; memberListIdx<cfgReq->listOfRrmPolicy[policyIdx]->numOfRrmPolicyMem; memberListIdx++)
755                       {
756                          MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy[policyIdx]->rRMPolicyMemberList[memberListIdx], sizeof(RrmPolicyMemberList));
757                       }
758                       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy[policyIdx]->rRMPolicyMemberList,\
759                       cfgReq->listOfRrmPolicy[policyIdx]->numOfRrmPolicyMem * sizeof(RrmPolicyMemberList*));
760                    }
761                 }
762                 MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy[policyIdx], sizeof(MacSliceRrmPolicy));
763              }
764           }
765           MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy, cfgReq->numOfRrmPolicy  * sizeof(MacSliceRrmPolicy*));
766        }
767     }
768
769 }
770
771 /**
772  * @brief send slice cfg response to duapp.
773  *
774  * @details
775  *
776  *     Function : MacSendSliceConfigRsp
777  *
778  *   sends  slice cfg response to duapp
779  *
780  *  @param[in] MacSliceCfgRsp macSliceCfgRsp 
781  *  @return  int
782  *      -# ROK
783  **/
784 uint8_t MacSendSliceConfigRsp(MacSliceCfgRsp *macSliceCfgRsp)
785 {
786     Pst  rspPst;
787     
788     memset(&rspPst, 0, sizeof(Pst));
789     FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_SLICE_CFG_RSP);
790     return (*macDuSliceCfgRspOpts[rspPst.selector])(&rspPst, macSliceCfgRsp);
791
792 }
793
794 /**
795  * @brief Mac process the slice cfg rsp received from sch.
796  *
797  * @details
798  *
799  *     Function : MacProcSchSliceCfgRsp 
800  *
801  *     This function  process the slice cfg rsp received from sch
802  *
803  *  @param[in]  Pst           *pst
804  *  @param[in]  SchSliceCfgRsp *sliceCfgrsp
805  *  @return  int
806  *      -# ROK
807  **/
808
809 uint8_t MacProcSchSliceCfgRsp(Pst *pst, SchSliceCfgRsp *schSliceCfgRsp)
810 {
811    MacSliceCfgRsp *macSliceCfgRsp = NULLP;
812
813    if(schSliceCfgRsp)
814    {
815       MAC_ALLOC_SHRABL_BUF(macSliceCfgRsp, sizeof(MacSliceCfgRsp));
816       if(macSliceCfgRsp == NULLP)
817       {
818           DU_LOG("\nERROR  -->  MAC : Failed to allocate memory in MacProcSchSliceCfgRsp");
819           return RFAILED;
820       }
821       macSliceCfgRsp->snssai = schSliceCfgRsp->snssai;
822       if(schSliceCfgRsp->rsp == RSP_OK)
823          macSliceCfgRsp->rsp    = MAC_DU_APP_RSP_OK;
824       else
825       {
826          macSliceCfgRsp->rsp    = MAC_DU_APP_RSP_NOK;
827       }
828       macSliceCfgRsp->cause  = schSliceCfgRsp->cause;
829       MacSendSliceConfigRsp(macSliceCfgRsp);
830    }
831    return ROK;
832 }
833
834 /**
835  * @brief send slice cfg response to duapp.
836  *
837  * @details
838  *
839  *     Function : MacSendSliceReconfigRsp 
840  *
841  *   sends  slice cfg response to duapp
842  *
843  *  @param[in] MacSliceRecfgRsp macSliceRecfgRsp
844  *  @return  int
845  *      -# ROK
846  **/
847 uint8_t MacSendSliceReconfigRsp(MacSliceRecfgRsp *macSliceRecfgRsp)
848 {
849    Pst  rspPst;
850
851    memset(&rspPst, 0, sizeof(Pst));
852    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_SLICE_RECFG_RSP);
853    return (*macDuSliceRecfgRspOpts[rspPst.selector])(&rspPst, macSliceRecfgRsp);
854
855 }
856
857 /**
858  * @brief Mac process the slice cfg rsp received from sch.
859  *
860  * @details
861  *
862  *     Function : MacProcSchSliceRecfgRsp 
863  *
864  *     This function  process the slice cfg rsp received from sch
865  *
866  *  @param[in]  Pst           *pst
867  *  @param[in]  SchSliceCfgRsp *schSliceRecfgRsp
868  *  @return  int
869  *      -# ROK
870  **/
871 uint8_t MacProcSchSliceRecfgRsp(Pst *pst, SchSliceRecfgRsp *schSliceRecfgRsp)
872 {
873    MacSliceRecfgRsp *macSliceRecfgRsp = NULLP;
874
875    if(schSliceRecfgRsp)
876    {
877       MAC_ALLOC_SHRABL_BUF(macSliceRecfgRsp, sizeof(MacSliceRecfgRsp));
878       if(macSliceRecfgRsp == NULLP)
879       {
880           DU_LOG("\nERROR  -->  MAC : Failed to allocate memory in MacProcSchSliceRecfgRsp");
881           return RFAILED;
882       }
883
884       macSliceRecfgRsp->snssai = schSliceRecfgRsp->snssai;
885       if(schSliceRecfgRsp->rsp == RSP_OK)
886          macSliceRecfgRsp->rsp    = MAC_DU_APP_RSP_OK;
887       else
888       {
889          macSliceRecfgRsp->rsp    = MAC_DU_APP_RSP_NOK;
890       }
891       macSliceRecfgRsp->cause  = schSliceRecfgRsp->cause;
892       MacSendSliceReconfigRsp(macSliceRecfgRsp);
893    }
894    return ROK;
895 }
896
897 /**
898  * @brief Mac process the downlink pcch indication received from DUAPP
899  *
900  * @details
901  *
902  *     Function : MacProcDlPcchInd 
903  *
904  *     This function process the downlink pcch indication received from DUAPP
905  *
906  *  @param[in]  Pst           *pst
907  *  @param[in]  DlPcchInd    *pcchInd 
908  *  @return  int
909  *      -# ROK
910  **/
911 uint8_t MacProcDlPcchInd(Pst *pst, DlPcchInd *pcchInd)
912 {
913    uint8_t ret = RFAILED;
914    uint16_t cellIdx = 0;
915    Pst       schPst;
916    SchPageInd *schPageInd = NULLP;
917
918    if(pcchInd)
919    {
920       DU_LOG("\nINFO   -->  MAC : Received DL PCCH IND from DU_APP for cellId[%d]", pcchInd->cellId);
921       
922       GET_CELL_IDX(pcchInd->cellId, cellIdx);
923
924       if(macCb.macCell[cellIdx] == NULLP || macCb.macCell[cellIdx]->cellId != pcchInd->cellId)
925       {
926          DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): CellId[%d] does not exist", pcchInd->cellId);
927       }
928       else
929       {
930          if((pcchInd->pcchPdu == NULLP) || (pcchInd->pduLen <= 0))
931          {
932             DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Received Pcch pdu is null");
933          }
934          else
935          {
936             MAC_ALLOC(schPageInd, sizeof(SchPageInd));
937             if(schPageInd == NULLP)
938             {
939                DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Failed to allocate memory");
940             }
941             else
942             {
943                schPageInd->cellId = pcchInd->cellId;
944                schPageInd->pf = pcchInd->pf;
945                schPageInd->i_s = pcchInd->i_s;
946                schPageInd->pduLen = pcchInd->pduLen;
947                
948                MAC_ALLOC(schPageInd->pagePdu, pcchInd->pduLen);
949                if(schPageInd->pagePdu == NULLP)
950                {
951                   DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Failed to allocate memory");
952                   MAC_FREE(schPageInd, sizeof(SchPageInd));
953                }
954                else
955                {
956                   memcpy(schPageInd->pagePdu, pcchInd->pcchPdu, pcchInd->pduLen);
957
958                   FILL_PST_MAC_TO_SCH(schPst, EVENT_PAGING_IND_TO_SCH);
959                   ret = SchMessageRouter(&schPst, (void *)schPageInd);
960                }
961             }
962          }
963       }
964       if((pcchInd->pcchPdu) && (pcchInd->pduLen > 0))
965       {
966          MAC_FREE_SHRABL_BUF(pst->region, pst->pool, pcchInd->pcchPdu, pcchInd->pduLen);
967       }
968       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, pcchInd, sizeof(DlPcchInd));
969    }
970    else
971    {
972       DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Received Null pointer");
973    }
974    return ret;
975 }
976
977 /**
978  * @brief Mac process the downlink Broadcast Req received from DUAPP
979  *
980  * @details
981  *
982  *     Function : MacProcDlBroadcastReq 
983  *
984  *     This function process the downlink Broadcast Req received from DUAPP
985  *
986  *  @param[in]  Pst           *pst
987  *  @param[in]  DlBroadcastReq    *dlBroadcastReq 
988  *  @return  int
989  *      -# ROK
990  **/
991 uint8_t MacProcDlBroadcastReq(Pst *pst, MacDlBroadcastReq *dlBroadcastReq)
992 {
993    uint8_t ret = ROK, idx=0;
994    uint16_t cellIdx = 0;
995
996    if(dlBroadcastReq)
997    {
998       DU_LOG("\nINFO   -->  MAC : Received DL braodcast req from DU_APP for cellId[%d]", dlBroadcastReq->cellId);
999       
1000       GET_CELL_IDX(dlBroadcastReq->cellId, cellIdx);
1001
1002       if(macCb.macCell[cellIdx] == NULLP || macCb.macCell[cellIdx]->cellId != dlBroadcastReq->cellId)
1003       {
1004          ret = RFAILED;
1005          DU_LOG("\nERROR  -->  MAC : MacProcDlBroadcastReq(): CellId[%d] does not exist", dlBroadcastReq->cellId);
1006       }
1007       else
1008       {
1009          /*TODO - Complete the processing of DL Broadcast Request*/
1010       }
1011       for(idx = 0; idx<dlBroadcastReq->numSiBlock; idx++)
1012       {
1013          MAC_FREE_SHRABL_BUF(pst->region, pst->pool, dlBroadcastReq->siSchedulingInfo[idx]->siAreaID, sizeof(uint8_t));
1014          MAC_FREE_SHRABL_BUF(pst->region, pst->pool, dlBroadcastReq->siSchedulingInfo[idx], sizeof(SiSchedulingInfo));
1015       }
1016       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, dlBroadcastReq, sizeof(MacDlBroadcastReq));
1017    }
1018    else
1019    {
1020       ret = RFAILED;
1021       DU_LOG("\nERROR  -->  MAC : MacProcDlBroadcastReq(): Received Null pointer");
1022    }
1023    return ret;
1024 }
1025
1026 /**
1027  * @brief Fill and send statistics response to DU APP
1028  *
1029  * @details
1030  *
1031  *     Function : MacSendStatsRspToDuApp
1032  *
1033  *     Fill and send statistics response to DU APP
1034  *
1035  *  @param[in]  Response
1036  *  @param[in]  Cause of response
1037  *  @return  int
1038  *      -# ROK
1039  **/
1040 uint8_t MacSendStatsRspToDuApp(MacStatsRsp *statsRsp)
1041 {
1042    uint8_t ret = ROK;
1043    Pst  pst;
1044    MacStatsRsp *macStatsRsp = NULLP;
1045
1046     DU_LOG("\nINFO  -->  MAC : MacSendStatsRspToDuApp: Sending Statistics Response to DU APP");
1047
1048    /* Workaround : To skip corrupted memory, allocating a pointer that will
1049     * remain unused */
1050    uint8_t *dummyPtr = NULLP;
1051    MAC_ALLOC_SHRABL_BUF(dummyPtr, sizeof(uint8_t));
1052
1053    MAC_ALLOC_SHRABL_BUF(macStatsRsp, sizeof(MacStatsRsp));
1054    if(macStatsRsp == NULLP)
1055    {
1056       DU_LOG("\nERROR  -->  MAC : Failed to allocate memory in MacProcSchStatsRsp");
1057       ret = RFAILED;
1058    }
1059    else
1060    {
1061       memcpy(macStatsRsp, statsRsp, sizeof(MacStatsRsp));
1062       memset(statsRsp, 0, sizeof(MacStatsRsp));
1063
1064       memset(&pst, 0, sizeof(Pst));
1065       FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_STATISTICS_RSP);
1066       if(((*macDuStatsRspOpts[pst.selector])(&pst, macStatsRsp))!= ROK)
1067       {
1068          DU_LOG("\nERROR  -->  MAC : Failed to send statistics response to DU APP");
1069          MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, macStatsRsp, sizeof(MacStatsRsp));
1070          ret = RFAILED;
1071       }
1072    }
1073
1074    /* Workaround : Freeing the dummy pointer */
1075    MAC_FREE_SHRABL_BUF(MAC_MEM_REGION, MAC_POOL, dummyPtr, sizeof(uint8_t));
1076    return ret;
1077 }
1078
1079 /*******************************************************************
1080  *
1081  * @brief Rejects all statistics group requested by DU APP
1082  *
1083  * @details
1084  *
1085  *    Function : MacRejectAllStats
1086  *
1087  *    Functionality: Add all statistics group received in statistics
1088  *       request from DU APP, to Reject-Stats-Group-List in statistics
1089  *       response to DU APP
1090  *
1091  * @params[in]  Statistics request from DU APP
1092  *              Cause of rejection
1093  * @return ROK     - success
1094  *         RFAILED - failure
1095  *
1096  * ****************************************************************/
1097 uint8_t MacRejectAllStats(MacStatsReq *macStatsReq, CauseOfResult cause)
1098 {
1099    uint8_t grpIdx = 0;
1100    MacStatsRsp macStatsRsp;
1101
1102    memset(&macStatsRsp, 0, sizeof(MacStatsRsp));
1103
1104    /* Copying all stats group from stats request to stats response */
1105    macStatsRsp.subscriptionId = macStatsReq->subscriptionId;
1106    for(grpIdx = 0; grpIdx < macStatsReq->numStatsGroup; grpIdx++)
1107    {
1108       macStatsRsp.statsGrpRejectedList[grpIdx].groupId = macStatsReq->statsGrpList[grpIdx].groupId;
1109       macStatsRsp.statsGrpRejectedList[grpIdx].cause = cause;
1110    }
1111    macStatsRsp.numGrpRejected = macStatsReq->numStatsGroup;
1112
1113    return MacSendStatsRspToDuApp(&macStatsRsp);
1114 }
1115
1116 /**
1117  * @brief Mac process the statistics Req received from DUAPP
1118  *
1119  * @details
1120  *
1121  *     Function : MacProcStatsReq
1122  *
1123  *     This function process the statistics request from duapp:
1124  *     [Step 1] Basic validation. If fails, all stats group in stats request are
1125  *     rejected.
1126  *     [Step 2] If basic validations passed, traverse all stats group and
1127  *     validate each measurement types in each group.
1128  *     [Step 3] If any measurement type validation fails in a group, that group 
1129  *     is not configured and it is added to stats-group-rejected-list in
1130  *     mac-stats-response message.
1131  *     [Step 4] Even if one group passes all validation, it is sent to SCH in
1132  *     statistics request. The mac-stats-response message is added to
1133  *     pending-response list. This will be sent to DU APP after stats response
1134  *     is received from SCH.
1135  *     [Step 5] If none of the groups passes all validation, mac-stats-response
1136  *     is sent to du app with all group as part of stats-group-rejected-list.
1137  *
1138  *  @param[in]  Pst      *pst
1139  *  @param[in]  StatsReq *statsReq
1140  *  @return  int
1141  *      -# ROK
1142  **/
1143 uint8_t MacProcStatsReq(Pst *pst, MacStatsReq *macStatsReq)
1144 {
1145    uint8_t       macStatsGrpIdx = 0, macStatsIdx = 0, schStatsGrpIdx = 0, schStatsIdx = 0;
1146    uint8_t       ret = RFAILED;
1147    bool          measTypeInvalid = false;
1148    Pst           schPst;
1149    MacStatsGrpInfo *macStatsGrp = NULLP;
1150    SchStatsReq     *schStatsReq = NULLP;
1151    MacStatsRsp     *macStatsRsp = NULLP;
1152
1153    DU_LOG("\nINFO   -->  MAC : Received Statistics Request from DU_APP");
1154
1155    if(macStatsReq == NULLP)
1156    {
1157       DU_LOG("\nERROR  -->  MAC : MacProcStatsReq(): Received Null pointer");
1158       return RFAILED;
1159    }
1160    
1161    /* [Step 1] Basic validation. If fails, statistics response is sent to DU APP
1162     * that rejectes all stats */
1163
1164    /* If number of statistics request for which response is still pending
1165     * towards DU APP has reached its maximum limit */
1166    if(macCb.statistics.numPendingStatsRsp >= MAX_PENDING_STATS_RSP)
1167    {
1168       DU_LOG("\nERROR  -->  MAC : MacProcStatsReq: Maximum number of statistics response is pending. \
1169          Cannot process new request."); 
1170       MacRejectAllStats(macStatsReq, RESOURCE_UNAVAILABLE);
1171       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq));
1172       return RFAILED;
1173    }
1174
1175    /* If memory resources are unavailable */
1176    MAC_ALLOC(schStatsReq, sizeof(SchStatsReq));
1177    if(schStatsReq == NULLP)
1178    {
1179       DU_LOG("\nERROR  -->  MAC : MacProcStatsReq: Failed to allocate memory");
1180       MacRejectAllStats(macStatsReq, RESOURCE_UNAVAILABLE);
1181       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq));
1182       return RFAILED;
1183    }
1184
1185    /* Add stats response to pending response list */ 
1186    macStatsRsp = &macCb.statistics.pendingStatsRsp[macCb.statistics.numPendingStatsRsp];
1187    memset(macStatsRsp, 0, sizeof(MacStatsRsp));
1188
1189    /* [Step 2] Traverse all stats group and validate each measurement types in each group */
1190    schStatsReq->subscriptionId = macStatsReq->subscriptionId;
1191    schStatsReq->numStatsGroup = 0;
1192    for(macStatsGrpIdx = 0; macStatsGrpIdx < macStatsReq->numStatsGroup; macStatsGrpIdx++)
1193    {
1194       measTypeInvalid = false;
1195       schStatsIdx = 0;
1196       macStatsGrp = &macStatsReq->statsGrpList[macStatsGrpIdx];
1197
1198       for(macStatsIdx=0; macStatsIdx < macStatsGrp->numStats; macStatsIdx++)
1199       {
1200          /* Validate each measurement type */
1201          switch(macStatsGrp->statsList[macStatsIdx])
1202          {
1203             case MAC_DL_TOTAL_PRB_USAGE:
1204                {
1205                   schStatsReq->statsGrpList[schStatsGrpIdx].statsList[schStatsIdx] = SCH_DL_TOTAL_PRB_USAGE;
1206                   break;
1207                }
1208             case MAC_UL_TOTAL_PRB_USAGE:
1209                {
1210                   schStatsReq->statsGrpList[schStatsGrpIdx].statsList[schStatsIdx] = SCH_UL_TOTAL_PRB_USAGE;
1211                   break;
1212                }
1213             default:
1214                {
1215                   DU_LOG("\nERROR  -->  MAC : MacProcStatsReq: Invalid measurement type [%d]", \
1216                      macStatsGrp->statsList[macStatsIdx]);
1217                   measTypeInvalid = true;
1218                }
1219          }
1220
1221          /* Even if one measurement type is invalid, this group is rejected */
1222          if(measTypeInvalid)
1223          {
1224             memset(&schStatsReq->statsGrpList[schStatsGrpIdx], 0, sizeof(SchStatsGrpInfo));
1225             break;
1226          }
1227          
1228          schStatsIdx++;
1229       }
1230
1231       /* If all measurement type is valid, add group info to send to SCH */
1232       if(!measTypeInvalid)
1233       {
1234          schStatsReq->statsGrpList[schStatsGrpIdx].groupId = macStatsGrp->groupId;
1235          schStatsReq->statsGrpList[schStatsGrpIdx].periodicity = macStatsGrp->periodicity;
1236          schStatsReq->statsGrpList[schStatsGrpIdx].numStats = schStatsIdx;
1237          schStatsGrpIdx++;
1238       }
1239       else
1240       {
1241          /* [Step 3] If any measurement type validation fails in a group, that group 
1242           * is not configured and it is added to stats-group-rejected-list in
1243           * mac-stats-response message */
1244          macStatsRsp->statsGrpRejectedList[macStatsRsp->numGrpRejected].groupId = macStatsGrp->groupId;
1245          macStatsRsp->statsGrpRejectedList[macStatsRsp->numGrpRejected].cause = PARAM_INVALID;
1246          macStatsRsp->numGrpRejected++;
1247       }
1248    }
1249    schStatsReq->numStatsGroup = schStatsGrpIdx;
1250
1251    macStatsRsp->subscriptionId = macStatsReq->subscriptionId;
1252
1253    if(schStatsReq->numStatsGroup)
1254    {
1255       /* [Step 4] Even if one group passes all validation, it is sent to SCH in
1256        * statistics request. The mac-stats-response message is added to
1257        * pending-response list. */     
1258       macCb.statistics.numPendingStatsRsp++;
1259
1260       FILL_PST_MAC_TO_SCH(schPst, EVENT_STATISTICS_REQ_TO_SCH);
1261       ret = SchMessageRouter(&schPst, (void *)schStatsReq);
1262    }
1263    else
1264    {
1265       /* [Step 5] If none of the groups passes all validation, mac-stats-response
1266        * is sent to du app with all group as part of stats-group-rejected-list. */
1267       DU_LOG("\nERROR  -->  MAC : MacProcStatsReq: All statistics group found invalid");
1268       MAC_FREE(schStatsReq, sizeof(SchStatsReq));
1269       ret = MacSendStatsRspToDuApp(macStatsRsp);
1270    }
1271
1272    MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macStatsReq, sizeof(MacStatsReq));
1273    return ret;
1274 }
1275
1276 /**
1277  * @brief Mac process the statistics rsp received from sch.
1278  *
1279  * @details
1280  *
1281  *     Function : MacProcSchStatsRsp
1282  *
1283  *     This function  process the statistics response received from sch
1284  *
1285  *  @param[in]  Pst           *pst
1286  *  @param[in]  SchStatsRsp *schStatsRsp
1287  *  @return  int
1288  *      -# ROK
1289  **/
1290 uint8_t MacProcSchStatsRsp(Pst *pst, SchStatsRsp *schStatsRsp)
1291 {
1292    uint8_t idx = 0, accptdIdx = 0, rjctdIdx = 0;
1293    uint8_t ret = RFAILED;
1294    MacStatsRsp *macStatsRsp = NULLP;
1295
1296    if(schStatsRsp)
1297    {
1298       /* Fetch pointer to statistics response from pending list saved at MAC 
1299        * during processing statistics request from DU APP */ 
1300       for(idx = 0; idx < macCb.statistics.numPendingStatsRsp; idx++)
1301       {
1302          if(macCb.statistics.pendingStatsRsp[idx].subscriptionId == schStatsRsp->subscriptionId)
1303          {
1304             macStatsRsp = &macCb.statistics.pendingStatsRsp[idx];
1305             break;
1306          }
1307       }
1308
1309       if(macStatsRsp == NULLP)
1310       {
1311          MAC_FREE(schStatsRsp, sizeof(SchStatsRsp));
1312          return RFAILED;
1313       }
1314       
1315       /* Copy Stats-group-accpeted list received from SCH */
1316       for(accptdIdx = 0; accptdIdx<schStatsRsp->numGrpAccepted && macStatsRsp->numGrpAccepted<MAX_NUM_STATS_GRP; accptdIdx++)
1317       {
1318          macStatsRsp->statsGrpAcceptedList[macStatsRsp->numGrpAccepted++] = schStatsRsp->statsGrpAcceptedList[accptdIdx];
1319       }
1320
1321       /* List together all stats group rejected by MAC and by SCH */
1322       for(rjctdIdx = 0; rjctdIdx < schStatsRsp->numGrpRejected && macStatsRsp->numGrpRejected<MAX_NUM_STATS_GRP; rjctdIdx++)
1323       {
1324          macStatsRsp->statsGrpRejectedList[macStatsRsp->numGrpRejected].groupId = \
1325             schStatsRsp->statsGrpRejectedList[rjctdIdx].groupId;
1326          macStatsRsp->statsGrpRejectedList[macStatsRsp->numGrpRejected].cause = \
1327             schStatsRsp->statsGrpRejectedList[rjctdIdx].cause;
1328          macStatsRsp->numGrpRejected++;
1329       }
1330       
1331       /* Send statistics response to DU APP */
1332       ret = MacSendStatsRspToDuApp(macStatsRsp);
1333    }
1334    MAC_FREE(schStatsRsp, sizeof(SchStatsRsp));
1335    return ret;
1336 }
1337
1338 /**********************************************************************
1339   End of file
1340  **********************************************************************/