0795850456166ab379c68619e75e0bd8eccd11c2
[o-du/l2.git] / src / du_app / du_msg_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
19 /* This file contains message handling functionality for DU APP */
20 #include "common_def.h"
21 #include "lrg.h"
22 #include "du_tmr.h"
23 #include "legtp.h"
24 #include "lkw.h"
25 #include "kwu.h"
26 #include "lrg.x"
27 #include "lkw.x"
28 #include "kwu.x"
29 #include "du_app_mac_inf.h"
30 #include "du_app_rlc_inf.h"
31 #include "du_e2ap_mgr.h"
32 #include "du_e2ap_msg_hdl.h"
33 #include "du_cfg.h"
34 #include "du_app_rlc_inf.h"
35 #include "du_mgr.h"
36 #include "du_sctp.h"
37 #include "F1AP-PDU.h"
38 #include "du_f1ap_msg_hdl.h"
39 #include "du_ue_mgr.h"
40 #include "lsctp.h"
41 #include "legtp.h"
42 #include "du_utils.h"
43 #include "du_cell_mgr.h" 
44
45 #ifdef O1_ENABLE
46
47 #include "AlarmInterface.h"
48 #include "CmInterface.h"
49 #include "PmInterface.h"
50
51 #endif 
52
53 uint8_t rlcDlCfg = 0;
54 uint8_t numRlcDlSaps = 0;
55 uint8_t rlcUlCfg = 0;
56 uint8_t numRlcMacSaps = 0;
57 uint8_t macCfg = 0;
58 uint8_t macCfgInst = 0;
59
60 DuCfgParams duCfgParam;
61 uint8_t packRlcConfigReq(Pst *pst, RlcMngmt *cfg);
62 uint8_t cmPkLkwCntrlReq(Pst *pst, RlcMngmt *cfg);
63 uint8_t cmPkLrgCfgReq(Pst *pst, RgMngmt *cfg);
64 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg);
65 uint8_t BuildAndSendDUConfigUpdate();
66 uint16_t getTransId();
67 uint8_t cmPkLrgSchCfgReq(Pst * pst,RgMngmt * cfg);
68 uint8_t sendCellDeleteReqToMac(uint16_t cellId);
69
70 packMacCellCfgReq packMacCellCfgOpts[] =
71 {
72    packMacCellCfg, /* packing for loosely coupled */
73    MacProcCellCfgReq, /* packing for tightly coupled */
74    packMacCellCfg, /* packing for light weight loosly coupled */
75 };
76
77 DuMacCellStart packMacCellStartOpts[] =
78 {
79    packMacCellStart,   /* Loose coupling */
80    MacProcCellStart,   /* TIght coupling */
81    packMacCellStart    /* Light weight-loose coupling */
82 };
83
84 DuMacCellStop packMacCellStopOpts[] =
85 {
86    packMacCellStop,   /* Loose coupling */
87    MacProcCellStop,   /* TIght coupling */
88    packMacCellStop    /* Light weight-loose coupling */
89 };
90
91 DuMacSliceCfgReq packMacSliceCfgReqOpts[] =
92 {
93    packDuMacSliceCfgReq,       /* Loose coupling */
94    MacProcSliceCfgReq,         /* TIght coupling */
95    packDuMacSliceCfgReq        /* Light weight-loose coupling */
96 };
97
98
99 DuMacSliceRecfgReq packMacSliceRecfgReqOpts[] =
100 {
101    packDuMacSliceRecfgReq,     /* Loose coupling */
102    MacProcSliceRecfgReq,       /* TIght coupling */
103    packDuMacSliceRecfgReq      /* Light weight-loose coupling */
104 };
105
106 DuMacStatsReqFunc packMacStatsReqOpts[]=
107 {
108    packDuMacStatsReq,          /* Loose Coupling */
109    MacProcStatsReq,            /* Tight Coupling */
110    packDuMacStatsReq           /* Light weight-loose coupling */
111 };
112
113 /**************************************************************************
114  * @brief Function to fill configs required by RLC
115  *
116  * @details
117  *
118  *      Function : duBuildRlcCfg 
119  * 
120  *      Functionality:
121  *           Initiates general Configs towards RLC 
122  *     
123  * @param[in] Inst  Specifies if RLC UL or RLC DL instance 
124  * @return ROK     - success
125  *         RFAILED - failure
126  *
127  ***************************************************************************/
128 uint8_t duBuildRlcCfg(Inst inst)
129 {
130    RlcMngmt   rlcMngmt;
131    RlcGenCfg  *genCfg = NULLP;
132    Pst pst;
133
134    DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
135    DU_SET_ZERO(&pst, sizeof(Pst));
136
137    genCfg   = &(rlcMngmt.t.cfg.s.gen);
138
139    /*----------- Fill General Configuration Parameters ---------*/
140    genCfg->maxUe       = duCfgParam.maxUe;
141    genCfg->maxKwuSaps  = 2;
142    genCfg->maxUdxSaps  = 1; 
143    genCfg->rlcMode     = (inst == RLC_UL_INST) ?
144       LKW_RLC_MODE_UL : LKW_RLC_MODE_DL;
145    genCfg->timeRes     = 1; 
146    genCfg->maxRguSaps  = DEFAULT_CELLS;
147
148    /*----------- Fill lmPst
149     * Parameters ---------*/
150    genCfg->lmPst.dstProcId = DU_PROC;
151    genCfg->lmPst.srcProcId = DU_PROC;
152    genCfg->lmPst.dstEnt    = ENTDUAPP;
153    genCfg->lmPst.dstInst   = DU_INST;
154    genCfg->lmPst.srcEnt    = ENTRLC;
155    genCfg->lmPst.srcInst   = inst;
156    genCfg->lmPst.prior     = PRIOR0;
157    genCfg->lmPst.route     = RTESPEC;
158    genCfg->lmPst.region    = (inst == RLC_UL_INST) ?
159       RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
160    genCfg->lmPst.pool      = RLC_POOL;
161    genCfg->lmPst.selector  = ODU_SELECTOR_LC;
162
163    /* Fill Header */
164    rlcMngmt.hdr.msgType             = TCFG;
165    rlcMngmt.hdr.msgLen              = 0;
166    rlcMngmt.hdr.entId.ent           = ENTRLC;
167    rlcMngmt.hdr.entId.inst          = (Inst)0;
168    rlcMngmt.hdr.elmId.elmnt         = STGEN;
169    rlcMngmt.hdr.seqNmb              = 0;
170    rlcMngmt.hdr.version             = 0;
171    rlcMngmt.hdr.transId             = 0;
172    rlcMngmt.hdr.response.prior      = PRIOR0;
173    rlcMngmt.hdr.response.route      = RTESPEC;
174    rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
175       RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
176    rlcMngmt.hdr.response.mem.pool   = DU_POOL;
177    rlcMngmt.hdr.response.selector   = ODU_SELECTOR_LC;
178
179    /* Fill Pst */
180    pst.selector  = ODU_SELECTOR_LC;
181    pst.srcEnt    = ENTDUAPP;
182    pst.dstEnt    = ENTRLC;
183    pst.dstInst   = inst;
184    pst.dstProcId = DU_PROC;
185    pst.srcProcId = DU_PROC;
186    pst.region    = duCb.init.region;
187
188    DU_LOG("\nDEBUG   -->  DU_APP : RLC Gen Cfg Req sent for inst %d", inst);
189
190    /* Send the request to RLC */
191    packRlcConfigReq(&pst, &rlcMngmt);
192
193    return ROK;
194 }
195
196 /**************************************************************************
197  * @brief Function to fill configs required by RLC
198  *
199  * @details
200  *
201  *      Function : duBuildRlcLsapCfg 
202  * 
203  *      Functionality:
204  *           Initiates general Configs towards RLC 
205  *     
206  * @param[in] Inst  Specifies if RLC UL or RLC DL instance 
207  * @return ROK     - success
208  *         RFAILED - failure
209  *
210  ***************************************************************************/
211 uint8_t duBuildRlcLsapCfg(Ent ent, Inst inst, uint8_t lsapInst)
212 {
213
214    RlcMngmt   rlcMngmt;
215    RlcSapCfg  *lSap = NULLP;
216    Pst        pst;
217
218    DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
219    DU_SET_ZERO(&pst, sizeof(Pst));
220
221    /* Fill Header */
222    rlcMngmt.hdr.msgType             = TCFG;
223    rlcMngmt.hdr.entId.ent           = ENTRLC;
224    rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
225       RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
226
227    rlcMngmt.hdr.response.mem.pool   = RLC_POOL;
228
229    /* Fill Pst */
230    pst.selector  = ODU_SELECTOR_LC;
231    pst.srcEnt    = ENTDUAPP;
232    pst.dstEnt    = ENTRLC;
233    pst.dstProcId = DU_PROC;
234    pst.dstInst   = inst;
235    pst.srcProcId = DU_PROC;
236    pst.region    = duCb.init.region;
237    lSap   = &(rlcMngmt.t.cfg.s.sap);
238
239    lSap->mem.region = (inst == RLC_UL_INST) ?
240       RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
241    lSap->mem.pool    = RLC_POOL;
242    lSap->mem.spare   = 0;
243    lSap->bndTmrIntvl = 10;
244    lSap->priority    = PRIOR0;
245    lSap->route       = RTESPEC;
246    if (ent == ENTMAC)
247    {
248       lSap->procId      = DU_PROC;
249       lSap->ent         = ENTMAC;
250       lSap->inst        = lsapInst;
251       lSap->sapId       = lsapInst;      /* SapId will be stored as suId in MAC */
252       lSap->selector    = (inst == RLC_UL_INST) ? ODU_SELECTOR_LWLC : ODU_SELECTOR_TC;
253       rlcMngmt.hdr.elmId.elmnt  = STRGUSAP;
254       DU_LOG("\nDEBUG   -->  DU_APP : RLC MAC Lower Sap Cfg Req sent for inst %d", inst);
255
256    }
257    else
258    {
259       lSap->procId    = DU_PROC;
260       lSap->ent       = ENTRLC;
261       lSap->inst      = (inst == RLC_UL_INST) ?
262          RLC_DL_INST : RLC_UL_INST;
263       lSap->sapId       = 0;
264       lSap->selector = ODU_SELECTOR_LC;
265       rlcMngmt.hdr.elmId.elmnt  = STUDXSAP;
266       DU_LOG("\nDEBUG   -->  DU_APP : RLC DL/UL Lower Sap Cfg Req sent for inst %d", inst);
267    }
268
269    packRlcConfigReq(&pst, &rlcMngmt);
270    return ROK;
271 }
272
273 /**************************************************************************
274  * @brief Function to fill configs required by RLC
275  *
276  * @details
277  *
278  *      Function : duBuildRlcUsapCfg 
279  * 
280  *      Functionality:
281  *           Initiates general Configs towards RLC 
282  *     
283  * @param[in] Inst  Specifies if RLC UL or RLC DL instance 
284  * @return ROK     - success
285  *         RFAILED - failure
286  *
287  ***************************************************************************/
288 uint8_t duBuildRlcUsapCfg(uint8_t elemId, Ent ent, Inst inst)
289 {
290    RlcMngmt   rlcMngmt;
291    RlcSapCfg  *uSap = NULLP;
292    Pst        pst;
293
294    DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
295    DU_SET_ZERO(&pst, sizeof(Pst));
296
297    uSap   = &(rlcMngmt.t.cfg.s.sap);
298
299    uSap->selector   = ODU_SELECTOR_LC;
300    uSap->mem.region = (inst == RLC_UL_INST) ?
301       RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
302    uSap->mem.pool = RLC_POOL;
303    uSap->mem.spare = 0;
304
305    uSap->procId = DU_PROC;
306    uSap->ent = ENTRLC;
307    uSap->sapId = 0;
308
309    uSap->inst = (inst == RLC_UL_INST) ?
310       RLC_DL_INST : RLC_UL_INST;
311    uSap->bndTmrIntvl = 1000;
312    uSap->priority = PRIOR0;
313    uSap->route = RTESPEC;
314
315    /* Fill Header */
316    rlcMngmt.hdr.msgType             = TCFG;
317    rlcMngmt.hdr.entId.ent           = ENTRLC;
318    rlcMngmt.hdr.elmId.elmnt         = STUDXSAP;
319    rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
320       RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
321
322    rlcMngmt.hdr.response.mem.pool   = RLC_POOL;
323
324    /* Fill Pst */
325    pst.selector  = ODU_SELECTOR_LC;
326    pst.srcEnt    = ENTDUAPP;
327    pst.dstEnt    = ENTRLC;
328    pst.dstProcId = DU_PROC;
329    pst.dstInst = inst;
330    pst.srcProcId = DU_PROC;
331    pst.region = duCb.init.region;
332
333    DU_LOG("\nDEBUG   -->  DU_APP : RLC Kwu Upper Sap Cfg Req sent for inst %d", inst);
334    packRlcConfigReq(&pst, &rlcMngmt);
335
336    return ROK;
337 }
338
339 /**************************************************************************
340  * @brief Function to populate internal DS of DU APP
341  *
342  * @details
343  *
344  *      Function : duProcCfgComplete
345  * 
346  *      Functionality:
347  *           Populates internal data structures of DU APP after 
348  *           receiving configurations.
349  *     
350  * @param[in]  void
351  * @return ROK     - success
352  *         RFAILED - failure
353  *
354  ***************************************************************************/
355 uint8_t duProcCfgComplete()
356 {
357    uint8_t         ret = ROK;
358    uint16_t        idx;
359    for(idx=0; idx< DEFAULT_CELLS; idx++)
360    {
361       DuCellCb *cell = NULLP;
362       DU_ALLOC(cell, sizeof(DuCellCb));
363       if(cell == NULLP)
364       {
365          DU_LOG("\nERROR  -->  DU_APP : Memory Allocation failed in duProcCfgComplete");
366          ret = RFAILED;
367       }
368       else
369       {
370          uint8_t idx1=0; 
371          memset(cell, 0, sizeof(DuCellCb));
372          cell->cellId = NR_CELL_ID; //++cellId;
373          memset(&cell->cellInfo.nrEcgi.plmn, 0, sizeof(Plmn));
374          cell->cellInfo.nrEcgi.plmn.mcc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[0];
375          cell->cellInfo.nrEcgi.plmn.mcc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[1];
376          cell->cellInfo.nrEcgi.plmn.mcc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[2];
377          cell->cellInfo.nrEcgi.plmn.mnc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[0];
378          cell->cellInfo.nrEcgi.plmn.mnc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[1];
379          cell->cellInfo.nrEcgi.plmn.mnc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[2];
380          cell->cellInfo.nrEcgi.cellId = cell->cellId;
381          cell->cellInfo.nrPci = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrPci; 
382          cell->cellInfo.fiveGsTac = duCfgParam.srvdCellLst[0].duCellInfo.tac;
383          memset(&cell->cellInfo.plmn[idx1], 0, sizeof(Plmn));
384          for(idx1=0; idx1<MAX_PLMN; idx1++)
385          {
386             cell->cellInfo.plmn[idx1].mcc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[0];
387             cell->cellInfo.plmn[idx1].mcc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[1];
388             cell->cellInfo.plmn[idx1].mcc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[2];
389             cell->cellInfo.plmn[idx1].mnc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[0];
390             cell->cellInfo.plmn[idx1].mnc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[1];
391             cell->cellInfo.plmn[idx1].mnc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[2];
392          }
393          cell->cellInfo.maxUe = duCfgParam.maxUe;
394          cell->cellStatus = CELL_OUT_OF_SERVICE;
395          gCellStatus = CELL_DOWN;
396          duCb.cfgCellLst[duCb.numCfgCells] = cell;
397          duCb.numCfgCells++;
398       }
399    }
400    if(ret != RFAILED)
401    {
402       //Start layer configs
403       ret = duSendRlcUlCfg();
404    }
405    return ret;
406 }
407 /**************************************************************************
408  * @brief Function to invoke DU Layer Configs
409  *
410  * @details
411  *
412  *      Function : duSendRlcUlCfg 
413  * 
414  *      Functionality:
415  *           Initiates Configs towards layers of DU
416  *     
417  * @param[in]  void
418  * @return ROK     - success
419  *         RFAILED - failure
420  *
421  ***************************************************************************/
422 uint8_t duSendRlcUlCfg()
423 {
424    uint8_t cellIdx; 
425
426    duBuildRlcCfg((Inst)RLC_UL_INST);
427    for(cellIdx = 0; cellIdx < DEFAULT_CELLS; cellIdx++)
428    {
429       duBuildRlcLsapCfg(ENTMAC, (Inst)RLC_UL_INST, cellIdx);
430    }
431    duBuildRlcLsapCfg(ENTRLC, (Inst)RLC_UL_INST, 0);
432
433    return ROK;
434 }
435
436 /**************************************************************************
437  * @brief Function to invoke DU Layer Configs
438  *
439  * @details
440  *
441  *      Function : duSendRlcDlCfg 
442  * 
443  *      Functionality:
444  *           Initiates Configs towards layers of DU
445  *     
446  * @param[in]  void
447  * @return ROK     - success
448  *         RFAILED - failure
449  *
450  ***************************************************************************/
451 uint8_t duSendRlcDlCfg()
452 {
453    uint8_t cellIdx; 
454
455    duBuildRlcCfg((Inst)RLC_DL_INST);
456    duBuildRlcUsapCfg(STUDXSAP, ENTRLC, (Inst)RLC_DL_INST);
457    for(cellIdx = 0; cellIdx < DEFAULT_CELLS; cellIdx++)
458    {
459       duBuildRlcLsapCfg(ENTMAC, (Inst)RLC_DL_INST, cellIdx);
460    }
461
462    return ROK;
463 }
464 /**************************************************************************
465  * @brief Function to handle Config Confirm from RLC
466  *
467  * @details
468  *
469  *      Function : DuHdlRlcCfgComplete 
470  * 
471  *      Functionality:
472  *           Handles Gen Config Confirm from RLC
473  *     
474  * @param[in]  Pst     *pst, Post structure of the primitive.     
475  * @param[in]  RlcMngmt *cfm, Unpacked primitive info received from RLC
476  * @return ROK     - success
477  *         RFAILED - failure
478  *
479  ***************************************************************************/
480 uint8_t DuHdlRlcCfgComplete(Pst *pst, RlcMngmt *cfm)
481 {
482    uint8_t ret = ROK;
483    if (pst->srcInst == RLC_UL_INST)
484    {
485       ret = duProcRlcUlCfgComplete(pst, cfm);
486    }
487    else
488    {
489       ret = duProcRlcDlCfgComplete(pst, cfm);
490    }
491    return ret;
492 }
493
494 /**************************************************************************
495  * @brief Function to handle Control Config Confirm from RLC
496  *
497  * @details
498  *
499  *      Function : duHdlRlcCntrlCfgComplete 
500  * 
501  *      Functionality:
502  *           Handles Control Config Confirm from RLC
503  *     
504  * @param[in]  Pst     *pst, Post structure of the primitive.     
505  * @param[in]  RlcMngmt *cfm, Unpacked primitive info received from RLC
506  * @return ROK     - success
507  *         RFAILED - failure
508  *
509  ***************************************************************************/
510 uint8_t duHdlRlcCntrlCfgComplete(Pst *pst, RlcMngmt *cntrl)
511 {
512    uint8_t ret = ROK;
513
514    if (cntrl->cfm.status == LCM_PRIM_OK)
515    {
516       switch (cntrl->hdr.elmId.elmnt)
517       {
518          case  STRGUSAP:
519             {
520                if (pst->srcInst == RLC_DL_INST)
521                {
522                   DU_LOG("\nDEBUG   -->  DU_APP : BIND OF RLC DL TO MAC (RGU) SAP SUCCESSFUL");
523                   macCfgInst++;
524                   if(macCfgInst < DEFAULT_CELLS)
525                   {
526                      macCfgInst = 0;
527                      duBindUnbindRlcToMacSap((Inst) RLC_DL_INST, ABND);
528                   }
529                   else
530                   {
531                      duBindUnbindRlcToMacSap((Inst) RLC_UL_INST, ABND);
532                   }
533                }
534                else
535                {
536                   DU_LOG("\nDEBUG   -->  DU_APP : BIND OF RLC UL TO MAC (RGU) SAP SUCCESSFUL");
537                   macCfgInst++;
538                   if(macCfgInst < DEFAULT_CELLS)
539                   {
540                      duBindUnbindRlcToMacSap((Inst) RLC_UL_INST, ABND);
541                   }
542                   else
543                   {
544                      duSendSchCfg();
545                   }
546                   break;
547                }
548             }
549
550       }
551    }
552    return ret;
553 }
554 /**************************************************************************
555  * @brief Function to handle Config Confirm from RLC UL
556  *
557  * @details
558  *
559  *      Function : duHdlRlcUlCfgComplete 
560  * 
561  *      Functionality:
562  *           Handles Config Confirm from RLC UL
563  *     
564  * @param[in]  Pst     *pst, Post structure of the primitive.     
565  * @param[in]  RlcMngmt *cfm, Unpacked primitive info received from RLC UL
566  * @return ROK     - success
567  *         RFAILED - failure
568  *
569  ***************************************************************************/
570 uint8_t duProcRlcUlCfgComplete(Pst *pst, RlcMngmt *cfm)
571 {
572    uint8_t ret;
573
574    DU_LOG("\nDEBUG   -->  DU_APP : RLC UL Cfg Status %d", cfm->cfm.status);
575    if (cfm->cfm.status == LCM_PRIM_OK)
576    {
577       switch(cfm->hdr.elmId.elmnt)
578       {
579          case STGEN:
580             {
581                rlcUlCfg |= RLC_GEN_CFG;
582                break;
583             }
584          case STRGUSAP:
585             {
586                numRlcMacSaps++;
587                if(numRlcMacSaps == DEFAULT_CELLS)
588                {
589                   rlcUlCfg |= RLC_MAC_SAP_CFG;
590                   numRlcMacSaps = 0;
591                }
592                break;
593             }
594          case STUDXSAP:
595             {
596                rlcUlCfg |= RLC_UDX_SAP_CFG;
597                break;
598
599             }
600          default:
601             break;
602       }
603       DU_LOG("\nDEBUG   -->  DU_APP : RLC UL Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
604       if(rlcUlCfg == DU_RLC_UL_CONFIGURED)
605       {
606          rlcUlCfg = 0;
607          numRlcMacSaps = 0;
608          //Start configuration of RLC DL
609          duSendRlcDlCfg();
610
611       }
612    }
613    else
614    {
615       DU_LOG("\nERROR  -->  DU_APP : Config confirm NOK from RLC UL");
616       ret = RFAILED;
617    }
618    return ret;
619 }
620
621 /**************************************************************************
622  * @brief Function to handle Config Confirm from RLC DL
623  *
624  * @details
625  *
626  *      Function : duHdlRlcDlCfgComplete 
627  * 
628  *      Functionality:
629  *           Handles Config Confirm from RLC DL
630  *     
631  * @param[in]  Pst     *pst, Post structure of the primitive.     
632  * @param[in]  RlcMngmt *cfm, Unpacked primitive info received from RLC DL
633  * @return ROK     - success
634  *         RFAILED - failure
635  *
636  ***************************************************************************/
637 uint8_t duProcRlcDlCfgComplete(Pst *pst, RlcMngmt *cfm)
638 {
639    DU_LOG("\nDEBUG   -->  DU_APP : RLC DL Cfg Status %d", cfm->cfm.status);
640    if (cfm->cfm.status == LCM_PRIM_OK)
641    {
642       switch(cfm->hdr.elmId.elmnt)
643       {
644          case STGEN:
645             {
646                rlcDlCfg |= RLC_GEN_CFG;
647                break;
648             }
649          case STRGUSAP:
650             {
651                numRlcMacSaps++;
652                if(numRlcMacSaps == DEFAULT_CELLS)
653                {
654                   rlcDlCfg |= RLC_MAC_SAP_CFG;
655                   numRlcMacSaps = 0;
656                }
657                break;
658             }
659          case STUDXSAP:
660             {
661                rlcDlCfg |= RLC_UDX_SAP_CFG;
662                break;
663
664             }
665          default:
666             break;
667
668       }
669       DU_LOG("\nDEBUG   -->  DU_APP : RLC DL Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
670       if(rlcDlCfg == DU_RLC_DL_CONFIGURED)
671       {
672          rlcDlCfg = 0;
673          //Start configuration of MAC
674          duSendMacCfg();
675
676       }
677    }
678    else
679    {
680       DU_LOG("\nERROR  -->  DU_APP : Config confirm NOK from RLC DL");
681    }
682    return ROK;
683 }
684
685 /**************************************************************************
686  * @brief Function to send configs to MAC
687  *
688  * @details
689  *
690  *      Function : duSendMacCfg 
691  * 
692  *      Functionality:
693  *           Initiates Configs towards MAC layer
694  *     
695  * @param[in]  void
696  * @return ROK     - success
697  *         RFAILED - failure
698  *
699  ***************************************************************************/
700 uint8_t duSendMacCfg()
701 {
702    duBuildMacGenCfg();
703    duBuildMacUsapCfg(RLC_UL_INST);
704    duBuildMacUsapCfg(RLC_DL_INST);
705
706    return ROK;
707 }
708
709 /**************************************************************************
710  * @brief Function to fill gen config required by MAC
711  *
712  * @details
713  *
714  *      Function : duBuildMacGenCfg 
715  * 
716  *      Functionality:
717  *           Initiates general Configs towards MAC
718  *     
719  * @param[in] void
720  * @return ROK     - success
721  *         RFAILED - failure
722  *
723  ***************************************************************************/
724 uint8_t duBuildMacGenCfg()
725 {
726    RgMngmt       rgMngmt;
727    RgGenCfg      *genCfg=NULLP;
728    Pst           pst;
729
730    DU_SET_ZERO(&pst, sizeof(Pst));
731    DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
732
733    genCfg   = &(rgMngmt.t.cfg.s.genCfg);
734
735    /*----------- Fill General Configuration Parameters ---------*/
736    genCfg->mem.region = MAC_MEM_REGION;
737    genCfg->mem.pool   = MAC_POOL;
738    genCfg->tmrRes     = 1;
739    genCfg->numRguSaps = 2;
740
741    genCfg->lmPst.dstProcId = DU_PROC;
742    genCfg->lmPst.srcProcId = DU_PROC;
743    genCfg->lmPst.dstEnt    = ENTDUAPP;
744    genCfg->lmPst.dstInst   = 0;
745    genCfg->lmPst.srcEnt    = ENTMAC;
746    genCfg->lmPst.srcInst   = macCfgInst;
747    genCfg->lmPst.prior     = PRIOR0;
748    genCfg->lmPst.route     = RTESPEC;
749    genCfg->lmPst.region    = MAC_MEM_REGION;
750    genCfg->lmPst.pool      = MAC_POOL;
751    genCfg->lmPst.selector  = ODU_SELECTOR_LC;
752
753    /* Fill Header */
754    rgMngmt.hdr.msgType             = TCFG;
755    rgMngmt.hdr.msgLen              = 0;
756    rgMngmt.hdr.entId.ent           = ENTMAC;
757    rgMngmt.hdr.entId.inst          = (Inst)0;
758    rgMngmt.hdr.elmId.elmnt         = STGEN;
759    rgMngmt.hdr.seqNmb              = 0;
760    rgMngmt.hdr.version             = 0;
761    rgMngmt.hdr.transId             = 0;
762
763    rgMngmt.hdr.response.prior      = PRIOR0;
764    rgMngmt.hdr.response.route      = RTESPEC;
765    rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
766    rgMngmt.hdr.response.mem.pool   = MAC_POOL;
767    rgMngmt.hdr.response.selector   = ODU_SELECTOR_LC;
768
769    /* Fill Pst */
770    pst.selector  = ODU_SELECTOR_LC;
771    pst.srcEnt    = ENTDUAPP;
772    pst.dstEnt    = ENTMAC;
773    pst.dstInst   = macCfgInst;
774    pst.dstProcId = DU_PROC;
775    pst.srcProcId = DU_PROC;
776    pst.region = duCb.init.region;
777
778    DU_LOG("\nDEBUG   -->  DU_APP : MAC Gen Cfg Req sent");
779
780    /* Send the request to MAC */
781    cmPkLrgCfgReq(&pst, &rgMngmt);
782
783    return ROK;
784 }
785
786 /**************************************************************************
787  * @brief Function to fill USAP config required by MAC
788  *
789  * @details
790  *
791  *      Function : duBuildMacUsapCfg 
792  * 
793  *      Functionality:
794  *           Initiates USAP Configs towards MAC
795  *     
796  * @param[in] SpId  Specifies if RLC UL or RLC DL instance 
797  * @return ROK     - success
798  *         RFAILED - failure
799  *
800  ***************************************************************************/
801 uint8_t duBuildMacUsapCfg(SpId sapId)
802 {
803    RgMngmt     rgMngmt;
804    RgUpSapCfg  *uSap = NULLP;
805    Pst         pst;
806
807    DU_SET_ZERO(&pst, sizeof(Pst));
808    DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
809
810    uSap   = &(rgMngmt.t.cfg.s.rguSap);
811
812    uSap->mem.region = MAC_MEM_REGION;
813    uSap->mem.pool   = MAC_POOL;
814    uSap->suId       = 0;
815    uSap->spId       = sapId;
816    uSap->procId     = DU_PROC;
817    uSap->ent        = ENTRLC;
818    uSap->inst       = sapId;
819    uSap->prior      = PRIOR0;
820    uSap->route      = RTESPEC;
821    uSap->selector   = ODU_SELECTOR_LC ;
822
823    /* fill header */
824    rgMngmt.hdr.msgType             = TCFG;
825    rgMngmt.hdr.entId.ent           = ENTMAC;
826    rgMngmt.hdr.entId.inst          = (Inst)0;
827    rgMngmt.hdr.elmId.elmnt         = STRGUSAP;
828    rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
829    rgMngmt.hdr.response.mem.pool   = MAC_POOL;
830
831    /* fill pst */
832    pst.selector  = ODU_SELECTOR_LC;
833    pst.srcEnt    = ENTDUAPP;
834    pst.dstEnt    = ENTMAC;
835    pst.dstInst   = macCfgInst;
836    pst.dstProcId = DU_PROC;
837    pst.srcProcId = DU_PROC;
838    pst.region    = duCb.init.region;
839
840    DU_LOG("\nDEBUG  -->  DU_APP : MAC Rgu USap Cfg Req sent");
841
842    /* Send the request to MAC */
843    cmPkLrgCfgReq(&pst, &rgMngmt);
844
845    return ROK;
846 }
847
848 /**************************************************************************
849  * @brief Function to handle Config Confirm from MAC
850  *
851  * @details
852  *
853  *      Function : duHdlMacCfgComplete 
854  * 
855  *      Functionality:
856  *           Handles Gen Config Confirm from MAC
857  *     
858  * @param[in]  Pst     *pst, Post structure of the primitive.     
859  * @param[in]  RgMngmt *cfm, Unpacked primitive info received from MAC
860  * @return ROK     - success
861  *         RFAILED - failure
862  *
863  ***************************************************************************/
864 uint8_t duHdlMacCfgComplete(Pst *pst, RgMngmt *cfm)
865 {
866    uint8_t ret = ROK;
867
868    if (cfm->cfm.status == LCM_PRIM_OK)
869    {
870       switch (cfm->hdr.elmId.elmnt)
871       {
872          case STGEN:
873             {
874                macCfg |= MAC_GEN_CFG;
875                break;
876             }
877          case STRGUSAP:
878             {
879                macCfg |= MAC_SAP_CFG;
880                numRlcMacSaps++;
881                break;
882             }
883          default:
884             break;
885       }
886       DU_LOG("\nDEBUG   -->  DU_APP : MAC Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
887       if(macCfg == MAC_CONFIGURED && numRlcMacSaps == MAX_MAC_SAP)
888       {
889          macCfg = 0;
890          DU_LOG("\nDEBUG   -->  DU_APP : Completed sending Configs");
891          macCfgInst = 0;
892          duBindUnbindRlcToMacSap(RLC_DL_INST, ABND);
893       }
894
895    }
896    else
897    {
898       DU_LOG("\nERROR  -->  DU_APP : Config confirm NOK from MAC");
899       ret = RFAILED;
900    }
901    return ret;
902 }
903
904 /**************************************************************************
905  * @brief Function to bind/unbind RLC to MAC SAP
906  *
907  * @details
908  *
909  *      Function : duBindUnbindRlcToMacSap 
910  * 
911  *      Functionality:
912  *           Initiates Bind/Unbind from RLC to MAC
913  *     
914  * @param[in] Inst   Specifies if RLC UL or RLC DL instance 
915  * @param[in] action Specifies if action is bind or unbind
916  * @return ROK     - success
917  *         RFAILED - failure
918  *
919  ***************************************************************************/
920 uint8_t duBindUnbindRlcToMacSap(uint8_t inst, uint8_t action)
921 {
922    RlcCntrl  *cntrl = NULLP;
923    RlcMngmt  rlcMngmt;
924    Pst      pst;
925
926
927    DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
928    DU_SET_ZERO(&pst, sizeof(Pst));
929
930    if (action == ABND)
931    {
932       DU_LOG("\nDEBUG   -->  DU_APP : Cntrl Req to RLC inst %d to bind MAC sap", inst);
933    }
934    else
935    {
936       DU_LOG("\nDEBUG   -->  DU_APP : Cntrl Req to RLC inst %d to unbind MAC sap", inst);
937    }
938    cntrl = &(rlcMngmt.t.cntrl);
939
940    cntrl->action            =  action;
941    cntrl->subAction         =  DU_ZERO_VAL;
942    cntrl->s.sapCntrl.suId   =  macCfgInst;
943    cntrl->s.sapCntrl.spId   =  inst;
944
945    /* Fill header */
946    rlcMngmt.hdr.msgType             = TCNTRL;
947    rlcMngmt.hdr.entId.ent           = ENTRLC;
948    rlcMngmt.hdr.entId.inst          = inst;
949    rlcMngmt.hdr.elmId.elmnt         = 186; /* ambiguous defines in lkw.h and lrg.h so direct hardcoded*/
950    rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
951       RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
952    rlcMngmt.hdr.response.mem.pool   = RLC_POOL;
953
954    /* Fill pst */
955    pst.selector  = ODU_SELECTOR_LC;
956    pst.srcEnt    = ENTDUAPP;
957    pst.dstEnt    = ENTRLC;
958    pst.dstProcId = DU_PROC;
959    pst.dstInst   = inst;
960    pst.srcProcId = DU_PROC;
961    pst.region    = duCb.init.region;
962
963    cmPkLkwCntrlReq(&pst, &rlcMngmt);
964
965    return ROK;
966 }
967 /*******************************************************************
968  *
969  * @brief Handles SCTP notifications
970  *
971  * @details
972  *
973  *    Function : duSctpNtfyHdl
974  *
975  *    Functionality:
976  *         Handles SCTP notification
977  *
978  * @params[in] Message Buffer
979  *             SCTP notification
980  *
981  * @return ROK     - success
982  *         RFAILED - failure
983  *
984  * ****************************************************************/
985
986 uint8_t duSctpNtfyHdl(Buffer *mBuf, CmInetSctpNotification *ntfy)
987 {
988    if(f1Params.assocId == ntfy->u.assocChange.assocId)
989    {
990       if(BuildAndSendF1SetupReq() != ROK)
991       {
992          return RFAILED;
993       }
994    }
995    else if(ricParams.assocId == ntfy->u.assocChange.assocId)
996    {
997        return ROK;
998    }
999    else
1000    {
1001       DU_LOG("\nERROR  -->  DU_APP : Invalid assocId %d received", ntfy->u.assocChange.assocId);
1002       return RFAILED;
1003    }
1004    return ROK;
1005 }
1006
1007 /*******************************************************************
1008  *
1009  * @brief  Fills Pst struct for ENTEGTP
1010  *
1011  * @details
1012  *
1013  *    Function : duFillEgtpPst
1014  *
1015  *    Functionality:
1016  *       Fills Pst struct for ENTEGTP
1017  *
1018  * @params[in] 
1019  * @return ROK     - success
1020  *         RFAILED - failure
1021  *
1022  * ****************************************************************/
1023 uint8_t duFillEgtpPst(Pst *pst, Event event)
1024 {
1025    memset(pst, 0, sizeof(Pst));
1026    pst->srcEnt = (Ent)ENTDUAPP;
1027    pst->srcInst = (Inst)DU_INST;
1028    pst->srcProcId = DU_PROC;
1029    pst->dstEnt = (Ent)ENTEGTP;
1030    pst->dstInst = (Inst)EGTP_INST;
1031    pst->dstProcId = pst->srcProcId;
1032    pst->event = event;
1033    pst->selector = ODU_SELECTOR_LC;
1034    pst->pool= DU_POOL;
1035
1036    return ROK;
1037 }
1038
1039
1040 /*******************************************************************
1041  *
1042  * @brief  Function to configure EGTP
1043  *
1044  * @details
1045  *
1046  *    Function : duBuildEgtpCfgReq
1047  *
1048  *    Functionality:
1049  *       Function to configure EGTP
1050  *
1051  * @params[in] 
1052  * @return ROK     - success
1053  *         RFAILED - failure
1054  *
1055  * ****************************************************************/
1056
1057 uint8_t duBuildEgtpCfgReq()
1058 {
1059    Pst pst;
1060    EgtpConfig egtpCfg;
1061
1062    DU_LOG("\nDEBUG   -->  DU_APP : Sending EGTP config request");
1063
1064    memset(&egtpCfg, 0, sizeof(EgtpConfig));
1065    memcpy(&egtpCfg, &duCfgParam.egtpParams, sizeof(EgtpConfig));
1066
1067    duFillEgtpPst(&pst, EVTCFGREQ);
1068    packEgtpCfgReq(&pst, egtpCfg);
1069
1070    return ROK;
1071 }
1072
1073 /*******************************************************************
1074  *
1075  * @brief  Function to configure EGTP
1076  *
1077  * @details
1078  *
1079  *    Function : duBuildEgtpCfgReq
1080  *
1081  *    Functionality:
1082  *       Function to configure EGTP
1083  *
1084  * @params[in] 
1085  * @return ROK     - success
1086  *         RFAILED - failure
1087  *
1088  * ****************************************************************/
1089 uint8_t duHdlEgtpCfgComplete(CmStatus cfm)
1090 {
1091    uint8_t ret = ROK;
1092
1093    if(cfm.status == LCM_PRIM_OK)
1094    {
1095       DU_LOG("\nDEBUG   -->  DU_APP : EGTP configuraton complete");
1096       duSendEgtpSrvOpenReq();
1097    }
1098    else
1099    {
1100       DU_LOG("\nERROR  -->  DU_APP : EGTP configuraton failed");
1101       ret = RFAILED;
1102    }
1103
1104    return (ret);
1105 }
1106
1107 /*******************************************************************
1108  *
1109  * @brief  Sends server open request to EGTP
1110  *
1111  * @details
1112  *
1113  *    Function : duSendEgtpSrvOpenReq
1114  *
1115  *    Functionality:
1116  *       Sends server open request to EGTP
1117  *
1118  * @params[in] 
1119  * @return ROK     - success
1120  *         RFAILED - failure
1121  *
1122  * ****************************************************************/
1123
1124 uint8_t duSendEgtpSrvOpenReq()
1125 {
1126    Pst pst;
1127
1128    DU_LOG("\nDEBUG   -->  DU_APP : Sending EGTP server open request");
1129
1130    duFillEgtpPst(&pst, EVTSRVOPENREQ);
1131    packEgtpSrvOpenReq(&pst);
1132
1133    return ROK;
1134 }
1135
1136 /*******************************************************************
1137  *
1138  * @brief Handles server open confirmation
1139  *
1140  * @details
1141  *
1142  *    Function : duHdlEgtpSrvOpenComplete
1143  *
1144  *    Functionality:
1145  *        Handles server open confirmation
1146  *
1147  * @params[in] 
1148  * @return ROK     - success
1149  *         RFAILED - failure
1150  *
1151  *****************************************************************/
1152
1153 uint8_t duHdlEgtpSrvOpenComplete(CmStatus cfm)
1154 {
1155    uint8_t ret = ROK;
1156
1157    if(cfm.status == LCM_PRIM_OK)
1158    {
1159       DU_LOG("\nDEBUG   -->  DU_APP : EGTP server opened successfully");
1160    }
1161    else
1162    {
1163       DU_LOG("\nERROR  -->  DU_APP : EGTP server opening failed");
1164       ret = RFAILED;
1165    }
1166
1167    return (ret);
1168 }
1169
1170 /*******************************************************************
1171  *
1172  * @brief Sends tunnel management request
1173  *
1174  * @details
1175  *
1176  *    Function : duSendEgtpTnlMgmtReq 
1177  *
1178  *    Functionality:
1179  *        Builds and sends tunnel management request to EGTP
1180  *
1181  * @params[in] Action
1182  *             Local tunnel endpoint id
1183  *             Remote tunnel endpoint id 
1184  * @return ROK     - success
1185  *         RFAILED - failure
1186  *
1187  * ****************************************************************/
1188
1189 uint8_t duSendEgtpTnlMgmtReq(uint8_t action, uint32_t teIdTobeMod, GtpTnlCfg *ueCbTnlCfg)
1190 {
1191    uint8_t ret =ROK;
1192    Pst pst;
1193    EgtpTnlEvt tnlEvt;
1194
1195    DU_LOG("\nDEBUG   -->  DU_APP : Sending EGTP tunnel management request for teId [%d]", ueCbTnlCfg->teId);
1196
1197    /* ADD/MOD/DEL per tunnel */
1198    tnlEvt.action = action;
1199    tnlEvt.remTeid = ueCbTnlCfg->teId;
1200    if(action != EGTP_TNL_MGMT_ADD)
1201    {
1202       tnlEvt.lclTeid = teIdTobeMod;
1203    }
1204    else
1205    {
1206       tnlEvt.lclTeid = ueCbTnlCfg->teId;
1207    }
1208    duFillEgtpPst(&pst, EVTTNLMGMTREQ);
1209    ret = egtpTnlMgmtReq(&pst, tnlEvt);
1210    return ret;
1211 }
1212
1213 /*******************************************************************
1214  *
1215  * @brief Handles Tunnel management confirm 
1216  *
1217  * @details
1218  *
1219  *    Function : duHdlEgtpTnlMgmtCfm
1220  *
1221  *    Functionality:
1222  *      Handles tunnel management confirm received from Egtp
1223  *
1224  * @params[in] Tunnel Event  
1225  * @return ROK     - success
1226  *         RFAILED - failure
1227  *
1228  * ****************************************************************/
1229 uint8_t duHdlEgtpTnlMgmtCfm(EgtpTnlEvt tnlEvtCfm)
1230 {
1231    uint8_t ret = ROK;
1232
1233    if(tnlEvtCfm.cfmStatus.status == LCM_PRIM_OK)
1234    {
1235       DU_LOG("\nDEBUG  -->  DU_APP: Tunnel management confirm OK");
1236    }
1237    else
1238    {
1239       DU_LOG("\nERROR  -->  DU_APP: Tunnel management failed");
1240       ret = RFAILED;
1241    }
1242
1243    return (ret);
1244 }
1245
1246 /*******************************************************************
1247  *
1248  * @brief Sends UL user data over to EGTP
1249  *
1250  * @details
1251  *
1252  *    Function : duSendEgtpDatInd
1253  *
1254  *    Functionality: Sends UL user data over to EGTP
1255  *
1256  * @params[in] UL data buffer
1257  * @return ROK     - success
1258  *         RFAILED - failure
1259  *
1260  * ****************************************************************/
1261 uint8_t duSendEgtpDatInd(Buffer *mBuf)
1262 {
1263    EgtpMsg  egtpMsg;
1264
1265    /* Fill EGTP header */
1266    egtpMsg.msgHdr.msgType = EGTPU_MSG_GPDU;
1267    egtpMsg.msgHdr.nPdu.pres = FALSE;
1268    egtpMsg.msgHdr.seqNum.pres = FALSE;
1269    egtpMsg.msgHdr.extHdr.udpPort.pres = FALSE;
1270    egtpMsg.msgHdr.extHdr.pdcpNmb.pres = FALSE;
1271    egtpMsg.msgHdr.teId = 1;
1272    egtpMsg.msg = mBuf;
1273    
1274    egtpHdlDatInd(egtpMsg);
1275
1276    return ROK;
1277
1278 }
1279
1280 /**************************************************************************
1281  * @brief Function to send configs to SCH
1282  *
1283  * @details
1284  *
1285  *      Function : duSendSchCfg 
1286  * 
1287  *      Functionality:
1288  *           Sends general config to Scheduler via MAC layer
1289  *     
1290  * @param[in]  void
1291  * @return ROK     - success
1292  *         RFAILED - failure
1293  *
1294  ***************************************************************************/
1295 uint8_t duSendSchCfg()
1296 {
1297    RgMngmt       rgMngmt;
1298    RgSchInstCfg  *cfg = NULLP;
1299    Pst           pst;
1300
1301    DU_SET_ZERO(&pst, sizeof(Pst));
1302    DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
1303
1304    cfg = &(rgMngmt.t.cfg.s.schInstCfg);
1305
1306    /* Filling of Instance Id */
1307    cfg->instId = DEFAULT_CELLS + 1;
1308    /* Filling of Gen config */
1309    cfg->genCfg.mem.region = MAC_MEM_REGION;
1310    cfg->genCfg.mem.pool = MAC_POOL;
1311    cfg->genCfg.tmrRes = 1;
1312
1313 #ifdef LTE_ADV
1314    cfg->genCfg.forceCntrlSrbBoOnPCel = FALSE;
1315    cfg->genCfg.isSCellActDeactAlgoEnable = TRUE;
1316 #endif/*LTE_ADV*/
1317    cfg->genCfg.startCellId     = 1;
1318    cfg->genCfg.lmPst.dstProcId = DU_PROC;
1319    cfg->genCfg.lmPst.srcProcId = DU_PROC;
1320    cfg->genCfg.lmPst.dstEnt    = ENTDUAPP;
1321    cfg->genCfg.lmPst.dstInst   = DU_INST;
1322    cfg->genCfg.lmPst.srcEnt    = ENTMAC;
1323    cfg->genCfg.lmPst.srcInst   = DEFAULT_CELLS + 1;
1324    cfg->genCfg.lmPst.prior     = PRIOR0;
1325    cfg->genCfg.lmPst.route     = RTESPEC;
1326    cfg->genCfg.lmPst.region    = MAC_MEM_REGION;
1327    cfg->genCfg.lmPst.pool      = MAC_POOL;
1328    cfg->genCfg.lmPst.selector  = ODU_SELECTOR_LC;
1329
1330    /* Fill Header */
1331    rgMngmt.hdr.msgType             = TCFG;
1332    rgMngmt.hdr.entId.ent           = ENTMAC;
1333    rgMngmt.hdr.entId.inst          = DU_INST;
1334    rgMngmt.hdr.elmId.elmnt         = STSCHINST;
1335    rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
1336    rgMngmt.hdr.response.mem.pool   = MAC_POOL;
1337
1338    /* Fill Pst */
1339    pst.selector  = ODU_SELECTOR_LC;
1340    pst.srcEnt    = ENTDUAPP;
1341    pst.dstEnt    = ENTMAC;
1342    pst.dstProcId = DU_PROC;
1343    pst.srcProcId = DU_PROC;
1344    pst.srcInst   = DU_INST;
1345    pst.dstInst   = 0;
1346    pst.region    = duCb.init.region;
1347    pst.event    = (Event) EVTMACSCHGENCFGREQ;
1348
1349    DU_LOG("\nDEBUG   -->  DU_APP : MAC Sch Cfg sent");
1350
1351    /* Send the request to MAC */
1352    cmPkLrgSchCfgReq(&pst, &rgMngmt);
1353
1354    return ROK;
1355 }
1356
1357
1358 /**************************************************************************
1359  * @brief Function to configure SCTP params and 
1360  *  responsible for F1 and E2 interfaces
1361  *
1362  * @details
1363  *
1364  *      Function : duLayerConfigComplete
1365  * 
1366  *      Functionality:
1367  *           Configures SCTP Params and responsible for handling
1368  *           F1 and E2 interface.
1369  *     
1370  * @param[in]  void
1371  * @return ROK     - success
1372  *         RFAILED - failure
1373  *
1374  ***************************************************************************/
1375 uint8_t duLayerConfigComplete()
1376 {
1377    uint8_t ret = ROK;
1378
1379    DU_LOG("\nINFO   -->  DU_APP : Configuring all Layer is complete");
1380
1381    if((ret = duSctpCfgReq(duCfgParam.sctpParams)) != ROK)
1382    {
1383       DU_LOG("\nERROR  -->  DU_APP : Failed configuring Sctp Params");
1384       ret = RFAILED;
1385    }
1386    if((ret = duSctpAssocReq(F1_INTERFACE)) != ROK)
1387    {
1388       DU_LOG("\nERROR  -->  DU_APP : Failed to send AssocReq F1");
1389       ret = RFAILED;
1390    }
1391    if((ret = duSctpAssocReq(E2_INTERFACE)) != ROK)
1392    {
1393       DU_LOG("\nERROR  -->  DU_APP : Failed to send AssocReq E2");
1394       ret = RFAILED;
1395    }
1396
1397    return (ret); 
1398
1399
1400 /**************************************************************************
1401  * @brief Function to handle  SCH Config Confirm from MAC
1402  *
1403  * @details
1404  *
1405  *      Function : duHdlSchCfgComplete 
1406  * 
1407  *      Functionality:
1408  *           Handles Scheduler Gen Config Confirm from MAC
1409  *     
1410  * @param[in]  Pst     *pst, Post structure of the primitive.     
1411  * @param[in]  RgMngmt *cfm, Unpacked primitive info received from MAC
1412  * @return ROK     - success
1413  *         RFAILED - failure
1414  *
1415  ***************************************************************************/
1416 uint8_t duHdlSchCfgComplete(Pst *pst, RgMngmt *cfm)
1417 {
1418    if (cfm->cfm.status == LCM_PRIM_OK)
1419    {
1420       switch (cfm->hdr.elmId.elmnt)
1421       {
1422          case STSCHINST:
1423             {
1424                DU_LOG("\nDEBUG   -->  DU_APP : Received SCH CFG CFM at DU APP");
1425                break;
1426             }
1427          default:
1428             break;
1429       }
1430    }
1431    duLayerConfigComplete();
1432    duBuildEgtpCfgReq();
1433    return ROK;
1434 }
1435
1436 /**************************************************************************
1437  * @brief Function to fill and send MacCellconfig
1438  *
1439  * @details
1440  *
1441  *      Function : duBuildAndSendMacCellCfg 
1442  * 
1443  *      Functionality:
1444  *           Initiates MAC Configs towards MAC
1445  *     
1446  * @param[in]cell id
1447  * @return ROK     - success
1448  *         RFAILED - failure
1449  *
1450  ***************************************************************************/
1451 uint8_t duBuildAndSendMacCellCfg(uint16_t cellId)
1452 {
1453    Pst pst;
1454    MacCellCfg *duMacCellCfg = NULLP;
1455
1456    DU_ALLOC_SHRABL_BUF(duMacCellCfg, sizeof(MacCellCfg));
1457    if(duMacCellCfg == NULLP)
1458    {
1459       return RFAILED;
1460    }
1461
1462    /* store the address in the duCellCb so that we can free on confirm msg */
1463    if(duCb.actvCellLst[cellId-1])
1464       duCb.actvCellLst[cellId-1]->duMacCellCfg = duMacCellCfg;
1465    else
1466    {
1467       DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, duMacCellCfg, sizeof(MacCellCfg));
1468       return RFAILED;
1469    }
1470
1471    /* copy the mac config structure from duCfgParams */
1472    memcpy(duMacCellCfg,&duCfgParam.macCellCfg,sizeof(MacCellCfg));
1473
1474    /* Fill Pst */
1475    FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_CONFIG_REQ);
1476
1477    /* Send MAC cell config to MAC */
1478    return (*packMacCellCfgOpts[pst.selector])(&pst, duMacCellCfg);
1479 }
1480
1481 /**************************************************************************
1482  * @brief Function to Handle MAC cell config confirm
1483  *
1484  * @details
1485  *
1486  *      Function : duHandleMacCellCfgCfm 
1487  * 
1488  *      Functionality:
1489  *           Initiates general Configs towards MAC
1490  *     
1491  * @param[in] void
1492  * @return ROK     - success
1493  *         RFAILED - failure
1494  *
1495  ***************************************************************************/
1496 uint8_t  duHandleMacCellCfgCfm(Pst *pst, MacCellCfgCfm *macCellCfgCfm)
1497 {
1498    uint8_t  actvCellIdx  = 0;
1499    uint8_t  ret          = ROK;
1500
1501    for(actvCellIdx = 0; actvCellIdx < MAX_NUM_CELL; actvCellIdx++)
1502    {
1503       if((duCb.actvCellLst[actvCellIdx]) && (macCellCfgCfm->cellId == duCb.actvCellLst[actvCellIdx]->cellId))
1504       {
1505          duCb.actvCellLst[actvCellIdx]->duMacCellCfg = NULLP;
1506       }
1507    }
1508    if(macCellCfgCfm->rsp == ROK)
1509    {
1510       /* Build and send GNB-DU config update */
1511       ret = BuildAndSendDUConfigUpdate(SERV_CELL_TO_MODIFY);
1512
1513       /* Build and Send Cell Start Req to MAC */
1514       ret = duBuildAndSendMacCellStart();
1515    }
1516    else
1517    {
1518       /* TODO : Action to be taken if cell configuration fails. 
1519        * Should CU be informed? */
1520
1521       DU_LOG("\nERROR  -->  DU_APP : Mac cell cfg failed");
1522       ret = RFAILED;
1523    }
1524    return ret;
1525 }
1526
1527 /*******************************************************************
1528  *
1529  * @brief Builds and sends cell start request to MAC
1530  *
1531  * @details
1532  *
1533  *    Function : duBuildAndSendMacCellStart
1534  *
1535  *    Functionality:
1536  *       Builds and sends cell start request to MAC
1537  *
1538  * @params[in] 
1539  * @return ROK     - success
1540  *         RFAILED - failure
1541  *
1542  * ****************************************************************/
1543 uint8_t duBuildAndSendMacCellStart()
1544 {
1545    Pst pst;
1546    CellStartInfo *cellStart = NULL;
1547
1548    DU_LOG("\nINFO   -->  DU APP : Building and Sending cell start request to MAC");
1549
1550    /* Send Cell Start Request to MAC */
1551    DU_ALLOC_SHRABL_BUF(cellStart, sizeof(CellStartInfo));
1552    if(!cellStart)
1553    {
1554       DU_LOG("\nERROR  -->  DU APP : Memory alloc failed while building cell start request");
1555       return RFAILED;
1556    }
1557
1558    for(uint8_t id = 0; id < MAX_NUM_CELL; id++) 
1559    {
1560       if(duCb.actvCellLst[id])
1561       {
1562          cellStart->cellId = duCb.actvCellLst[id]->cellId;
1563
1564          /* Fill Pst */
1565          FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_START);
1566
1567          return (*packMacCellStartOpts[pst.selector])(&pst, cellStart);
1568       }
1569    }
1570    return ROK;
1571 }
1572
1573 /*******************************************************************
1574  *
1575  * @brief Builds and sends cell stop request to MAC
1576  *
1577  * @details
1578  *
1579  *    Function : duBuildAndSendMacCellStop 
1580  *
1581  *    Functionality:
1582  *       Builds and sends cell stop request to MAC
1583  *
1584  * @params[in] 
1585  * @return ROK     - success
1586  *         RFAILED - failure
1587  *
1588  * ****************************************************************/
1589 uint8_t duBuildAndSendMacCellStop(uint16_t cellId)
1590 {
1591    Pst pst;
1592    uint16_t cellIdx=0;
1593    CellStopInfo *cellStop = NULL;
1594
1595    DU_LOG("\nINFO   -->  DU APP : Building and Sending cell stop request to MAC");
1596
1597    GET_CELL_IDX(cellId, cellIdx);
1598    if(duCb.actvCellLst[cellIdx] != NULLP)
1599    {
1600       /* Send Cell Stop Request to MAC */
1601       DU_ALLOC_SHRABL_BUF(cellStop, sizeof(CellStopInfo));
1602       if(!cellStop)
1603       {
1604          DU_LOG("\nERROR  -->  DU APP : Memory alloc failed while building cell stop request");
1605          return RFAILED;
1606       }
1607       memset(cellStop, 0, sizeof(CellStopInfo));
1608       cellStop->cellId = duCb.actvCellLst[cellIdx]->cellId;
1609
1610       /* Fill Pst */
1611       FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_STOP);
1612
1613       return (*packMacCellStopOpts[pst.selector])(&pst, cellStop);
1614    }
1615    else
1616    {
1617       DU_LOG("\nERROR  -->  DU APP : duBuildAndSendMacCellStop(): cellId[%d] doesnot exists", cellId);
1618       return RFAILED;
1619    }
1620    return ROK;
1621 }
1622
1623 /*******************************************************************
1624  *
1625  * @brief Handles stop indication from MAC
1626  *
1627  * @details
1628  *
1629  *    Function : duHandleStopInd
1630  *
1631  *    Functionality:
1632  *      Handles stop indication from MAC
1633  *
1634  * @params[in] Post structure pointer
1635  * @return ROK     - success
1636  *         RFAILED - failure
1637  *
1638  * ****************************************************************/
1639 uint8_t duHandleStopInd(Pst *pst, OduCellId *cellId)
1640 {
1641    DuCellCb *cellCb = NULLP;
1642
1643    if(cellId->cellId <=0 || cellId->cellId > MAX_NUM_CELL)
1644    {
1645       DU_LOG("\nERROR  -->  DU APP : Invalid Cell Id %d in duHandleStopInd()", cellId->cellId);
1646    }
1647
1648    if(duGetCellCb(cellId->cellId, &cellCb) != ROK)
1649       return RFAILED;
1650
1651    if((cellCb->cellStatus == ACTIVATED) || (cellCb->cellStatus == DELETION_IN_PROGRESS))
1652    {
1653       DU_LOG("\nINFO   -->  DU APP : 5G-NR Cell %d is DOWN", cellId->cellId);
1654       if(sendCellDeleteReqToMac(cellId->cellId) == RFAILED)
1655       {
1656          DU_LOG("\nERROR  -->  DU APP : duHandleStopInd(): Failed to send Cell delete req to MAC for\
1657                cellId[%d]", cellId->cellId);
1658          return RFAILED;
1659       }
1660
1661
1662 #ifdef O1_ENABLE
1663       DU_LOG("\nINFO   -->  DU APP : Raise cell down alarm for cell id=%d", cellId->cellId);
1664       raiseCellAlrm(CELL_DOWN_ALARM_ID, cellId->cellId);
1665       setCellOpState(cellId->cellId, DISABLED, INACTIVE);
1666 #endif
1667    }
1668
1669    if((pst->selector == ODU_SELECTOR_LWLC) || (pst->selector == ODU_SELECTOR_TC))
1670       DU_FREE_SHRABL_BUF(MAC_MEM_REGION, pst->pool, cellId, sizeof(OduCellId));
1671
1672    cellCb->cellStatus = CELL_OUT_OF_SERVICE; //TODO: cell status must be set to OOS after all UE and cell cleanup which is not
1673                                              //supported now
1674
1675    return ROK;
1676 }
1677
1678 /*******************************************************************
1679  *
1680  * @brief Handles slot indication from MAC
1681  *
1682  * @details
1683  *
1684  *    Function : duHandleUlCcchInd
1685  *
1686  *    Functionality:
1687  *      Handles UL CCCH indication from MAC
1688  *
1689  * @params[in] Post structure pointer
1690  *             UL CCCH Ind pointer
1691  * @return ROK     - success
1692  *         RFAILED - failure
1693  *
1694  * ****************************************************************/
1695 uint8_t duHandleUlCcchInd(Pst *pst, UlCcchIndInfo *ulCcchIndInfo)
1696 {
1697
1698    DU_LOG("\nINFO  -->  DU APP : UL CCCH Indication received");
1699
1700    return (duProcUlCcchInd(ulCcchIndInfo));
1701 }
1702
1703 /*******************************************************************
1704  *
1705  * @brief Process UL RRC Message from RLC
1706  *
1707  * @details
1708  *
1709  *    Function : DuProcRlcUlRrcMsgTrans
1710  *
1711  *    Functionality: Process UL RRC Message from RLC
1712  *
1713  * @params[in] Post structure
1714  *             UL RRC Message Info
1715  * @return ROK     - success
1716  *         RFAILED - failure
1717  *
1718  * ****************************************************************/
1719 uint8_t DuProcRlcUlRrcMsgTrans(Pst *pst, RlcUlRrcMsgInfo *ulRrcMsgInfo)
1720 {
1721    uint8_t  ret = ROK;
1722    DuCellCb *cellCb = NULLP;
1723    DuUeCb   *ueCb = NULLP;
1724   
1725    duGetCellCb(ulRrcMsgInfo->cellId, &cellCb);
1726    if(cellCb)
1727    {
1728       if(ulRrcMsgInfo->ueId > 0)
1729       {
1730          if(cellCb->ueCb[ulRrcMsgInfo->ueId -1].gnbDuUeF1apId == ulRrcMsgInfo->ueId)
1731             ueCb = &cellCb->ueCb[ulRrcMsgInfo->ueId -1];
1732
1733          if(ueCb)
1734          {
1735             /* If UL message is received for a UE in handover, it signifies that UE is now
1736              * attached to GNB. Hence marking this UE as active and requesting MAC to 
1737              * release the dedicated RACH resources */
1738             if(ueCb->ueState == UE_HANDIN_IN_PROGRESS)
1739             {
1740                ueCb->ueState = UE_ACTIVE;
1741                cellCb->numActvUes++;
1742
1743                /* Release RACH resources */
1744                memset(&ueCb->cfraResource, 0, sizeof(MacCfraResource));
1745                if(duBuildAndSendRachRsrcRelToMac(ulRrcMsgInfo->cellId, ueCb) != ROK)
1746                {
1747                   DU_LOG("\nERROR  -->  DU_APP : DuProcRlcUlRrcMsgTrans() : Failed to send RACH resource release to MAC");
1748                }
1749             }
1750
1751             if(BuildAndSendULRRCMessageTransfer(ueCb, ulRrcMsgInfo->lcId, ulRrcMsgInfo->msgLen, ulRrcMsgInfo->rrcMsg) != ROK)
1752             {
1753                DU_LOG("\nERROR  -->  DU_APP : DuProcRlcUlRrcMsgTrans() : Failed to build and send UL RRC Message Transfer");
1754                ret = RFAILED;
1755             }
1756          }
1757          else
1758          {
1759             DU_LOG("\nERROR  -->  DU_APP : DuProcRlcUlRrcMsgTrans() : UE ID [%d] not found", ulRrcMsgInfo->ueId);
1760             ret = RFAILED;
1761          }
1762       }
1763       else
1764       {
1765          DU_LOG("\nERROR  -->  DU_APP : DuProcRlcUlRrcMsgTrans() : Invalid UE ID [%d]", ulRrcMsgInfo->ueId);
1766          ret = RFAILED;
1767       }
1768    }
1769    else
1770    {
1771       DU_LOG("\nERROR  -->  DU_APP : DuProcRlcUlRrcMsgTrans() : Cell ID [%d] not found", ulRrcMsgInfo->cellId);
1772       ret = RFAILED;
1773    }
1774
1775    DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulRrcMsgInfo->rrcMsg, ulRrcMsgInfo->msgLen);
1776    DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
1777    return ret;
1778 }
1779
1780 /*******************************************************************
1781 *
1782 * @brief Process RRC delivery report from RLC
1783 *
1784 * @details
1785 *
1786 *    Function : DuProcRlcRrcDeliveryReport
1787 *
1788 *    Functionality: Process RRC delivery Message from RLC
1789 *
1790 * @params[in] Post structure
1791 *             UL RRC Message Info
1792 * @return ROK     - success
1793 *         RFAILED - failure
1794 *
1795 * ****************************************************************/
1796 uint8_t DuProcRlcRrcDeliveryReport(Pst *pst, RrcDeliveryReport *rrcDeliveryReport)
1797 {
1798    DuCellCb *cellCb = NULLP;
1799    DuUeCb   ueCb;
1800    uint8_t  ret = RFAILED;
1801
1802    if(duGetCellCb(rrcDeliveryReport->cellId, &cellCb) != ROK)
1803       return RFAILED;
1804    
1805    ueCb = cellCb->ueCb[rrcDeliveryReport->ueId -1];
1806    ret = BuildAndSendRrcDeliveryReport(ueCb.gnbCuUeF1apId, ueCb.gnbDuUeF1apId,rrcDeliveryReport);
1807
1808    DU_FREE_SHRABL_BUF(pst->region, pst->pool, rrcDeliveryReport, sizeof(RrcDeliveryReport));
1809    return ret;
1810 }
1811
1812 /*******************************************************************
1813  *
1814  * @brief Process UL user data from RLC
1815  *
1816  * @details
1817  *
1818  *    Function : DuProcRlcUlUserDataTrans
1819  *
1820  *    Functionality: Process UL user data from RLC
1821  *
1822  * @params[in] Post structure
1823  *             UL user data
1824  * @return ROK     - success
1825  *         RFAILED - failure
1826  *
1827  * ****************************************************************/
1828 uint8_t DuProcRlcUlUserDataTrans(Pst *pst, RlcUlUserDatInfo *ulUserData)
1829 {
1830    uint8_t  teIdx = 0;
1831    EgtpMsg  egtpMsg;
1832    Buffer   *mBuf;
1833
1834    DU_LOG("\nDEBUG  -->  DU APP : Received UL user data");
1835
1836    /* Fill EGTP header */
1837    egtpMsg.msgHdr.msgType = EGTPU_MSG_GPDU;
1838    egtpMsg.msgHdr.nPdu.pres = FALSE;
1839    egtpMsg.msgHdr.seqNum.pres = FALSE;
1840    egtpMsg.msgHdr.extHdr.udpPort.pres = FALSE;
1841    egtpMsg.msgHdr.extHdr.pdcpNmb.pres = FALSE;
1842
1843    /* Fetch EGTP tunnel info */
1844    for(teIdx = 0; teIdx < duCb.numTeId; teIdx++)
1845    {
1846       /*TODO: If multiple Cell Support is enables then CellId also needs to be validated alongwith ueId and DrbId*/
1847       if((duCb.upTnlCfg[teIdx] != NULLP) && (duCb.upTnlCfg[teIdx]->ueId == ulUserData->ueId) && \
1848          (duCb.upTnlCfg[teIdx]->drbId == ulUserData->rbId))
1849       {
1850          if(duCb.upTnlCfg[teIdx]->tnlCfg1)
1851          {
1852             egtpMsg.msgHdr.teId = duCb.upTnlCfg[teIdx]->tnlCfg1->teId; /*As we are supporting only 1 tunnel per DRB*/
1853             break;
1854          }
1855       }
1856    }
1857
1858    if (ODU_GET_MSG_BUF(DU_APP_MEM_REGION, DU_POOL, &mBuf) != ROK)
1859    {
1860       DU_LOG("\nERROR  -->  DU APP : Failed to allocated buffer memory in DuProcRlcUlUserDataTrans");
1861       DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData->userData, ulUserData->msgLen);
1862       DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData, sizeof(RlcUlUserDatInfo));
1863       return RFAILED;
1864    }
1865    oduCpyFixBufToMsg(ulUserData->userData, mBuf, ulUserData->msgLen);
1866    ODU_PRINT_MSG(mBuf, 0, 0);
1867    egtpMsg.msg = mBuf;
1868    egtpHdlDatInd(egtpMsg);
1869
1870    DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData->userData, ulUserData->msgLen);
1871    DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData, sizeof(RlcUlUserDatInfo));
1872    return ROK;
1873 }
1874
1875 /*******************************************************************
1876  *
1877  * @brief process the slice cfg rsp received from MAC
1878  *
1879  * @details
1880  *
1881  *    Function : DuProcMacSliceCfgRsp
1882  *
1883  *    Functionality: process the slice cfg rsp received from MAC
1884  *
1885  * @params[in] Post structure, MacSliceCfgRsp  *cfgRsp
1886  *             
1887  * @return ROK     - success
1888  *         RFAILED - failure
1889  *
1890  **********************************************************************/
1891 uint8_t DuProcMacSliceCfgRsp(Pst *pst,  MacSliceCfgRsp *cfgRsp)
1892 {
1893     if(cfgRsp)
1894     {
1895        if(cfgRsp->rsp ==  MAC_DU_APP_RSP_OK)
1896        {
1897           duCb.sliceState = SLICE_CONFIGURED;
1898           DU_LOG("\nINFO  -->  DU_APP : Slice configured successfully ");
1899        }
1900        else
1901        {
1902           DU_LOG("\nERROR  -->  DU_APP : Slice not available");
1903        }
1904        DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, cfgRsp, sizeof(MacSliceCfgRsp));
1905     }
1906     return ROK;
1907 }
1908
1909 /*******************************************************************
1910  *
1911  * @brief Fill the slice configration and rrm policy related
1912  *    information received form O1
1913  *
1914  * @details
1915  *
1916  *    Function : BuildAndSendSliceConfigReq 
1917  *
1918  *    Functionality: Fill the slice configration and rrm policy related 
1919  *
1920  * @params[in] RrmPolicy *rrmPolicy[], uint8_t totalRrmPolicy, uint8_t
1921  * totalSliceCnt 
1922  *             
1923  * @return ROK     - success
1924  *         RFAILED - failure
1925  *
1926  * ****************************************************************/
1927 uint8_t BuildAndSendSliceConfigReq()
1928 {
1929    Pst pst;
1930    MacSliceCfgReq *sliceCfgReq;
1931
1932    DU_ALLOC_SHRABL_BUF(sliceCfgReq, sizeof(MacSliceCfgReq));
1933    if(sliceCfgReq == NULLP)
1934    {
1935       DU_LOG("\nERROR  -->  DU_APP : Memory allocation failed in BuildAndSendSliceConfigReq");
1936       return RFAILED;
1937    }
1938    else
1939    {
1940       memcpy(sliceCfgReq,  &duCfgParam.tempSliceCfg, sizeof(MacSliceCfgReq));
1941       FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_SLICE_CFG_REQ);
1942
1943       DU_LOG("\nDEBUG  -->  DU_APP : Sending Slice Cfg Request to MAC ");
1944       if((*packMacSliceCfgReqOpts[pst.selector])(&pst, sliceCfgReq) == RFAILED)
1945       {
1946          DU_LOG("\nERROR  -->  DU_APP : Failed to send Slice Cfg Req to MAC");
1947          DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, sliceCfgReq, sizeof(MacSliceCfgReq));
1948       }
1949    }
1950    return ROK;  
1951 }
1952
1953 /*******************************************************************
1954  *
1955  * @brief Fill the slice configration and rrm policy related
1956  *    information received form O1
1957  *
1958  * @details
1959  *
1960  *    Function : BuildAndSendSliceRecfgReq 
1961  *
1962  *    Functionality: Fill the slice configration and rrm policy related 
1963  *
1964  * @params[in] RrmPolicy rrmPolicy[], uint8_t totalSliceCount 
1965  *             
1966  * @return ROK     - success
1967  *         RFAILED - failure
1968  *
1969  * ****************************************************************/
1970 uint8_t BuildAndSendSliceRecfgReq()
1971 {
1972    Pst pst;
1973    MacSliceRecfgReq *sliceRecfgReq = NULLP;
1974    
1975    DU_LOG("\nINFO  --> DU_APP : Slice ReConfiguration Request received");
1976
1977    DU_ALLOC_SHRABL_BUF(sliceRecfgReq, sizeof(MacSliceRecfgReq));
1978    if(sliceRecfgReq == NULLP)
1979    {
1980       DU_LOG("\nERROR  -->  DU_APP : Memory allocation failed to BuildAndSendSliceRecfgReq");
1981       return RFAILED;
1982    }
1983    else
1984    {
1985       memcpy(sliceRecfgReq,  &duCfgParam.tempSliceCfg, sizeof(MacSliceRecfgReq));
1986       
1987       FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_SLICE_RECFG_REQ);
1988
1989       DU_LOG("\nDEBUG  -->  DU_APP: Sending Slice ReCfg Request to MAC ");
1990       if( (*packMacSliceRecfgReqOpts[pst.selector])(&pst, sliceRecfgReq) == RFAILED)
1991       {
1992          DU_LOG("\nERROR  -->  DU_APP: Failed to send Slice ReCfg Req to MAC");
1993          DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, sliceRecfgReq, sizeof(MacSliceRecfgReq));
1994       }
1995    }
1996    return ROK;  
1997 }
1998 /*******************************************************************
1999  *
2000  * @brief process the slice ReCfg rsp received from MAC
2001  *
2002  * @details
2003  *
2004  *    Function : DuProcMacSliceRecfgRsp
2005  *
2006  *    Functionality: process the slice ReCfg rsp received from MAC
2007  *
2008  * @params[in] Post structure, MacSliceRecfgRsp  *ReCfgRsp
2009  *             
2010  * @return ROK     - success
2011  *         RFAILED - failure
2012  *
2013  **********************************************************************/
2014 uint8_t DuProcMacSliceRecfgRsp(Pst *pst,  MacSliceRecfgRsp *recfgRsp)
2015 {
2016    if(recfgRsp)
2017    {
2018       if(recfgRsp->rsp == MAC_DU_APP_RSP_OK)
2019       {
2020          duCb.sliceState = SLICE_RECONFIGURED; 
2021           DU_LOG("\nINFO  -->  DU_APP : Slice Reconfigured successfully ");
2022       }
2023       else
2024       {
2025          DU_LOG("\nERROR  -->  DU_APP : Slice not available");
2026       }
2027       DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, recfgRsp, sizeof(MacSliceCfgRsp));
2028    }
2029    return ROK;
2030 }
2031
2032 /*******************************************************************
2033 *
2034 * @brief Handles received Slice Metrics from RLC and forward it to O1 
2035 *
2036 * @details
2037 *
2038 *    Function : DuProcRlcSliceMetrics
2039 *
2040 *    Functionality:
2041 *      Handles received Slice Metrics from RLC and forward it to O1
2042 *
2043 * @params[in] Post structure pointer
2044 *              SlicePmList *sliceStats
2045 *
2046 * @return ROK     - success
2047 *         RFAILED - failure
2048 *
2049 * ****************************************************************/
2050 uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats)
2051 {
2052     uint8_t sliceRecord = 0;
2053
2054     DU_LOG("\nDEBUG  -->  DU APP : Received Slice Metrics");
2055     if(sliceStats == NULLP)
2056     {
2057        DU_LOG("\nERROR  -->  DU APP : Empty Metrics");
2058        return RFAILED;
2059     }
2060     
2061     for(sliceRecord = 0; sliceRecord < sliceStats->numSlice; sliceRecord++)
2062     {
2063        DU_LOG("\nINFO   -->  DU_APP: SliceId[SST-SD]:%d-%d, DlTput %.5lf, UlTput:%.5lf", sliceStats->sliceRecord[sliceRecord].networkSliceIdentifier.sst,\
2064                         sliceStats->sliceRecord[sliceRecord].networkSliceIdentifier.sd,sliceStats->sliceRecord[sliceRecord].ThpDl,\
2065                         sliceStats->sliceRecord[sliceRecord].ThpUl);
2066     }
2067 #ifdef O1_ENABLE
2068     if(sliceStats)
2069     {
2070        sendSliceMetric((SliceMetricList*) sliceStats);
2071     }
2072 #endif
2073
2074    DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats->sliceRecord, (sliceStats->numSlice) * (sizeof(SlicePm)));
2075    DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats, sizeof(SlicePmList));
2076
2077    return ROK;
2078 }
2079
2080
2081 /*******************************************************************
2082  *
2083  * @brief Send Statistics request to MAC
2084  *
2085  * @details
2086  *
2087  *    Function : BuildAndSendStatsReqToMac()
2088  *
2089  *    Functionality: Send Statistics Request To Mac
2090  *
2091  * @params[in]
2092  *             
2093  * @return ROK     - success
2094  *         RFAILED - failure
2095  *
2096  * ****************************************************************/
2097 uint8_t BuildAndSendStatsReqToMac(uint64_t subscriptionId, RicSubscription *ricSubscriptionInfo)
2098 {
2099    Pst pst;
2100    uint8_t    actionIdx = 0, grpIdx = 0, statsIdx = 0;
2101    ActionInfo *actionDb = NULLP;
2102    ActionDefFormat1 *format1Action = NULLP;
2103    MacStatsReq *macStatsReq = NULLP;
2104
2105    /* Fill MAC statistics request */
2106    DU_ALLOC_SHRABL_BUF(macStatsReq, sizeof(MacStatsReq));
2107    if(macStatsReq == NULLP)
2108    {
2109       DU_LOG("\nERROR  -->  DU_APP : Memory allocation failed for macStatsReq in BuildAndSendStatsReqToMac");
2110       return RFAILED;
2111    }
2112
2113    macStatsReq->subscriptionId = subscriptionId;
2114    for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++)
2115    {
2116       if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
2117       {
2118          actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
2119          macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id;
2120          switch(actionDb->definition.formatType)
2121          {
2122             case 1:
2123                {
2124                   format1Action = &actionDb->definition.choice.format1;
2125                   macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod;
2126
2127                   CmLList *node = NULLP;
2128                   MeasurementInfo *measInfo = NULLP;
2129                   statsIdx = 0;
2130                   /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
2131                   node = cmLListFirst(&format1Action->measurementInfoList);
2132                   while(node)
2133                   {
2134                      measInfo = (MeasurementInfo *)(node->node);
2135                      switch(measInfo->measurementTypeId)
2136                      {
2137                         case 1:
2138                            {
2139                               macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE;
2140                               break;
2141                            }
2142                         case 2:
2143                            {
2144                               macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE;
2145                               break;
2146                            }
2147                         default:
2148                            {
2149                               DU_LOG("\nERROR  -->  DU_APP : Invalid measurement name BuildAndSendStatsReqToMac");
2150                               break;
2151                            }
2152                      }
2153                      node = node->next;
2154                   }
2155                   macStatsReq->statsGrpList[grpIdx].numStats = statsIdx;
2156                   break;
2157                }
2158             default:
2159                {
2160                   DU_LOG("\nERROR  -->  DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported");
2161                   break;
2162                }
2163          }
2164          if(macStatsReq->statsGrpList[grpIdx].numStats)
2165             grpIdx++;
2166       }
2167    }
2168    macStatsReq->numStatsGroup = grpIdx;
2169
2170    if(macStatsReq->numStatsGroup)
2171    {
2172       DU_LOG("\nDEBUG  -->  DU_APP: Sending Statistics Request to MAC ");
2173       FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_STATISTICS_REQ);
2174
2175       if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == ROK)
2176          return ROK;
2177
2178       DU_LOG("\nERROR  -->  DU_APP: Failed to send Statistics Request to MAC");
2179    }
2180
2181    DU_LOG("\nERROR  -->  DU_APP: No Statistics group found valid. Hence statistics request is not sent to MAC");
2182    DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq));
2183    return RFAILED;
2184 }
2185
2186 /*******************************************************************
2187  *
2188  * @brief Fetch statistics details from Action Definition Format 1
2189  *
2190  * @details
2191  *
2192  *    Function : FetchStatsFromActionDefFormat1()
2193  *
2194  *    Functionality: Fetch statistics details from Action 
2195  *       Definition Format 1 received in an E2 message from 
2196  *       RIC.
2197  *
2198  * @params[in] ActionDefFormat1
2199  *
2200  * @return Statistics
2201  *
2202  * ****************************************************************/
2203 Statistics FetchStatsFromActionDefFormat1(ActionDefFormat1 format1)
2204 {
2205    Statistics stats;
2206
2207    /* TODO : When E2AP subscription procedure is implemented:
2208     * Measurement info list is traveresed 
2209     * Based on KPI type, stats.macStatsReq or stats.rlcstatsReq is filled */
2210
2211    /* Hardcoding values for now for testing purpose 
2212     * Will be removed in next gerrit */
2213    stats.macStatsReq.subscriptionId = 1;
2214    stats.macStatsReq.numStatsGroup = 1;
2215    stats.macStatsReq.statsGrpList[0].groupId = 1;
2216    stats.macStatsReq.statsGrpList[0].periodicity = 100;
2217    stats.macStatsReq.statsGrpList[0].numStats = 2;
2218    stats.macStatsReq.statsGrpList[0].statsList[0] = MAC_DL_TOTAL_PRB_USAGE;
2219    stats.macStatsReq.statsGrpList[0].statsList[1] = MAC_UL_TOTAL_PRB_USAGE;
2220
2221    return stats;
2222 }
2223
2224 /*******************************************************************
2225  *
2226  * @brief Send Statistics request to DU layers
2227  *
2228  * @details
2229  *
2230  *    Function : BuildAndSendStatsReq()
2231  *
2232  *    Functionality: Check if there is an update in statistics 
2233  *       reporting configuration. If so, send the update to 
2234  *       respective layer.
2235  *
2236  * @params[in] Subscription Info
2237  *             
2238  * @return ROK     - success
2239  *         RFAILED - failure
2240  *
2241  * ****************************************************************/
2242 uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo)
2243 {
2244    uint64_t   subscriptionId = 0; 
2245
2246    /* Calculate 64 bit subscription-ID :
2247     *  First 16 MSB is unused
2248     *  Next 16 MSB = RAN-Function-ID
2249     *  Next 16 MSB = Requestor-ID in RIC-Request-ID
2250     *  Last 16 LSB = Instance-ID in RIC-Request-ID
2251     */
2252    subscriptionId = ricSubscriptionInfo->requestId.instanceId;
2253    subscriptionId |= ((uint64_t)ricSubscriptionInfo->requestId.requestorId << 16);
2254    subscriptionId |= ((uint64_t)ranFuncId << 32);
2255
2256    /* Build and sent subscription information to MAC in Statistics Request */
2257    if(BuildAndSendStatsReqToMac(subscriptionId, ricSubscriptionInfo) != ROK)
2258    {
2259       DU_LOG("\nERROR  -->  DU_APP : Failed at BuildAndSendStatsReqToMac()");
2260       return RFAILED;   
2261    }
2262
2263 /* TODO : When KPI collection from RLC will be supported, this function will be 
2264  * called to configure KPIs to be colled */
2265 #if 0
2266    if(BuildAndSendStatsReqToRlc() != ROK)
2267    {
2268       DU_LOG("\nERROR  -->  DU_APP : Failed at BuildAndSendStatsReqToRlc()");
2269       return RFAILED;
2270    }
2271 #endif
2272
2273    return ROK;
2274 }
2275
2276 /*******************************************************************
2277  *
2278  * @brief Converts DU specific failure cause to E2 interface
2279  *        failure cause
2280  *
2281  * @details
2282  *
2283  *    Function : convertDuCauseToE2Cause
2284  *
2285  *    Functionality: Converts DU specific failure cause to E2 
2286  *       interface failure cause
2287  *
2288  * @params[in] DU specific failure cause
2289  *             E2 specific failure cause
2290  *
2291  * @return void
2292  *
2293  * ****************************************************************/
2294 void convertDuCauseToE2Cause(CauseOfResult l2Cause, E2FailureCause *failureCause)
2295 {
2296    switch(l2Cause)
2297    {
2298       case PARAM_INVALID:
2299          {
2300             failureCause->causeType = E2_RIC_REQUEST;
2301             failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2302             break;
2303          }
2304       case RESOURCE_UNAVAILABLE:
2305          {
2306             failureCause->causeType = E2_RIC_REQUEST;
2307             failureCause->cause = E2_FUNCTION_RESOURCE_LIMIT;
2308             break;
2309          }
2310       default:
2311          {
2312             failureCause->causeType = E2_RIC_REQUEST;
2313             failureCause->cause = E2_RIC_REQUEST_CAUSE_UNSPECIFIED;
2314             break;
2315          }
2316    }
2317 }
2318
2319 /*******************************************************************
2320  *
2321  * @brief Rejects all actions received in a subscription request
2322  *
2323  * @details
2324  *
2325  *    Function : duRejectAllStatsGroup
2326  *
2327  *    Functionality: Rejects all actions received in a subscription
2328  *       request by :
2329  *       a. Removing the subscription entry from RAN function
2330  *       b. Sending RIC Subscription Failure to RIC with appropriate
2331  *          cause of failure
2332  *
2333  * @params[in] RAN Function DB
2334  *             Subscription entry in RAN Function subscription list
2335  *             Statistics Response from MAC
2336  *
2337  * @return ROK     - success
2338  *         RFAILED - failure
2339  *
2340  * ****************************************************************/
2341 uint8_t duRejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode, MacStatsRsp *statsRsp)
2342 {
2343    uint8_t ret = ROK;
2344    RicRequestId  requestId;
2345    E2FailureCause failureCause;
2346
2347    /* Delete subcription from RAN Function */
2348    memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId));
2349    cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2350    DU_FREE(ricSubscriptionNode->node, sizeof(RicSubscription));
2351    DU_FREE(ricSubscriptionNode, sizeof(CmLList));
2352
2353    convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause);
2354
2355    /* Send RIC subscription failure to RIC */
2356    ret = BuildAndSendRicSubscriptionFailure(requestId, ranFuncDb->id, failureCause);
2357    return ret;
2358 }
2359
2360 /*******************************************************************
2361  *
2362  * @brief Process statistics response from MAC
2363  *
2364  * @details
2365  *
2366  *    Function : DuProcMacStatsRsp
2367  *
2368  *    Functionality: Processes statistics configuration response
2369  *       from MAC. If configuration is succsessful, DUAPP starts
2370  *       reporting period timer for this subscription request 
2371  *       from RIC
2372  *
2373  * @params[in]
2374  *
2375  * @return ROK     - success
2376  *         RFAILED - failure
2377  *
2378  * ****************************************************************/
2379 uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp)
2380 {
2381    uint16_t ranFuncId = 0;
2382    RicRequestId ricReqId;
2383    RanFunction *ranFuncDb = NULLP;
2384    CmLList *ricSubscriptionNode = NULLP;
2385    RicSubscription *ricSubscriptionInfo = NULLP;
2386
2387    DU_LOG("\nINFO  -->  DU_APP : DuProcMacStatsRsp: Received Statistics Response from MAC");
2388
2389    if(statsRsp)
2390    {
2391 #ifdef DEBUG_PRINT   
2392       uint8_t idx = 0;
2393       DU_LOG("\n  Subscription Id [%ld]", statsRsp->subscriptionId);
2394
2395       DU_LOG("\n  Number of Accepted Groups [%d]", statsRsp->numGrpAccepted);
2396       for(idx=0; idx<statsRsp->numGrpAccepted; idx++)
2397       {
2398          DU_LOG("\n    Group Id [%d]", statsRsp->statsGrpAcceptedList[idx]);
2399       }
2400
2401       DU_LOG("\n  Number of Rejected Groups [%d]", statsRsp->numGrpRejected);
2402       for(idx=0; idx<statsRsp->numGrpRejected; idx++)
2403       {
2404          DU_LOG("\n    Group Id [%d]", statsRsp->statsGrpRejectedList[idx]);
2405       }
2406 #endif      
2407
2408       /* Extract following from 64 bit subscription-ID :
2409        *  First 16 MSB is unused
2410        *  Next 16 MSB = RAN-Function-ID
2411        *  Next 16 MSB = Requestor-ID in RIC-Request-ID
2412        *  Last 16 LSB = Instance-ID in RIC-Request-ID
2413        */
2414       ricReqId.instanceId = statsRsp->subscriptionId & 0xFFFF;
2415       ricReqId.requestorId = (statsRsp->subscriptionId >> 16) & 0xFFFF;
2416       ranFuncId = (statsRsp->subscriptionId >> 32) & 0xFFFF;
2417
2418       /* Fetch RAN Function DB */
2419       if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
2420       {
2421          ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
2422       }
2423       else
2424       {
2425          DU_LOG("\nERROR  -->  DU_APP : DuProcMacStatsRsp: Invalid RAN Function ID[%d]  with Subscription ID [%ld]", \
2426             ranFuncId, statsRsp->subscriptionId);
2427          DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
2428          return RFAILED;
2429       }
2430
2431       /* Fetch subscription detail in RAN Function DB */
2432       CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2433       while(ricSubscriptionNode)
2434       {
2435          ricSubscriptionInfo = (RicSubscription *)ricSubscriptionNode->node;
2436          if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) &&
2437             (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
2438          {
2439             break;
2440          }
2441          ricSubscriptionNode = ricSubscriptionNode->next;
2442       }
2443
2444       if(ricSubscriptionNode == NULLP)
2445       {
2446          DU_LOG("\nERROR  -->  DU_APP : DuProcMacStatsRsp: Subscription not found for Requestor ID [%d] Instance ID [%d]",\
2447             ricReqId.requestorId, ricReqId.instanceId);
2448          DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
2449          return RFAILED;
2450       }
2451
2452       /* If no action is accepted
2453        *  a. Remove subcription entry from RAN Function
2454        *  b. Send RIC subscription failure */
2455       if(statsRsp->numGrpAccepted == 0)
2456       {
2457          duRejectAllStatsGroup(ranFuncDb, ricSubscriptionNode, statsRsp);
2458       }
2459
2460       /* TODO :
2461        * If even 1 action is accepted :
2462        *
2463        * For accepted groups:
2464        *    Mark scubscrbed-action's -> action = CONFIG_UNKNOWN
2465        *    Add action ID to accpeted-action-list in Subscription response
2466        *
2467        * For rejected groups:
2468        *    Remove entry from DU's RAN Function->subscription->actionList
2469        *    Add Rejected action Id to reject-action-list created by DU APP while
2470        *     processing of subscription request.
2471        *
2472        * Send subscription response with accepted and rejected action lists to
2473        * RIC
2474        */
2475
2476       DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
2477       return ROK;
2478    }
2479
2480    DU_LOG("\nERROR  -->  DU_APP : DuProcMacStatsRsp: Received NULL Pointer");
2481    return RFAILED;
2482 }
2483
2484 /*******************************************************************
2485  *
2486  * @brief Process statistics indication from MAC
2487  *
2488  * @details
2489  *
2490  *    Function : DuProcMacStatsInd
2491  *
2492  *    Functionality: Processes statistics indication from MAC.
2493  *
2494  * @params[in]
2495  *
2496  * @return ROK     - success
2497  *         RFAILED - failure
2498  *
2499  * ****************************************************************/
2500 uint8_t DuProcMacStatsInd(Pst *pst, MacStatsInd *statsInd)
2501 {
2502    if(statsInd)
2503    {
2504 #ifdef DEBUG_PRINT   
2505       DU_LOG("\nDEBUG  -->  DU_APP : DuProcMacStatsInd: Received Statistics Indication");
2506       DU_LOG("\n  Subscription Id [%ld]", statsInd->subscriptionId);
2507       DU_LOG("\n  Group Id [%d]", statsInd->groupId);
2508       for(int idx = 0; idx < statsInd->numStats; idx++)
2509       {
2510          DU_LOG("\n  Meas type [%d] Meas Value [%lf]", statsInd->measuredStatsList[idx].type,\
2511             statsInd->measuredStatsList[idx].value);
2512       }
2513 #endif      
2514
2515       /* TODO : When stats indication is received
2516        * DU APP searches for the message type in E2AP RIC subscription database
2517        * and stores in the value in the list of subscribed measurements
2518        *
2519        * This will be implemented in next gerrit.
2520        */
2521
2522       DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsInd, sizeof(MacStatsInd));
2523       return ROK;
2524    }
2525    
2526    DU_LOG("\nINFO  -->  DU_APP : DuProcMacStatsInd: Received NULL Pointer");
2527    return RFAILED;
2528 }
2529
2530 /**********************************************************************
2531   End of file
2532  **********************************************************************/