Merge "[EPIC-ID: ODUHIGH-488][TASK-ID: ODUHIGH-494]SCH framework update to support...
[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 /**
67  * @brief Layer Manager  Configuration request handler for Scheduler
68  *
69  * @details
70  *
71  *     Function : MacSchGenCfgReq
72  *
73  *     This function receives general configurations for Scheduler
74  *     from DU APP and forwards to Scheduler.
75  *
76  *  @param[in]  Pst *pst, the post structure
77  *  @param[in]  RgMngmt *cfg, the configuration parameter's structure
78  *  @return 
79  *      -# ROK
80  **/
81 uint8_t MacSchGenCfgReq(Pst *pst, RgMngmt *cfg)
82 {
83    Pst schPst;
84
85    DU_LOG("\nINFO  -->  MAC : Received Scheduler gen config at MAC");
86    memset(&schPst, 0, sizeof(Pst));
87    FILL_PST_MAC_TO_SCH(schPst, EVENT_SCH_GEN_CFG);
88    
89    return(SchMessageRouter(&schPst, (void *)cfg));
90 }
91
92 /**
93  * @brief Layer Manager Configuration response from Scheduler
94  *
95  * @details
96  *
97  *     Function : SchSendCfgCfm
98  *
99  *     This function sends general configurations response from
100  *     Scheduler to DU APP.
101  *
102  *  @param[in]  Pst *pst, the post structure
103  *  @param[in]  RgMngmt *cfm, the configuration confirm structure
104  *  @return 
105  *      -# ROK
106  **/
107 uint8_t SchSendCfgCfm(Pst *pst, RgMngmt  *cfm)
108 {
109    DU_LOG("\nDEBUG  -->  MAC : Sending Scheduler config confirm to DU APP");
110    pst->dstEnt = ENTDUAPP;
111    pst->dstInst = 0;
112    pst->srcInst = 0;
113    pst->selector = ODU_SELECTOR_LC;
114    RgMiLrgSchCfgCfm(pst, cfm);
115
116    return ROK;
117 }
118
119 /**
120  * @brief Layer Manager Configuration request handler.
121  *
122  * @details
123  *
124  *     Function : MacProcCellCfgReq
125  *
126  *     This function handles the gNB and cell configuration
127  *     request received from DU APP.
128  *     This API unapcks and forwards the config towards SCH
129  *
130  *  @param[in]  Pst           *pst
131  *  @param[in]  MacCellCfg    *macCellCfg
132  *  @return  
133  *      -# ROK
134  **/
135 uint8_t MacProcCellCfgReq(Pst *pst, MacCellCfg *macCellCfg)
136 {
137    Pst cfmPst;
138    uint16_t cellIdx;
139    uint8_t ret = ROK, sliceIdx = 0;
140    MacCellCb     *macCellCb;
141
142    memset((uint8_t *)&cfmPst, 0, sizeof(Pst));
143
144    MAC_ALLOC(macCellCb, sizeof(MacCellCb));
145    if(macCellCb == NULLP)
146    {
147       DU_LOG("\nERROR  -->  MAC : macCellCb is NULL at handling of macCellCfg\n");
148       return RFAILED;
149    }
150    memset(macCellCb, 0, sizeof(MacCellCb));
151
152    GET_CELL_IDX(macCellCfg->cellId, cellIdx);
153    macCb.macCell[cellIdx] = macCellCb;
154    macCb.macCell[cellIdx]->cellId = macCellCfg->cellId;
155    macCb.macCell[cellIdx]->numOfSlots = 10 * (1 << macCellCfg->numerology);
156    memcpy(&macCb.macCell[cellIdx]->macCellCfg, macCellCfg, sizeof(MacCellCfg));
157
158    MAC_ALLOC(macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1Pdu, \
159          macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1PduLen);
160    if(macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1Pdu == NULLP)
161    {
162       DU_LOG("\nERROR  -->  MAC : macCellCb is NULL at handling of sib1Pdu of macCellCfg\n");
163       return RFAILED;
164    }
165    memcpy(macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1Pdu, macCellCfg->sib1Cfg.sib1Pdu, \
166          macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1PduLen);
167    
168    macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.numSupportedSlice = macCellCfg->plmnInfoList.numSupportedSlice;
169    MAC_ALLOC(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai, macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.numSupportedSlice\
170          * sizeof(Snssai*));
171    if(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai == NULLP)
172    {
173       DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacProcCellCfgReq");
174       return RFAILED;
175    }
176
177    if(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai)
178    {
179       for(sliceIdx=0; sliceIdx<macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.numSupportedSlice; sliceIdx++)
180       {
181          if(macCellCfg->plmnInfoList.snssai[sliceIdx])
182          {
183             MAC_ALLOC(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai[sliceIdx], sizeof(Snssai));
184             if(!macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai[sliceIdx])
185             {
186                DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacProcCellCfgReq");
187                return RFAILED;
188             }
189             memcpy(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai[sliceIdx], macCellCfg->plmnInfoList.snssai[sliceIdx],\
190             sizeof(Snssai));
191          }
192       }
193    }
194
195    /* Send cell cfg to scheduler */
196    ret = MacSchCellCfgReq(pst, macCellCfg);
197    if(ret != ROK)
198    {
199       MacCellCfgCfm macCellCfgCfm;
200       macCellCfgCfm.rsp = RSP_NOK;
201       macCellCfgCfm.cellId = macCellCfg->cellId;
202       /* Fill Pst */
203       FILL_PST_MAC_TO_DUAPP(cfmPst, EVENT_MAC_CELL_CONFIG_CFM);
204       cfmPst.selector  = ODU_SELECTOR_LC;
205
206       ret = (*packMacCellCfmOpts[cfmPst.selector])(&cfmPst,&macCellCfgCfm);
207    }
208    else
209    {
210       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, macCellCfg ,sizeof(MacCellCfg));
211    }
212    return ret;
213 } /* end of MacProcCellCfgReq */
214
215 /**
216  * @brief Layer Manager Configuration request handler.
217  *
218  * @details
219  *
220  *     Function : MacSchCellCfgReq
221  *
222  *     This function sends cell configuration to SCH
223  *
224  *  @param[in]  Pst           *pst
225  *  @param[in]  MacCellCfg    *macCellCfg
226  *  @return  
227  *      -# ROK
228  **/
229 uint8_t MacSchCellCfgReq(Pst *pst, MacCellCfg *macCellCfg)
230 {
231    SchCellCfg schCellCfg;
232    Pst        cfgPst;
233    uint8_t    ssbMaskIdx = 0, rsrcListIdx = 0, sliceIdx=0;
234
235    memset(&cfgPst, 0, sizeof(Pst));
236    memset(&schCellCfg, 0, sizeof(SchCellCfg));
237    schCellCfg.cellId = macCellCfg->cellId;
238    schCellCfg.phyCellId = macCellCfg->phyCellId;
239    schCellCfg.numerology = macCellCfg->numerology;
240    schCellCfg.dupMode = macCellCfg->dupType;
241    schCellCfg.bandwidth = macCellCfg->dlCarrCfg.bw;
242    schCellCfg.dlFreq = macCellCfg->dlCarrCfg.freq;
243    schCellCfg.ulFreq = macCellCfg->ulCarrCfg.freq;
244
245    /* fill ssb scheduler parameters */
246    schCellCfg.ssbSchCfg.ssbPbchPwr = macCellCfg->ssbCfg.ssbPbchPwr;
247    schCellCfg.ssbSchCfg.scsCommon = macCellCfg->ssbCfg.scsCmn;
248    schCellCfg.ssbSchCfg.ssbOffsetPointA = macCellCfg->ssbCfg.ssbOffsetPointA;
249    schCellCfg.ssbSchCfg.ssbPeriod = ssbPeriodicity[macCellCfg->ssbCfg.ssbPeriod];
250    schCellCfg.ssbSchCfg.ssbSubcOffset = macCellCfg->ssbCfg.ssbScOffset;
251    for(ssbMaskIdx=0; ssbMaskIdx<SSB_MASK_SIZE; ssbMaskIdx++)
252    {
253       schCellCfg.ssbSchCfg.nSSBMask[ssbMaskIdx] = macCellCfg->ssbCfg.ssbMask[ssbMaskIdx];
254    }
255    schCellCfg.ssbSchCfg.totNumSsb = countSetBits(schCellCfg.ssbSchCfg.nSSBMask[0]);
256
257    /* fill SIB1 scheduler parameters */
258    schCellCfg.sib1SchCfg.sib1PduLen = macCellCfg->sib1Cfg.sib1PduLen;
259    schCellCfg.sib1SchCfg.sib1RepetitionPeriod = macCellCfg->sib1Cfg.sib1RepetitionPeriod;
260    schCellCfg.sib1SchCfg.coresetZeroIndex = macCellCfg->sib1Cfg.coresetZeroIndex;
261    schCellCfg.sib1SchCfg.searchSpaceZeroIndex = macCellCfg->sib1Cfg.searchSpaceZeroIndex;
262    schCellCfg.sib1SchCfg.sib1Mcs = macCellCfg->sib1Cfg.sib1Mcs;
263    schCellCfg.sib1SchCfg.pageCfg.numPO  =  macCellCfg->sib1Cfg.pagingCfg.numPO;
264    schCellCfg.sib1SchCfg.pageCfg.poPresent = macCellCfg->sib1Cfg.pagingCfg.poPresent;
265
266    if(schCellCfg.sib1SchCfg.pageCfg.poPresent)
267    {
268       memcpy(schCellCfg.sib1SchCfg.pageCfg.pagingOcc, macCellCfg->sib1Cfg.pagingCfg.pagingOcc, MAX_PO_PER_PF);
269    }
270
271    /* fill RACH config params */
272    schCellCfg.schRachCfg.prachCfgIdx = macCellCfg->prachCfg.prachCfgIdx;
273    schCellCfg.schRachCfg.prachSubcSpacing = \
274                                             macCellCfg->prachCfg.prachSubcSpacing;
275    schCellCfg.schRachCfg.msg1FreqStart = macCellCfg->prachCfg.msg1FreqStart;
276    schCellCfg.schRachCfg.msg1Fdm       = macCellCfg->prachCfg.msg1Fdm;
277    schCellCfg.schRachCfg.rootSeqLen    = macCellCfg->prachCfg.rootSeqLen;
278    schCellCfg.schRachCfg.rootSeqIdx    = macCellCfg->prachCfg.fdm[0].rootSeqIdx;
279    schCellCfg.schRachCfg.numRootSeq    = macCellCfg->prachCfg.fdm[0].numRootSeq;
280    schCellCfg.schRachCfg.k1            = macCellCfg->prachCfg.fdm[0].k1;
281    schCellCfg.schRachCfg.totalNumRaPreamble = macCellCfg->prachCfg.totalNumRaPreamble;
282    schCellCfg.schRachCfg.ssbPerRach    = macCellCfg->prachCfg.ssbPerRach;
283    schCellCfg.schRachCfg.numCbPreamblePerSsb = macCellCfg->prachCfg.numCbPreamblePerSsb;
284    schCellCfg.schRachCfg.prachMultCarrBand = macCellCfg->prachCfg.prachMultCarrBand;
285    schCellCfg.schRachCfg.raContResTmr  = macCellCfg->prachCfg.raContResTmr;
286    schCellCfg.schRachCfg.rsrpThreshSsb = macCellCfg->prachCfg.rsrpThreshSsb;
287    schCellCfg.schRachCfg.raRspWindow   = macCellCfg->prachCfg.raRspWindow;
288
289    /* fill initial DL BWP */
290    schCellCfg.schInitialDlBwp.bwp.freqAlloc.startPrb = macCellCfg->initialDlBwp.bwp.firstPrb;
291    schCellCfg.schInitialDlBwp.bwp.freqAlloc.numPrb = macCellCfg->initialDlBwp.bwp.numPrb;
292    schCellCfg.schInitialDlBwp.bwp.scs = macCellCfg->initialDlBwp.bwp.scs;
293    schCellCfg.schInitialDlBwp.bwp.cyclicPrefix = macCellCfg->initialDlBwp.bwp.cyclicPrefix;
294    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.searchSpaceId =
295       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.searchSpaceId;
296    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.coresetId =
297       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.coresetId;
298    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.monitoringSlot =
299       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.monitoringSlot;
300    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.duration =
301       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.duration;
302    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.monitoringSymbol =
303       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.monitoringSymbol;
304    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel1 =
305       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel1;
306    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel2 =
307       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel2;
308    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel4 =
309       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel4;
310    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel8 =
311       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel8;
312    schCellCfg.schInitialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel16 =
313       macCellCfg->initialDlBwp.pdcchCommon.commonSearchSpace.candidate.aggLevel16;
314    schCellCfg.schInitialDlBwp.pdschCommon.numTimeDomAlloc = macCellCfg->initialDlBwp.pdschCommon.numTimeDomAlloc;
315    for(rsrcListIdx = 0; rsrcListIdx<macCellCfg->initialDlBwp.pdschCommon.numTimeDomAlloc; rsrcListIdx++)
316    {
317       schCellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].k0 = 
318          macCellCfg->initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].k0;
319       schCellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType =
320          macCellCfg->initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType;
321       schCellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol =
322          macCellCfg->initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol;
323       schCellCfg.schInitialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].lengthSymbol =
324          macCellCfg->initialDlBwp.pdschCommon.timeDomRsrcAllocList[rsrcListIdx].lengthSymbol;
325    }
326
327    /* fill initial UL BWP */
328    schCellCfg.schInitialUlBwp.bwp.freqAlloc.startPrb = macCellCfg->initialUlBwp.bwp.firstPrb;
329    schCellCfg.schInitialUlBwp.bwp.freqAlloc.numPrb = macCellCfg->initialUlBwp.bwp.numPrb;
330    schCellCfg.schInitialUlBwp.bwp.scs = macCellCfg->initialUlBwp.bwp.scs;
331    schCellCfg.schInitialUlBwp.bwp.cyclicPrefix = macCellCfg->initialUlBwp.bwp.cyclicPrefix;
332    schCellCfg.schInitialUlBwp.puschCommon.numTimeDomRsrcAlloc = \
333       macCellCfg->initialUlBwp.puschCommon.numTimeDomRsrcAlloc;
334    for(rsrcListIdx = 0; rsrcListIdx < macCellCfg->initialUlBwp.puschCommon.numTimeDomRsrcAlloc; rsrcListIdx++)
335    {
336       schCellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].k2 = 
337          macCellCfg->initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].k2;
338       schCellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType =
339          macCellCfg->initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].mappingType;
340       schCellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol =
341          macCellCfg->initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].startSymbol;
342       schCellCfg.schInitialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].symbolLength =
343          macCellCfg->initialUlBwp.puschCommon.timeDomRsrcAllocList[rsrcListIdx].symbolLength;
344    }
345
346    if(macCellCfg->plmnInfoList.snssai) 
347    {
348       schCellCfg.plmnInfoList.numSliceSupport = macCellCfg->plmnInfoList.numSupportedSlice;
349       MAC_ALLOC(schCellCfg.plmnInfoList.snssai, schCellCfg.plmnInfoList.numSliceSupport * sizeof(Snssai*));
350       if(!schCellCfg.plmnInfoList.snssai)
351       {
352          DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacSchCellCfgReq");
353          return RFAILED;
354       }
355       for(sliceIdx=0; sliceIdx<schCellCfg.plmnInfoList.numSliceSupport; sliceIdx++)
356       {
357          if(macCellCfg->plmnInfoList.snssai[sliceIdx])
358          {
359             MAC_ALLOC(schCellCfg.plmnInfoList.snssai[sliceIdx], sizeof(Snssai));
360             if(!schCellCfg.plmnInfoList.snssai[sliceIdx])
361             {
362                DU_LOG("\nERROR  --> MAC: Memory allocation failed at MacSchCellCfgReq");
363                return RFAILED;
364             }
365             memcpy(schCellCfg.plmnInfoList.snssai[sliceIdx], macCellCfg->plmnInfoList.snssai[sliceIdx],  sizeof(Snssai));
366          }
367       }
368    }
369
370 #ifdef NR_TDD
371    memcpy(&schCellCfg.tddCfg, &macCellCfg->tddCfg, sizeof(TDDCfg));
372 #endif
373
374    FILL_PST_MAC_TO_SCH(cfgPst, EVENT_SCH_CELL_CFG);
375
376    return(SchMessageRouter(&cfgPst, (void *)&schCellCfg));
377 } /* end of MacSchCellCfgReq */
378
379
380 /*******************************************************************
381  *
382  * @brief Sends Cell config confirm to DU APP
383  *
384  * @details
385  *
386  *    Function : MacSendCellCfgCfm
387  *
388  *    Functionality:
389  *      Sends Cell config confirm to DU APP
390  *
391  * @params[in] Response status
392  * @return void
393  *
394  * ****************************************************************/
395 void MacSendCellCfgCfm(uint16_t cellId, uint8_t response)
396 {
397    Pst pst;
398    uint16_t   cellIdx;
399    MacCellCfgCfm macCellCfgCfm;
400
401    memset(&pst, 0, sizeof(Pst));
402
403    GET_CELL_IDX(cellId, cellIdx);
404    macCellCfgCfm.cellId = macCb.macCell[cellIdx]->macCellCfg.cellId;
405    macCellCfgCfm.rsp = response;
406
407    /* Fill Pst */
408    FILL_PST_MAC_TO_DUAPP(pst, EVENT_MAC_CELL_CONFIG_CFM);
409    pst.selector  = ODU_SELECTOR_LC;
410
411    (*packMacCellCfmOpts[pst.selector])(&pst,&macCellCfgCfm);
412 }
413
414
415 /**
416  * @brief Layer Manager Configuration response handler.
417  *
418  * @details
419  *
420  *     Function : MacProcSchCellCfgCfm
421  *
422  *     This function processes cell configuration to SCH
423  *
424  *  @param[in]  Pst           *pst
425  *  @param[in]  SchCellCfgCfm *schCellCfgCfm
426  *  @return  int
427  *      -# ROK
428  **/
429 uint8_t MacProcSchCellCfgCfm(Pst *pst, SchCellCfgCfm *schCellCfgCfm)
430 {
431    uint16_t *cellId = NULLP;
432
433 #ifdef CALL_FLOW_DEBUG_LOG
434    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_SCH_CELL_CFG_CFM\n");
435 #endif
436
437    if(schCellCfgCfm->rsp == RSP_OK)
438    {
439       cellId = &schCellCfgCfm->cellId;
440 #ifdef INTEL_TIMER_MODE
441       sendToLowerMac(UL_IQ_SAMPLE, 0, (void *)cellId);
442 #else
443       sendToLowerMac(CONFIG_REQUEST, 0, (void *)cellId);
444 #endif
445    }
446    else
447    {
448       MacSendCellCfgCfm(schCellCfgCfm->cellId, RSP_NOK);
449    }
450    return ROK;
451 }
452
453 /*******************************************************************
454  *
455  * @brief MAC handler for config response from PHY
456  *
457  * @details
458  *
459  *    Function : fapiMacConfigRsp
460  *
461  *    Functionality:
462  *     Processes config response from PHY and sends cell config
463  *     confirm to DU APP
464  *
465  * @params[in]
466  * @return void
467  *
468  * ****************************************************************/
469 void fapiMacConfigRsp(uint16_t cellId)
470 {
471    /* TODO : Processing of config response from PHY */
472
473    /* Send cell config cfm to DU APP */
474    MacSendCellCfgCfm(cellId, RSP_OK);
475 }
476
477 /*******************************************************************
478  *
479  * @brief Fill and Send Cell Delete response from MAC to DU APP
480  *
481  * @details
482  *
483  *    Function : MacSendCellDeleteRsp
484  *
485  *    Functionality: Fill and Send Cell Delete response from MAC to DUAPP
486  *
487  * @params[in] MAC Cell delete result
488  *             SCH Cell delete response
489  * @return ROK     - success
490  *         RFAILED - failure
491  *
492  * ****************************************************************/
493 uint8_t MacSendCellDeleteRsp(CellDeleteStatus result, uint8_t cellId)
494 {
495    MacCellDeleteRsp *deleteRsp=NULLP;
496    Pst            rspPst;
497
498    MAC_ALLOC_SHRABL_BUF(deleteRsp, sizeof(MacCellDeleteRsp));
499    if(!deleteRsp)
500    {
501       DU_LOG("\nERROR  -->  MAC : MacSendCellDeleteRsp(): Memory allocation for Cell delete response failed");
502       return RFAILED;
503    }
504
505    /* Filling CELL delete response */
506    
507    memset(deleteRsp, 0, sizeof(MacCellDeleteRsp));
508    deleteRsp->cellId = cellId;
509    deleteRsp->result = result;
510
511    /* Fill Post structure and send CELL delete response*/
512    memset(&rspPst, 0, sizeof(Pst));
513    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_CELL_DELETE_RSP);
514    return (*macDuCellDeleteRspOpts[rspPst.selector])(&rspPst, deleteRsp);
515 }
516
517 /*******************************************************************
518  *
519  * @brief  Processes CELL delete response from scheduler
520  *
521  * @details
522  *
523  *    Function : MacProcSchCellDeleteRsp
524  *
525  *    Functionality:
526  *      Processes CELL delete from scheduler
527  *
528  * @params[in] Pst : Post structure
529  *             schCellDelRsp : Scheduler CELL delete respons
530  * @return ROK     - success
531  *         RFAILED - failure
532  *
533  * * ****************************************************************/
534 uint8_t MacProcSchCellDeleteRsp(Pst *pst, SchCellDeleteRsp *schCellDelRsp)
535 {
536    uint8_t  ret = ROK, sliceIdx = 0;
537    uint16_t cellIdx=0;
538    CellDeleteStatus status;
539    
540 #ifdef CALL_FLOW_DEBUG_LOG
541    DU_LOG("\nCall Flow: ENTSCH -> ENTMAC : EVENT_CELL_DELETE_RSP_TO_MAC\n");
542 #endif  
543
544    if(schCellDelRsp)
545    {
546       if(schCellDelRsp->rsp == RSP_OK)
547       {
548          DU_LOG("\nINFO   -->  MAC : SCH CELL Delete response for cellId[%d] is successful ", \
549          schCellDelRsp->cellId);
550          GET_CELL_IDX(schCellDelRsp->cellId, cellIdx);
551          if(macCb.macCell[cellIdx])
552          {
553             if(macCb.macCell[cellIdx]->cellId == schCellDelRsp->cellId)
554             {
555                status  = SUCCESSFUL_RSP;
556                if(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai)
557                {
558                   for(sliceIdx = 0; sliceIdx<macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.numSupportedSlice; sliceIdx++)
559                   {
560                      MAC_FREE(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai[sliceIdx], sizeof(Snssai));
561                   }
562                   MAC_FREE(macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.snssai, macCb.macCell[cellIdx]->macCellCfg.plmnInfoList.\
563                   numSupportedSlice * sizeof(Snssai*));
564                }
565                MAC_FREE(macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1Pdu, \
566                   macCb.macCell[cellIdx]->macCellCfg.sib1Cfg.sib1PduLen);
567                MAC_FREE(macCb.macCell[cellIdx], sizeof(MacCellCb));
568             }
569             else
570             {
571                 DU_LOG("ERROR  -->  MAC : MacProcSchCellDeleteRsp(): CellId[%d] does not exists", schCellDelRsp->cellId);
572                 status = CELL_ID_INVALID;
573                 ret = RFAILED;
574             }
575          }
576          else
577          {
578             DU_LOG("ERROR  -->  MAC : MacProcSchCellDeleteRsp(): CellId[%d] does not exists", schCellDelRsp->cellId);
579             status = CELL_ID_INVALID;
580             ret = RFAILED;
581          }
582       }
583       else
584       {
585          DU_LOG("ERROR  -->  MAC : MacProcSchCellDeleteRsp(): CellId[%d] does not exists", schCellDelRsp->cellId);
586          status = CELL_ID_INVALID;
587          ret = RFAILED;
588       }
589       if(MacSendCellDeleteRsp(status, schCellDelRsp->cellId) != ROK)
590       {
591          DU_LOG("\nERROR  -->  MAC: MacProcSchCellDeleteRsp(): Failed to send CELL delete response");
592          ret = RFAILED;
593       }
594
595    }
596    else
597    {
598       DU_LOG("\nERROR  -->  MAC: MacProcSchCellDeleteRsp(): schCellDelRsp is NULL");
599       ret = RFAILED;
600    }
601    return ret;
602 }
603
604 /*******************************************************************
605  *
606  * @brief Sends Cell delete req to Scheduler
607  *
608  * @details
609  *
610  *    Function : sendCellDelReqToSch
611  *
612  *    Functionality: sends Cell delete req to Scheduler
613  *
614  * @params[in]  SchCellDelete *schCellDel
615  * @return ROK     - success
616  *         RFAILED - failure
617  *
618  * ****************************************************************/
619
620 uint8_t sendCellDelReqToSch(SchCellDeleteReq *schCellDelReq)
621 {
622    Pst schPst;
623    FILL_PST_MAC_TO_SCH(schPst, EVENT_CELL_DELETE_REQ_TO_SCH);
624    return(SchMessageRouter(&schPst, (void *)schCellDelReq));
625 }
626
627 /*******************************************************************
628  *
629  * @brief Handles CELL Delete requst from DU APP
630  *
631  * @details
632  *
633  *    Function : MacProcCellDeleteReq
634  *
635  *    Functionality: Handles CELL Delete requst from DU APP
636  *
637  * @params[in] Pst *pst, MacCellDelete *cellDelete
638  * @return ROK     - success
639  *         RFAILED - failure
640  *
641  *
642  * ****************************************************************/
643 uint8_t MacProcCellDeleteReq(Pst *pst, MacCellDeleteReq *cellDelete)
644 {
645    uint8_t ret = ROK, cellIdx=0;
646    SchCellDeleteReq schCellDelete;
647
648    DU_LOG("\nINFO   -->  MAC : Cell Delete Request received for cellId[%d]", cellDelete->cellId);
649
650    if(cellDelete)
651    {
652       GET_CELL_IDX(cellDelete->cellId, cellIdx);
653       if(macCb.macCell[cellIdx])
654       {
655          if(macCb.macCell[cellIdx]->cellId == cellDelete->cellId)
656          {
657             memset(&schCellDelete, 0, sizeof(SchCellDeleteReq ));
658             schCellDelete.cellId =  cellDelete->cellId;
659             ret = sendCellDelReqToSch(&schCellDelete);
660             if(ret != ROK)
661             {
662                DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Failed to send UE Delete Request to SCH");
663                ret = RFAILED;
664             }
665          }
666          else
667          {
668             DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Failed to find the MacUeCb of CellId = %d",\
669             cellDelete->cellId);
670             ret = RFAILED;
671          }
672       }
673       else
674       {
675          DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Failed to find the MacUeCb of CellId = %d",\
676                cellDelete->cellId);
677          ret = RFAILED;
678       }
679
680       if(ret == RFAILED)
681       {
682           DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Sending failure response to DU");
683           if(MacSendCellDeleteRsp(CELL_ID_INVALID, cellDelete->cellId) != ROK)
684           {
685              DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): failed to send cell delete rsp for cellID[%d]",\
686              cellDelete->cellId);
687           }
688
689       }
690       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cellDelete, sizeof(MacCellDeleteReq));
691    }
692    else
693    {
694       DU_LOG("\nERROR  -->  MAC : MacProcCellDeleteReq(): Received MacCellDelete is NULL");
695       ret = RFAILED;
696    }
697    return ret;
698 }
699
700 /**
701  * @brief free the temporary slice cfg stored in macCb.
702  *
703  * @details
704  *
705  *     Function : freeMacSliceCfgReq 
706  *
707  *   free the temporary slice cfg stored in macCb
708  *
709  *  @param[in]  
710  *  @return  int
711  *      -# ROK
712  **/
713 void freeMacSliceCfgReq(MacSliceCfgReq *cfgReq,Pst *pst)
714 {
715     uint8_t policyIdx = 0, memberListIdx=0;
716
717     if(cfgReq->numOfRrmPolicy)
718     {
719        if(cfgReq->listOfRrmPolicy)
720        {
721           for(policyIdx = 0; policyIdx<cfgReq->numOfRrmPolicy; policyIdx++)
722           {
723              if(cfgReq->listOfRrmPolicy[policyIdx])
724              {
725                 if(cfgReq->listOfRrmPolicy[policyIdx]->numOfRrmPolicyMem)
726                 {
727                    if(cfgReq->listOfRrmPolicy[policyIdx]->rRMPolicyMemberList)
728                    {
729                       for(memberListIdx = 0; memberListIdx<cfgReq->listOfRrmPolicy[policyIdx]->numOfRrmPolicyMem; memberListIdx++)
730                       {
731                          MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy[policyIdx]->rRMPolicyMemberList[memberListIdx], sizeof(RrmPolicyMemberList));
732                       }
733                       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy[policyIdx]->rRMPolicyMemberList,\
734                       cfgReq->listOfRrmPolicy[policyIdx]->numOfRrmPolicyMem * sizeof(RrmPolicyMemberList*));
735                    }
736                 }
737                 MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy[policyIdx], sizeof(MacSliceRrmPolicy));
738              }
739           }
740           MAC_FREE_SHRABL_BUF(pst->region, pst->pool, cfgReq->listOfRrmPolicy, cfgReq->numOfRrmPolicy  * sizeof(MacSliceRrmPolicy*));
741        }
742     }
743
744 }
745 /**
746  * @brief fill Mac Slice Config Rsp
747  *
748  * @details
749  *
750  *     Function : fillMacSliceCfgRsp 
751  *
752  *     This function   fill Mac Slice Config Rsp
753  *
754  *  @param[in]  SchSliceCfgRsp *sliceCfgRsp, MacSliceCfgRsp *macSliceCfgRsp,
755  *  uint8_t *count
756  *  @return  int
757  *      -# ROK
758  **/
759 uint8_t fillMacSliceCfgRsp(SchSliceCfgRsp *schSliceCfgRsp, MacSliceCfgRsp *macSliceCfgRsp)
760 {
761    
762     bool sliceFound = false;
763     uint8_t cfgIdx = 0;
764
765     macSliceCfgRsp->numSliceCfgRsp  = schSliceCfgRsp->numSliceCfgRsp;
766     MAC_ALLOC_SHRABL_BUF(macSliceCfgRsp->listOfSliceCfgRsp,  macSliceCfgRsp->numSliceCfgRsp* sizeof(MacSliceRsp*));
767     if(macSliceCfgRsp->listOfSliceCfgRsp == NULLP)
768     {
769        DU_LOG("\nERROR  -->  MAC : Memory allocation failedi in fillMacSliceCfgRsp");
770        return RFAILED;
771     }
772
773     for(cfgIdx = 0; cfgIdx<schSliceCfgRsp->numSliceCfgRsp; cfgIdx++)
774     {
775        sliceFound = false;
776        if(schSliceCfgRsp->listOfSliceCfgRsp[cfgIdx]->rsp == RSP_OK)
777        {
778           sliceFound = true;
779        }
780
781        MAC_ALLOC_SHRABL_BUF(macSliceCfgRsp->listOfSliceCfgRsp[cfgIdx], sizeof(SliceRsp));
782        if(macSliceCfgRsp->listOfSliceCfgRsp[cfgIdx] == NULLP)
783        {
784           DU_LOG("\nERROR  -->  MAC : Memory allocation failedi in fillMacSliceCfgRsp");
785           return RFAILED;
786        }
787
788        macSliceCfgRsp->listOfSliceCfgRsp[cfgIdx]->snssai = schSliceCfgRsp->listOfSliceCfgRsp[cfgIdx]->snssai;
789        if(sliceFound == true)
790           macSliceCfgRsp->listOfSliceCfgRsp[cfgIdx]->rsp    = MAC_DU_APP_RSP_OK;
791        else
792        {
793           macSliceCfgRsp->listOfSliceCfgRsp[cfgIdx]->rsp    = MAC_DU_APP_RSP_NOK;
794           macSliceCfgRsp->listOfSliceCfgRsp[cfgIdx]->cause  = SLICE_NOT_PRESENT;
795        }
796     }
797     return ROK;
798 }
799
800 /**
801  * @brief send slice cfg response to duapp.
802  *
803  * @details
804  *
805  *     Function : MacSendSliceConfigRsp
806  *
807  *   sends  slice cfg response to duapp
808  *
809  *  @param[in] MacSliceCfgRsp macSliceCfgRsp 
810  *  @return  int
811  *      -# ROK
812  **/
813 uint8_t MacSendSliceConfigRsp(MacSliceCfgRsp *macSliceCfgRsp)
814 {
815     Pst  rspPst;
816     
817     memset(&rspPst, 0, sizeof(Pst));
818     FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_SLICE_CFG_RSP);
819     return (*macDuSliceCfgRspOpts[rspPst.selector])(&rspPst, macSliceCfgRsp);
820
821 }
822 /**
823  * @brief free the slice cfg rsp received from sch.
824  *
825  * @details
826  *
827  *     Function : freeSchSliceCfgRsp 
828  *
829  *     This free the slice cfg rsp received from sch
830  *
831  *  @param[in]  SchSliceCfgRsp *sliceCfgrsp
832  *  @return  int
833  *      -# ROK
834  **/
835 void freeSchSliceCfgRsp(SchSliceCfgRsp *schSliceCfgRsp)
836 {
837    uint8_t cfgIdx = 0;
838
839    if(schSliceCfgRsp)
840    {
841       if(schSliceCfgRsp->numSliceCfgRsp)
842       {
843          for(cfgIdx = 0; cfgIdx< schSliceCfgRsp->numSliceCfgRsp; cfgIdx++)
844          {
845             MAC_FREE(schSliceCfgRsp->listOfSliceCfgRsp[cfgIdx], sizeof(SliceRsp));
846          }
847          MAC_FREE(schSliceCfgRsp->listOfSliceCfgRsp, schSliceCfgRsp->numSliceCfgRsp * sizeof(SliceRsp*));
848       }
849    }
850 }
851
852 /**
853  * @brief Mac process the slice cfg rsp received from sch.
854  *
855  * @details
856  *
857  *     Function : MacProcSchSliceCfgRsp 
858  *
859  *     This function  process the slice cfg rsp received from sch
860  *
861  *  @param[in]  Pst           *pst
862  *  @param[in]  SchSliceCfgRsp *sliceCfgrsp
863  *  @return  int
864  *      -# ROK
865  **/
866 uint8_t MacProcSchSliceCfgRsp(Pst *pst, SchSliceCfgRsp *schSliceCfgRsp)
867 {
868    MacSliceCfgRsp *macSliceCfgRsp = NULLP;
869
870    if(schSliceCfgRsp)
871    {
872       MAC_ALLOC_SHRABL_BUF(macSliceCfgRsp, sizeof(MacSliceCfgRsp));
873       if(macSliceCfgRsp == NULLP)
874       {
875           DU_LOG("\nERROR  -->  MAC : Failed to allocate memory in MacProcSchSliceCfgRsp");
876           return RFAILED;
877       }
878       if(schSliceCfgRsp->listOfSliceCfgRsp)
879       {
880          if(fillMacSliceCfgRsp(schSliceCfgRsp, macSliceCfgRsp) != ROK)
881          {
882             DU_LOG("\nERROR  -->  MAC : Failed to fill the slice cfg response");
883             return RFAILED;
884          }
885          MacSendSliceConfigRsp(macSliceCfgRsp);
886       }
887       freeSchSliceCfgRsp(schSliceCfgRsp);
888    }
889    return ROK;
890 }
891
892 /**
893 * @brief send slice cfg response to duapp.
894 *
895 * @details
896 *
897 *     Function : MacSendSliceReconfigRsp 
898 *
899 *   sends  slice cfg response to duapp
900 *
901 *  @param[in] MacSliceRecfgRsp macSliceRecfgRsp
902 *  @return  int
903 *      -# ROK
904 **/
905 uint8_t MacSendSliceReconfigRsp(MacSliceRecfgRsp *macSliceRecfgRsp)
906 {
907    Pst  rspPst;
908
909    memset(&rspPst, 0, sizeof(Pst));
910    FILL_PST_MAC_TO_DUAPP(rspPst, EVENT_MAC_SLICE_RECFG_RSP);
911    return (*macDuSliceRecfgRspOpts[rspPst.selector])(&rspPst, macSliceRecfgRsp);
912
913 }
914
915 /**
916  * @brief Mac process the slice cfg rsp received from sch.
917  *
918  * @details
919  *
920  *     Function : MacProcSchSliceRecfgRsp 
921  *
922  *     This function  process the slice cfg rsp received from sch
923  *
924  *  @param[in]  Pst           *pst
925  *  @param[in]  SchSliceCfgRsp *schSliceRecfgRsp
926  *  @return  int
927  *      -# ROK
928  **/
929 uint8_t MacProcSchSliceRecfgRsp(Pst *pst, SchSliceRecfgRsp *schSliceRecfgRsp)
930 {
931    MacSliceRecfgRsp *macSliceRecfgRsp = NULLP;
932
933    if(schSliceRecfgRsp)
934    {
935       MAC_ALLOC_SHRABL_BUF(macSliceRecfgRsp, sizeof(MacSliceRecfgRsp));
936       if(macSliceRecfgRsp == NULLP)
937       {
938           DU_LOG("\nERROR  -->  MAC : Failed to allocate memory in MacProcSchSliceRecfgRsp");
939           return RFAILED;
940       }
941
942       if(schSliceRecfgRsp->listOfSliceCfgRsp)
943       {
944          if(fillMacSliceCfgRsp(schSliceRecfgRsp, macSliceRecfgRsp) != ROK)
945          {
946             DU_LOG("\nERROR  -->  MAC : Failed to fill the slice Recfg response");
947             return RFAILED;
948          }
949          MacSendSliceReconfigRsp(macSliceRecfgRsp);
950       }
951       freeSchSliceCfgRsp(schSliceRecfgRsp);
952    }
953    return ROK;
954 }
955
956 /**
957  * @brief Mac process the downlink pcch indication received from DUAPP
958  *
959  * @details
960  *
961  *     Function : MacProcDlPcchInd 
962  *
963  *     This function process the downlink pcch indication received from DUAPP
964  *
965  *  @param[in]  Pst           *pst
966  *  @param[in]  DlPcchInd    *pcchInd 
967  *  @return  int
968  *      -# ROK
969  **/
970 uint8_t MacProcDlPcchInd(Pst *pst, DlPcchInd *pcchInd)
971 {
972    uint8_t ret = RFAILED;
973    uint16_t cellIdx = 0;
974    Pst       schPst;
975    SchPageInd *schPageInd = NULLP;
976
977    if(pcchInd)
978    {
979       DU_LOG("\nINFO   -->  MAC : Received DL PCCH IND from DU_APP for cellId[%d]", pcchInd->cellId);
980       
981       GET_CELL_IDX(pcchInd->cellId, cellIdx);
982
983       if(macCb.macCell[cellIdx] == NULLP || macCb.macCell[cellIdx]->cellId != pcchInd->cellId)
984       {
985          DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): CellId[%d] does not exist", pcchInd->cellId);
986       }
987       else
988       {
989          if((pcchInd->pcchPdu == NULLP) || (pcchInd->pduLen <= 0))
990          {
991             DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Received Pcch pdu is null");
992          }
993          else
994          {
995             MAC_ALLOC(schPageInd, sizeof(SchPageInd));
996             if(schPageInd == NULLP)
997             {
998                DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Failed to allocate memory");
999             }
1000             else
1001             {
1002                schPageInd->cellId = pcchInd->cellId;
1003                schPageInd->pf = pcchInd->pf;
1004                schPageInd->i_s = pcchInd->i_s;
1005                schPageInd->pduLen = pcchInd->pduLen;
1006                
1007                MAC_ALLOC(schPageInd->pagePdu, pcchInd->pduLen);
1008                if(schPageInd->pagePdu == NULLP)
1009                {
1010                   DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Failed to allocate memory");
1011                   MAC_FREE(schPageInd, sizeof(SchPageInd));
1012                }
1013                else
1014                {
1015                   memcpy(schPageInd->pagePdu, pcchInd->pcchPdu, pcchInd->pduLen);
1016
1017                   FILL_PST_MAC_TO_SCH(schPst, EVENT_PAGING_IND_TO_SCH);
1018                   ret = SchMessageRouter(&schPst, (void *)schPageInd);
1019                }
1020             }
1021          }
1022       }
1023       if((pcchInd->pcchPdu) && (pcchInd->pduLen > 0))
1024       {
1025          MAC_FREE_SHRABL_BUF(pst->region, pst->pool, pcchInd->pcchPdu, pcchInd->pduLen);
1026       }
1027       MAC_FREE_SHRABL_BUF(pst->region, pst->pool, pcchInd, sizeof(DlPcchInd));
1028    }
1029    else
1030    {
1031       DU_LOG("\nERROR  -->  MAC : MacProcDlPcchInd(): Received Null pointer");
1032    }
1033    return ret;
1034 }
1035 /**********************************************************************
1036   End of file
1037  **********************************************************************/