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