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