1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /* This file contains message handling functionality for DU APP */
20 #include "common_def.h"
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"
34 #include "du_app_rlc_inf.h"
38 #include "du_f1ap_msg_hdl.h"
39 #include "du_ue_mgr.h"
43 #include "du_cell_mgr.h"
47 #include "AlarmInterface.h"
48 #include "CmInterface.h"
49 #include "PmInterface.h"
54 uint8_t numRlcDlSaps = 0;
56 uint8_t numRlcMacSaps = 0;
58 uint8_t macCfgInst = 0;
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);
70 packMacCellCfgReq packMacCellCfgOpts[] =
72 packMacCellCfg, /* packing for loosely coupled */
73 MacProcCellCfgReq, /* packing for tightly coupled */
74 packMacCellCfg, /* packing for light weight loosly coupled */
77 DuMacCellStart packMacCellStartOpts[] =
79 packMacCellStart, /* Loose coupling */
80 MacProcCellStart, /* TIght coupling */
81 packMacCellStart /* Light weight-loose coupling */
84 DuMacCellStop packMacCellStopOpts[] =
86 packMacCellStop, /* Loose coupling */
87 MacProcCellStop, /* TIght coupling */
88 packMacCellStop /* Light weight-loose coupling */
91 DuMacSliceCfgReq packMacSliceCfgReqOpts[] =
93 packDuMacSliceCfgReq, /* Loose coupling */
94 MacProcSliceCfgReq, /* TIght coupling */
95 packDuMacSliceCfgReq /* Light weight-loose coupling */
99 DuMacSliceRecfgReq packMacSliceRecfgReqOpts[] =
101 packDuMacSliceRecfgReq, /* Loose coupling */
102 MacProcSliceRecfgReq, /* TIght coupling */
103 packDuMacSliceRecfgReq /* Light weight-loose coupling */
106 DuMacStatsReqFunc packMacStatsReqOpts[]=
108 packDuMacStatsReq, /* Loose Coupling */
109 MacProcStatsReq, /* Tight Coupling */
110 packDuMacStatsReq /* Light weight-loose coupling */
113 /**************************************************************************
114 * @brief Function to fill configs required by RLC
118 * Function : duBuildRlcCfg
121 * Initiates general Configs towards RLC
123 * @param[in] Inst Specifies if RLC UL or RLC DL instance
124 * @return ROK - success
127 ***************************************************************************/
128 uint8_t duBuildRlcCfg(Inst inst)
131 RlcGenCfg *genCfg = NULLP;
134 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
135 DU_SET_ZERO(&pst, sizeof(Pst));
137 genCfg = &(rlcMngmt.t.cfg.s.gen);
139 /*----------- Fill General Configuration Parameters ---------*/
140 genCfg->maxUe = duCfgParam.maxUe;
141 genCfg->maxKwuSaps = 2;
142 genCfg->maxUdxSaps = 1;
143 genCfg->rlcMode = (inst == RLC_UL_INST) ?
144 LKW_RLC_MODE_UL : LKW_RLC_MODE_DL;
146 genCfg->maxRguSaps = DEFAULT_CELLS;
148 /*----------- Fill lmPst
149 * Parameters ---------*/
150 genCfg->lmPst.dstProcId = DU_PROC;
151 genCfg->lmPst.srcProcId = DU_PROC;
152 genCfg->lmPst.dstEnt = ENTDUAPP;
153 genCfg->lmPst.dstInst = DU_INST;
154 genCfg->lmPst.srcEnt = ENTRLC;
155 genCfg->lmPst.srcInst = inst;
156 genCfg->lmPst.prior = PRIOR0;
157 genCfg->lmPst.route = RTESPEC;
158 genCfg->lmPst.region = (inst == RLC_UL_INST) ?
159 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
160 genCfg->lmPst.pool = RLC_POOL;
161 genCfg->lmPst.selector = ODU_SELECTOR_LC;
164 rlcMngmt.hdr.msgType = TCFG;
165 rlcMngmt.hdr.msgLen = 0;
166 rlcMngmt.hdr.entId.ent = ENTRLC;
167 rlcMngmt.hdr.entId.inst = (Inst)0;
168 rlcMngmt.hdr.elmId.elmnt = STGEN;
169 rlcMngmt.hdr.seqNmb = 0;
170 rlcMngmt.hdr.version = 0;
171 rlcMngmt.hdr.transId = 0;
172 rlcMngmt.hdr.response.prior = PRIOR0;
173 rlcMngmt.hdr.response.route = RTESPEC;
174 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
175 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
176 rlcMngmt.hdr.response.mem.pool = DU_POOL;
177 rlcMngmt.hdr.response.selector = ODU_SELECTOR_LC;
180 pst.selector = ODU_SELECTOR_LC;
181 pst.srcEnt = ENTDUAPP;
184 pst.dstProcId = DU_PROC;
185 pst.srcProcId = DU_PROC;
186 pst.region = duCb.init.region;
188 DU_LOG("\nDEBUG --> DU_APP : RLC Gen Cfg Req sent for inst %d", inst);
190 /* Send the request to RLC */
191 packRlcConfigReq(&pst, &rlcMngmt);
196 /**************************************************************************
197 * @brief Function to fill configs required by RLC
201 * Function : duBuildRlcLsapCfg
204 * Initiates general Configs towards RLC
206 * @param[in] Inst Specifies if RLC UL or RLC DL instance
207 * @return ROK - success
210 ***************************************************************************/
211 uint8_t duBuildRlcLsapCfg(Ent ent, Inst inst, uint8_t lsapInst)
215 RlcSapCfg *lSap = NULLP;
218 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
219 DU_SET_ZERO(&pst, sizeof(Pst));
222 rlcMngmt.hdr.msgType = TCFG;
223 rlcMngmt.hdr.entId.ent = ENTRLC;
224 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
225 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
227 rlcMngmt.hdr.response.mem.pool = RLC_POOL;
230 pst.selector = ODU_SELECTOR_LC;
231 pst.srcEnt = ENTDUAPP;
233 pst.dstProcId = DU_PROC;
235 pst.srcProcId = DU_PROC;
236 pst.region = duCb.init.region;
237 lSap = &(rlcMngmt.t.cfg.s.sap);
239 lSap->mem.region = (inst == RLC_UL_INST) ?
240 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
241 lSap->mem.pool = RLC_POOL;
243 lSap->bndTmrIntvl = 10;
244 lSap->priority = PRIOR0;
245 lSap->route = RTESPEC;
248 lSap->procId = DU_PROC;
250 lSap->inst = lsapInst;
251 lSap->sapId = lsapInst; /* SapId will be stored as suId in MAC */
252 lSap->selector = (inst == RLC_UL_INST) ? ODU_SELECTOR_LWLC : ODU_SELECTOR_TC;
253 rlcMngmt.hdr.elmId.elmnt = STRGUSAP;
254 DU_LOG("\nDEBUG --> DU_APP : RLC MAC Lower Sap Cfg Req sent for inst %d", inst);
259 lSap->procId = DU_PROC;
261 lSap->inst = (inst == RLC_UL_INST) ?
262 RLC_DL_INST : RLC_UL_INST;
264 lSap->selector = ODU_SELECTOR_LC;
265 rlcMngmt.hdr.elmId.elmnt = STUDXSAP;
266 DU_LOG("\nDEBUG --> DU_APP : RLC DL/UL Lower Sap Cfg Req sent for inst %d", inst);
269 packRlcConfigReq(&pst, &rlcMngmt);
273 /**************************************************************************
274 * @brief Function to fill configs required by RLC
278 * Function : duBuildRlcUsapCfg
281 * Initiates general Configs towards RLC
283 * @param[in] Inst Specifies if RLC UL or RLC DL instance
284 * @return ROK - success
287 ***************************************************************************/
288 uint8_t duBuildRlcUsapCfg(uint8_t elemId, Ent ent, Inst inst)
291 RlcSapCfg *uSap = NULLP;
294 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
295 DU_SET_ZERO(&pst, sizeof(Pst));
297 uSap = &(rlcMngmt.t.cfg.s.sap);
299 uSap->selector = ODU_SELECTOR_LC;
300 uSap->mem.region = (inst == RLC_UL_INST) ?
301 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
302 uSap->mem.pool = RLC_POOL;
305 uSap->procId = DU_PROC;
309 uSap->inst = (inst == RLC_UL_INST) ?
310 RLC_DL_INST : RLC_UL_INST;
311 uSap->bndTmrIntvl = 1000;
312 uSap->priority = PRIOR0;
313 uSap->route = RTESPEC;
316 rlcMngmt.hdr.msgType = TCFG;
317 rlcMngmt.hdr.entId.ent = ENTRLC;
318 rlcMngmt.hdr.elmId.elmnt = STUDXSAP;
319 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
320 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
322 rlcMngmt.hdr.response.mem.pool = RLC_POOL;
325 pst.selector = ODU_SELECTOR_LC;
326 pst.srcEnt = ENTDUAPP;
328 pst.dstProcId = DU_PROC;
330 pst.srcProcId = DU_PROC;
331 pst.region = duCb.init.region;
333 DU_LOG("\nDEBUG --> DU_APP : RLC Kwu Upper Sap Cfg Req sent for inst %d", inst);
334 packRlcConfigReq(&pst, &rlcMngmt);
339 /**************************************************************************
340 * @brief Function to populate internal DS of DU APP
344 * Function : duProcCfgComplete
347 * Populates internal data structures of DU APP after
348 * receiving configurations.
351 * @return ROK - success
354 ***************************************************************************/
355 uint8_t duProcCfgComplete()
359 for(idx=0; idx< DEFAULT_CELLS; idx++)
361 DuCellCb *cell = NULLP;
362 DU_ALLOC(cell, sizeof(DuCellCb));
365 DU_LOG("\nERROR --> DU_APP : Memory Allocation failed in duProcCfgComplete");
371 memset(cell, 0, sizeof(DuCellCb));
372 cell->cellId = NR_CELL_ID; //++cellId;
373 memset(&cell->cellInfo.nrEcgi.plmn, 0, sizeof(Plmn));
374 cell->cellInfo.nrEcgi.plmn.mcc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[0];
375 cell->cellInfo.nrEcgi.plmn.mcc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[1];
376 cell->cellInfo.nrEcgi.plmn.mcc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[2];
377 cell->cellInfo.nrEcgi.plmn.mnc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[0];
378 cell->cellInfo.nrEcgi.plmn.mnc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[1];
379 cell->cellInfo.nrEcgi.plmn.mnc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[2];
380 cell->cellInfo.nrEcgi.cellId = cell->cellId;
381 cell->cellInfo.nrPci = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrPci;
382 cell->cellInfo.fiveGsTac = duCfgParam.srvdCellLst[0].duCellInfo.tac;
383 memset(&cell->cellInfo.plmn[idx1], 0, sizeof(Plmn));
384 for(idx1=0; idx1<MAX_PLMN; idx1++)
386 cell->cellInfo.plmn[idx1].mcc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[0];
387 cell->cellInfo.plmn[idx1].mcc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[1];
388 cell->cellInfo.plmn[idx1].mcc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[2];
389 cell->cellInfo.plmn[idx1].mnc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[0];
390 cell->cellInfo.plmn[idx1].mnc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[1];
391 cell->cellInfo.plmn[idx1].mnc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[2];
393 cell->cellInfo.maxUe = duCfgParam.maxUe;
394 cell->cellStatus = CELL_OUT_OF_SERVICE;
395 gCellStatus = CELL_DOWN;
396 duCb.cfgCellLst[duCb.numCfgCells] = cell;
402 //Start layer configs
403 ret = duSendRlcUlCfg();
407 /**************************************************************************
408 * @brief Function to invoke DU Layer Configs
412 * Function : duSendRlcUlCfg
415 * Initiates Configs towards layers of DU
418 * @return ROK - success
421 ***************************************************************************/
422 uint8_t duSendRlcUlCfg()
426 duBuildRlcCfg((Inst)RLC_UL_INST);
427 for(cellIdx = 0; cellIdx < DEFAULT_CELLS; cellIdx++)
429 duBuildRlcLsapCfg(ENTMAC, (Inst)RLC_UL_INST, cellIdx);
431 duBuildRlcLsapCfg(ENTRLC, (Inst)RLC_UL_INST, 0);
436 /**************************************************************************
437 * @brief Function to invoke DU Layer Configs
441 * Function : duSendRlcDlCfg
444 * Initiates Configs towards layers of DU
447 * @return ROK - success
450 ***************************************************************************/
451 uint8_t duSendRlcDlCfg()
455 duBuildRlcCfg((Inst)RLC_DL_INST);
456 duBuildRlcUsapCfg(STUDXSAP, ENTRLC, (Inst)RLC_DL_INST);
457 for(cellIdx = 0; cellIdx < DEFAULT_CELLS; cellIdx++)
459 duBuildRlcLsapCfg(ENTMAC, (Inst)RLC_DL_INST, cellIdx);
464 /**************************************************************************
465 * @brief Function to handle Config Confirm from RLC
469 * Function : DuHdlRlcCfgComplete
472 * Handles Gen Config Confirm from RLC
474 * @param[in] Pst *pst, Post structure of the primitive.
475 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC
476 * @return ROK - success
479 ***************************************************************************/
480 uint8_t DuHdlRlcCfgComplete(Pst *pst, RlcMngmt *cfm)
483 if (pst->srcInst == RLC_UL_INST)
485 ret = duProcRlcUlCfgComplete(pst, cfm);
489 ret = duProcRlcDlCfgComplete(pst, cfm);
494 /**************************************************************************
495 * @brief Function to handle Control Config Confirm from RLC
499 * Function : duHdlRlcCntrlCfgComplete
502 * Handles Control Config Confirm from RLC
504 * @param[in] Pst *pst, Post structure of the primitive.
505 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC
506 * @return ROK - success
509 ***************************************************************************/
510 uint8_t duHdlRlcCntrlCfgComplete(Pst *pst, RlcMngmt *cntrl)
514 if (cntrl->cfm.status == LCM_PRIM_OK)
516 switch (cntrl->hdr.elmId.elmnt)
520 if (pst->srcInst == RLC_DL_INST)
522 DU_LOG("\nDEBUG --> DU_APP : BIND OF RLC DL TO MAC (RGU) SAP SUCCESSFUL");
524 if(macCfgInst < DEFAULT_CELLS)
527 duBindUnbindRlcToMacSap((Inst) RLC_DL_INST, ABND);
531 duBindUnbindRlcToMacSap((Inst) RLC_UL_INST, ABND);
536 DU_LOG("\nDEBUG --> DU_APP : BIND OF RLC UL TO MAC (RGU) SAP SUCCESSFUL");
538 if(macCfgInst < DEFAULT_CELLS)
540 duBindUnbindRlcToMacSap((Inst) RLC_UL_INST, ABND);
554 /**************************************************************************
555 * @brief Function to handle Config Confirm from RLC UL
559 * Function : duHdlRlcUlCfgComplete
562 * Handles Config Confirm from RLC UL
564 * @param[in] Pst *pst, Post structure of the primitive.
565 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC UL
566 * @return ROK - success
569 ***************************************************************************/
570 uint8_t duProcRlcUlCfgComplete(Pst *pst, RlcMngmt *cfm)
574 DU_LOG("\nDEBUG --> DU_APP : RLC UL Cfg Status %d", cfm->cfm.status);
575 if (cfm->cfm.status == LCM_PRIM_OK)
577 switch(cfm->hdr.elmId.elmnt)
581 rlcUlCfg |= RLC_GEN_CFG;
587 if(numRlcMacSaps == DEFAULT_CELLS)
589 rlcUlCfg |= RLC_MAC_SAP_CFG;
596 rlcUlCfg |= RLC_UDX_SAP_CFG;
603 DU_LOG("\nDEBUG --> DU_APP : RLC UL Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
604 if(rlcUlCfg == DU_RLC_UL_CONFIGURED)
608 //Start configuration of RLC DL
615 DU_LOG("\nERROR --> DU_APP : Config confirm NOK from RLC UL");
621 /**************************************************************************
622 * @brief Function to handle Config Confirm from RLC DL
626 * Function : duHdlRlcDlCfgComplete
629 * Handles Config Confirm from RLC DL
631 * @param[in] Pst *pst, Post structure of the primitive.
632 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC DL
633 * @return ROK - success
636 ***************************************************************************/
637 uint8_t duProcRlcDlCfgComplete(Pst *pst, RlcMngmt *cfm)
639 DU_LOG("\nDEBUG --> DU_APP : RLC DL Cfg Status %d", cfm->cfm.status);
640 if (cfm->cfm.status == LCM_PRIM_OK)
642 switch(cfm->hdr.elmId.elmnt)
646 rlcDlCfg |= RLC_GEN_CFG;
652 if(numRlcMacSaps == DEFAULT_CELLS)
654 rlcDlCfg |= RLC_MAC_SAP_CFG;
661 rlcDlCfg |= RLC_UDX_SAP_CFG;
669 DU_LOG("\nDEBUG --> DU_APP : RLC DL Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
670 if(rlcDlCfg == DU_RLC_DL_CONFIGURED)
673 //Start configuration of MAC
680 DU_LOG("\nERROR --> DU_APP : Config confirm NOK from RLC DL");
685 /**************************************************************************
686 * @brief Function to send configs to MAC
690 * Function : duSendMacCfg
693 * Initiates Configs towards MAC layer
696 * @return ROK - success
699 ***************************************************************************/
700 uint8_t duSendMacCfg()
703 duBuildMacUsapCfg(RLC_UL_INST);
704 duBuildMacUsapCfg(RLC_DL_INST);
709 /**************************************************************************
710 * @brief Function to fill gen config required by MAC
714 * Function : duBuildMacGenCfg
717 * Initiates general Configs towards MAC
720 * @return ROK - success
723 ***************************************************************************/
724 uint8_t duBuildMacGenCfg()
727 RgGenCfg *genCfg=NULLP;
730 DU_SET_ZERO(&pst, sizeof(Pst));
731 DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
733 genCfg = &(rgMngmt.t.cfg.s.genCfg);
735 /*----------- Fill General Configuration Parameters ---------*/
736 genCfg->mem.region = MAC_MEM_REGION;
737 genCfg->mem.pool = MAC_POOL;
739 genCfg->numRguSaps = 2;
741 genCfg->lmPst.dstProcId = DU_PROC;
742 genCfg->lmPst.srcProcId = DU_PROC;
743 genCfg->lmPst.dstEnt = ENTDUAPP;
744 genCfg->lmPst.dstInst = 0;
745 genCfg->lmPst.srcEnt = ENTMAC;
746 genCfg->lmPst.srcInst = macCfgInst;
747 genCfg->lmPst.prior = PRIOR0;
748 genCfg->lmPst.route = RTESPEC;
749 genCfg->lmPst.region = MAC_MEM_REGION;
750 genCfg->lmPst.pool = MAC_POOL;
751 genCfg->lmPst.selector = ODU_SELECTOR_LC;
754 rgMngmt.hdr.msgType = TCFG;
755 rgMngmt.hdr.msgLen = 0;
756 rgMngmt.hdr.entId.ent = ENTMAC;
757 rgMngmt.hdr.entId.inst = (Inst)0;
758 rgMngmt.hdr.elmId.elmnt = STGEN;
759 rgMngmt.hdr.seqNmb = 0;
760 rgMngmt.hdr.version = 0;
761 rgMngmt.hdr.transId = 0;
763 rgMngmt.hdr.response.prior = PRIOR0;
764 rgMngmt.hdr.response.route = RTESPEC;
765 rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
766 rgMngmt.hdr.response.mem.pool = MAC_POOL;
767 rgMngmt.hdr.response.selector = ODU_SELECTOR_LC;
770 pst.selector = ODU_SELECTOR_LC;
771 pst.srcEnt = ENTDUAPP;
773 pst.dstInst = macCfgInst;
774 pst.dstProcId = DU_PROC;
775 pst.srcProcId = DU_PROC;
776 pst.region = duCb.init.region;
778 DU_LOG("\nDEBUG --> DU_APP : MAC Gen Cfg Req sent");
780 /* Send the request to MAC */
781 cmPkLrgCfgReq(&pst, &rgMngmt);
786 /**************************************************************************
787 * @brief Function to fill USAP config required by MAC
791 * Function : duBuildMacUsapCfg
794 * Initiates USAP Configs towards MAC
796 * @param[in] SpId Specifies if RLC UL or RLC DL instance
797 * @return ROK - success
800 ***************************************************************************/
801 uint8_t duBuildMacUsapCfg(SpId sapId)
804 RgUpSapCfg *uSap = NULLP;
807 DU_SET_ZERO(&pst, sizeof(Pst));
808 DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
810 uSap = &(rgMngmt.t.cfg.s.rguSap);
812 uSap->mem.region = MAC_MEM_REGION;
813 uSap->mem.pool = MAC_POOL;
816 uSap->procId = DU_PROC;
819 uSap->prior = PRIOR0;
820 uSap->route = RTESPEC;
821 uSap->selector = ODU_SELECTOR_LC ;
824 rgMngmt.hdr.msgType = TCFG;
825 rgMngmt.hdr.entId.ent = ENTMAC;
826 rgMngmt.hdr.entId.inst = (Inst)0;
827 rgMngmt.hdr.elmId.elmnt = STRGUSAP;
828 rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
829 rgMngmt.hdr.response.mem.pool = MAC_POOL;
832 pst.selector = ODU_SELECTOR_LC;
833 pst.srcEnt = ENTDUAPP;
835 pst.dstInst = macCfgInst;
836 pst.dstProcId = DU_PROC;
837 pst.srcProcId = DU_PROC;
838 pst.region = duCb.init.region;
840 DU_LOG("\nDEBUG --> DU_APP : MAC Rgu USap Cfg Req sent");
842 /* Send the request to MAC */
843 cmPkLrgCfgReq(&pst, &rgMngmt);
848 /**************************************************************************
849 * @brief Function to handle Config Confirm from MAC
853 * Function : duHdlMacCfgComplete
856 * Handles Gen Config Confirm from MAC
858 * @param[in] Pst *pst, Post structure of the primitive.
859 * @param[in] RgMngmt *cfm, Unpacked primitive info received from MAC
860 * @return ROK - success
863 ***************************************************************************/
864 uint8_t duHdlMacCfgComplete(Pst *pst, RgMngmt *cfm)
868 if (cfm->cfm.status == LCM_PRIM_OK)
870 switch (cfm->hdr.elmId.elmnt)
874 macCfg |= MAC_GEN_CFG;
879 macCfg |= MAC_SAP_CFG;
886 DU_LOG("\nDEBUG --> DU_APP : MAC Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
887 if(macCfg == MAC_CONFIGURED && numRlcMacSaps == MAX_MAC_SAP)
890 DU_LOG("\nDEBUG --> DU_APP : Completed sending Configs");
892 duBindUnbindRlcToMacSap(RLC_DL_INST, ABND);
898 DU_LOG("\nERROR --> DU_APP : Config confirm NOK from MAC");
904 /**************************************************************************
905 * @brief Function to bind/unbind RLC to MAC SAP
909 * Function : duBindUnbindRlcToMacSap
912 * Initiates Bind/Unbind from RLC to MAC
914 * @param[in] Inst Specifies if RLC UL or RLC DL instance
915 * @param[in] action Specifies if action is bind or unbind
916 * @return ROK - success
919 ***************************************************************************/
920 uint8_t duBindUnbindRlcToMacSap(uint8_t inst, uint8_t action)
922 RlcCntrl *cntrl = NULLP;
927 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
928 DU_SET_ZERO(&pst, sizeof(Pst));
932 DU_LOG("\nDEBUG --> DU_APP : Cntrl Req to RLC inst %d to bind MAC sap", inst);
936 DU_LOG("\nDEBUG --> DU_APP : Cntrl Req to RLC inst %d to unbind MAC sap", inst);
938 cntrl = &(rlcMngmt.t.cntrl);
940 cntrl->action = action;
941 cntrl->subAction = DU_ZERO_VAL;
942 cntrl->s.sapCntrl.suId = macCfgInst;
943 cntrl->s.sapCntrl.spId = inst;
946 rlcMngmt.hdr.msgType = TCNTRL;
947 rlcMngmt.hdr.entId.ent = ENTRLC;
948 rlcMngmt.hdr.entId.inst = inst;
949 rlcMngmt.hdr.elmId.elmnt = 186; /* ambiguous defines in lkw.h and lrg.h so direct hardcoded*/
950 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
951 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
952 rlcMngmt.hdr.response.mem.pool = RLC_POOL;
955 pst.selector = ODU_SELECTOR_LC;
956 pst.srcEnt = ENTDUAPP;
958 pst.dstProcId = DU_PROC;
960 pst.srcProcId = DU_PROC;
961 pst.region = duCb.init.region;
963 cmPkLkwCntrlReq(&pst, &rlcMngmt);
967 /*******************************************************************
969 * @brief Handles SCTP notifications
973 * Function : duSctpNtfyHdl
976 * Handles SCTP notification
978 * @params[in] Message Buffer
981 * @return ROK - success
984 * ****************************************************************/
986 uint8_t duSctpNtfyHdl(Buffer *mBuf, CmInetSctpNotification *ntfy)
988 if(f1Params.assocId == ntfy->u.assocChange.assocId)
990 if(BuildAndSendF1SetupReq() != ROK)
995 else if(ricParams.assocId == ntfy->u.assocChange.assocId)
1001 DU_LOG("\nERROR --> DU_APP : Invalid assocId %d received", ntfy->u.assocChange.assocId);
1007 /*******************************************************************
1009 * @brief Fills Pst struct for ENTEGTP
1013 * Function : duFillEgtpPst
1016 * Fills Pst struct for ENTEGTP
1019 * @return ROK - success
1022 * ****************************************************************/
1023 uint8_t duFillEgtpPst(Pst *pst, Event event)
1025 memset(pst, 0, sizeof(Pst));
1026 pst->srcEnt = (Ent)ENTDUAPP;
1027 pst->srcInst = (Inst)DU_INST;
1028 pst->srcProcId = DU_PROC;
1029 pst->dstEnt = (Ent)ENTEGTP;
1030 pst->dstInst = (Inst)EGTP_INST;
1031 pst->dstProcId = pst->srcProcId;
1033 pst->selector = ODU_SELECTOR_LC;
1040 /*******************************************************************
1042 * @brief Function to configure EGTP
1046 * Function : duBuildEgtpCfgReq
1049 * Function to configure EGTP
1052 * @return ROK - success
1055 * ****************************************************************/
1057 uint8_t duBuildEgtpCfgReq()
1062 DU_LOG("\nDEBUG --> DU_APP : Sending EGTP config request");
1064 memset(&egtpCfg, 0, sizeof(EgtpConfig));
1065 memcpy(&egtpCfg, &duCfgParam.egtpParams, sizeof(EgtpConfig));
1067 duFillEgtpPst(&pst, EVTCFGREQ);
1068 packEgtpCfgReq(&pst, egtpCfg);
1073 /*******************************************************************
1075 * @brief Function to configure EGTP
1079 * Function : duBuildEgtpCfgReq
1082 * Function to configure EGTP
1085 * @return ROK - success
1088 * ****************************************************************/
1089 uint8_t duHdlEgtpCfgComplete(CmStatus cfm)
1093 if(cfm.status == LCM_PRIM_OK)
1095 DU_LOG("\nDEBUG --> DU_APP : EGTP configuraton complete");
1096 duSendEgtpSrvOpenReq();
1100 DU_LOG("\nERROR --> DU_APP : EGTP configuraton failed");
1107 /*******************************************************************
1109 * @brief Sends server open request to EGTP
1113 * Function : duSendEgtpSrvOpenReq
1116 * Sends server open request to EGTP
1119 * @return ROK - success
1122 * ****************************************************************/
1124 uint8_t duSendEgtpSrvOpenReq()
1128 DU_LOG("\nDEBUG --> DU_APP : Sending EGTP server open request");
1130 duFillEgtpPst(&pst, EVTSRVOPENREQ);
1131 packEgtpSrvOpenReq(&pst);
1136 /*******************************************************************
1138 * @brief Handles server open confirmation
1142 * Function : duHdlEgtpSrvOpenComplete
1145 * Handles server open confirmation
1148 * @return ROK - success
1151 *****************************************************************/
1153 uint8_t duHdlEgtpSrvOpenComplete(CmStatus cfm)
1157 if(cfm.status == LCM_PRIM_OK)
1159 DU_LOG("\nDEBUG --> DU_APP : EGTP server opened successfully");
1163 DU_LOG("\nERROR --> DU_APP : EGTP server opening failed");
1170 /*******************************************************************
1172 * @brief Sends tunnel management request
1176 * Function : duSendEgtpTnlMgmtReq
1179 * Builds and sends tunnel management request to EGTP
1181 * @params[in] Action
1182 * Local tunnel endpoint id
1183 * Remote tunnel endpoint id
1184 * @return ROK - success
1187 * ****************************************************************/
1189 uint8_t duSendEgtpTnlMgmtReq(uint8_t action, uint32_t teIdTobeMod, GtpTnlCfg *ueCbTnlCfg)
1195 DU_LOG("\nDEBUG --> DU_APP : Sending EGTP tunnel management request for teId [%d]", ueCbTnlCfg->teId);
1197 /* ADD/MOD/DEL per tunnel */
1198 tnlEvt.action = action;
1199 tnlEvt.remTeid = ueCbTnlCfg->teId;
1200 if(action != EGTP_TNL_MGMT_ADD)
1202 tnlEvt.lclTeid = teIdTobeMod;
1206 tnlEvt.lclTeid = ueCbTnlCfg->teId;
1208 duFillEgtpPst(&pst, EVTTNLMGMTREQ);
1209 ret = egtpTnlMgmtReq(&pst, tnlEvt);
1213 /*******************************************************************
1215 * @brief Handles Tunnel management confirm
1219 * Function : duHdlEgtpTnlMgmtCfm
1222 * Handles tunnel management confirm received from Egtp
1224 * @params[in] Tunnel Event
1225 * @return ROK - success
1228 * ****************************************************************/
1229 uint8_t duHdlEgtpTnlMgmtCfm(EgtpTnlEvt tnlEvtCfm)
1233 if(tnlEvtCfm.cfmStatus.status == LCM_PRIM_OK)
1235 DU_LOG("\nDEBUG --> DU_APP: Tunnel management confirm OK");
1239 DU_LOG("\nERROR --> DU_APP: Tunnel management failed");
1246 /*******************************************************************
1248 * @brief Sends UL user data over to EGTP
1252 * Function : duSendEgtpDatInd
1254 * Functionality: Sends UL user data over to EGTP
1256 * @params[in] UL data buffer
1257 * @return ROK - success
1260 * ****************************************************************/
1261 uint8_t duSendEgtpDatInd(Buffer *mBuf)
1265 /* Fill EGTP header */
1266 egtpMsg.msgHdr.msgType = EGTPU_MSG_GPDU;
1267 egtpMsg.msgHdr.nPdu.pres = FALSE;
1268 egtpMsg.msgHdr.seqNum.pres = FALSE;
1269 egtpMsg.msgHdr.extHdr.udpPort.pres = FALSE;
1270 egtpMsg.msgHdr.extHdr.pdcpNmb.pres = FALSE;
1271 egtpMsg.msgHdr.teId = 1;
1274 egtpHdlDatInd(egtpMsg);
1280 /**************************************************************************
1281 * @brief Function to send configs to SCH
1285 * Function : duSendSchCfg
1288 * Sends general config to Scheduler via MAC layer
1291 * @return ROK - success
1294 ***************************************************************************/
1295 uint8_t duSendSchCfg()
1298 RgSchInstCfg *cfg = NULLP;
1301 DU_SET_ZERO(&pst, sizeof(Pst));
1302 DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
1304 cfg = &(rgMngmt.t.cfg.s.schInstCfg);
1306 /* Filling of Instance Id */
1307 cfg->instId = DEFAULT_CELLS + 1;
1308 /* Filling of Gen config */
1309 cfg->genCfg.mem.region = MAC_MEM_REGION;
1310 cfg->genCfg.mem.pool = MAC_POOL;
1311 cfg->genCfg.tmrRes = 1;
1314 cfg->genCfg.forceCntrlSrbBoOnPCel = FALSE;
1315 cfg->genCfg.isSCellActDeactAlgoEnable = TRUE;
1317 cfg->genCfg.startCellId = 1;
1318 cfg->genCfg.lmPst.dstProcId = DU_PROC;
1319 cfg->genCfg.lmPst.srcProcId = DU_PROC;
1320 cfg->genCfg.lmPst.dstEnt = ENTDUAPP;
1321 cfg->genCfg.lmPst.dstInst = DU_INST;
1322 cfg->genCfg.lmPst.srcEnt = ENTMAC;
1323 cfg->genCfg.lmPst.srcInst = DEFAULT_CELLS + 1;
1324 cfg->genCfg.lmPst.prior = PRIOR0;
1325 cfg->genCfg.lmPst.route = RTESPEC;
1326 cfg->genCfg.lmPst.region = MAC_MEM_REGION;
1327 cfg->genCfg.lmPst.pool = MAC_POOL;
1328 cfg->genCfg.lmPst.selector = ODU_SELECTOR_LC;
1331 rgMngmt.hdr.msgType = TCFG;
1332 rgMngmt.hdr.entId.ent = ENTMAC;
1333 rgMngmt.hdr.entId.inst = DU_INST;
1334 rgMngmt.hdr.elmId.elmnt = STSCHINST;
1335 rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
1336 rgMngmt.hdr.response.mem.pool = MAC_POOL;
1339 pst.selector = ODU_SELECTOR_LC;
1340 pst.srcEnt = ENTDUAPP;
1341 pst.dstEnt = ENTMAC;
1342 pst.dstProcId = DU_PROC;
1343 pst.srcProcId = DU_PROC;
1344 pst.srcInst = DU_INST;
1346 pst.region = duCb.init.region;
1347 pst.event = (Event) EVTMACSCHGENCFGREQ;
1349 DU_LOG("\nDEBUG --> DU_APP : MAC Sch Cfg sent");
1351 /* Send the request to MAC */
1352 cmPkLrgSchCfgReq(&pst, &rgMngmt);
1358 /**************************************************************************
1359 * @brief Function to configure SCTP params and
1360 * responsible for F1 and E2 interfaces
1364 * Function : duLayerConfigComplete
1367 * Configures SCTP Params and responsible for handling
1368 * F1 and E2 interface.
1371 * @return ROK - success
1374 ***************************************************************************/
1375 uint8_t duLayerConfigComplete()
1379 DU_LOG("\nINFO --> DU_APP : Configuring all Layer is complete");
1381 if((ret = duSctpCfgReq(duCfgParam.sctpParams)) != ROK)
1383 DU_LOG("\nERROR --> DU_APP : Failed configuring Sctp Params");
1386 if((ret = duSctpAssocReq(F1_INTERFACE)) != ROK)
1388 DU_LOG("\nERROR --> DU_APP : Failed to send AssocReq F1");
1391 if((ret = duSctpAssocReq(E2_INTERFACE)) != ROK)
1393 DU_LOG("\nERROR --> DU_APP : Failed to send AssocReq E2");
1400 /**************************************************************************
1401 * @brief Function to handle SCH Config Confirm from MAC
1405 * Function : duHdlSchCfgComplete
1408 * Handles Scheduler Gen Config Confirm from MAC
1410 * @param[in] Pst *pst, Post structure of the primitive.
1411 * @param[in] RgMngmt *cfm, Unpacked primitive info received from MAC
1412 * @return ROK - success
1415 ***************************************************************************/
1416 uint8_t duHdlSchCfgComplete(Pst *pst, RgMngmt *cfm)
1418 if (cfm->cfm.status == LCM_PRIM_OK)
1420 switch (cfm->hdr.elmId.elmnt)
1424 DU_LOG("\nDEBUG --> DU_APP : Received SCH CFG CFM at DU APP");
1431 duLayerConfigComplete();
1432 duBuildEgtpCfgReq();
1436 /**************************************************************************
1437 * @brief Function to fill and send MacCellconfig
1441 * Function : duBuildAndSendMacCellCfg
1444 * Initiates MAC Configs towards MAC
1447 * @return ROK - success
1450 ***************************************************************************/
1451 uint8_t duBuildAndSendMacCellCfg(uint16_t cellId)
1454 MacCellCfg *duMacCellCfg = NULLP;
1456 DU_ALLOC_SHRABL_BUF(duMacCellCfg, sizeof(MacCellCfg));
1457 if(duMacCellCfg == NULLP)
1462 /* store the address in the duCellCb so that we can free on confirm msg */
1463 if(duCb.actvCellLst[cellId-1])
1464 duCb.actvCellLst[cellId-1]->duMacCellCfg = duMacCellCfg;
1467 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, duMacCellCfg, sizeof(MacCellCfg));
1471 /* copy the mac config structure from duCfgParams */
1472 memcpy(duMacCellCfg,&duCfgParam.macCellCfg,sizeof(MacCellCfg));
1475 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_CONFIG_REQ);
1477 /* Send MAC cell config to MAC */
1478 return (*packMacCellCfgOpts[pst.selector])(&pst, duMacCellCfg);
1481 /**************************************************************************
1482 * @brief Function to Handle MAC cell config confirm
1486 * Function : duHandleMacCellCfgCfm
1489 * Initiates general Configs towards MAC
1492 * @return ROK - success
1495 ***************************************************************************/
1496 uint8_t duHandleMacCellCfgCfm(Pst *pst, MacCellCfgCfm *macCellCfgCfm)
1498 uint8_t actvCellIdx = 0;
1501 for(actvCellIdx = 0; actvCellIdx < MAX_NUM_CELL; actvCellIdx++)
1503 if((duCb.actvCellLst[actvCellIdx]) && (macCellCfgCfm->cellId == duCb.actvCellLst[actvCellIdx]->cellId))
1505 duCb.actvCellLst[actvCellIdx]->duMacCellCfg = NULLP;
1508 if(macCellCfgCfm->rsp == ROK)
1510 /* Build and send GNB-DU config update */
1511 ret = BuildAndSendDUConfigUpdate(SERV_CELL_TO_MODIFY);
1513 /* Build and Send Cell Start Req to MAC */
1514 ret = duBuildAndSendMacCellStart();
1518 /* TODO : Action to be taken if cell configuration fails.
1519 * Should CU be informed? */
1521 DU_LOG("\nERROR --> DU_APP : Mac cell cfg failed");
1527 /*******************************************************************
1529 * @brief Builds and sends cell start request to MAC
1533 * Function : duBuildAndSendMacCellStart
1536 * Builds and sends cell start request to MAC
1539 * @return ROK - success
1542 * ****************************************************************/
1543 uint8_t duBuildAndSendMacCellStart()
1546 CellStartInfo *cellStart = NULL;
1548 DU_LOG("\nINFO --> DU APP : Building and Sending cell start request to MAC");
1550 /* Send Cell Start Request to MAC */
1551 DU_ALLOC_SHRABL_BUF(cellStart, sizeof(CellStartInfo));
1554 DU_LOG("\nERROR --> DU APP : Memory alloc failed while building cell start request");
1558 for(uint8_t id = 0; id < MAX_NUM_CELL; id++)
1560 if(duCb.actvCellLst[id])
1562 cellStart->cellId = duCb.actvCellLst[id]->cellId;
1565 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_START);
1567 return (*packMacCellStartOpts[pst.selector])(&pst, cellStart);
1573 /*******************************************************************
1575 * @brief Builds and sends cell stop request to MAC
1579 * Function : duBuildAndSendMacCellStop
1582 * Builds and sends cell stop request to MAC
1585 * @return ROK - success
1588 * ****************************************************************/
1589 uint8_t duBuildAndSendMacCellStop(uint16_t cellId)
1593 CellStopInfo *cellStop = NULL;
1595 DU_LOG("\nINFO --> DU APP : Building and Sending cell stop request to MAC");
1597 GET_CELL_IDX(cellId, cellIdx);
1598 if(duCb.actvCellLst[cellIdx] != NULLP)
1600 /* Send Cell Stop Request to MAC */
1601 DU_ALLOC_SHRABL_BUF(cellStop, sizeof(CellStopInfo));
1604 DU_LOG("\nERROR --> DU APP : Memory alloc failed while building cell stop request");
1607 memset(cellStop, 0, sizeof(CellStopInfo));
1608 cellStop->cellId = duCb.actvCellLst[cellIdx]->cellId;
1611 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_STOP);
1613 return (*packMacCellStopOpts[pst.selector])(&pst, cellStop);
1617 DU_LOG("\nERROR --> DU APP : duBuildAndSendMacCellStop(): cellId[%d] doesnot exists", cellId);
1623 /*******************************************************************
1625 * @brief Handles stop indication from MAC
1629 * Function : duHandleStopInd
1632 * Handles stop indication from MAC
1634 * @params[in] Post structure pointer
1635 * @return ROK - success
1638 * ****************************************************************/
1639 uint8_t duHandleStopInd(Pst *pst, OduCellId *cellId)
1641 DuCellCb *cellCb = NULLP;
1643 if(cellId->cellId <=0 || cellId->cellId > MAX_NUM_CELL)
1645 DU_LOG("\nERROR --> DU APP : Invalid Cell Id %d in duHandleStopInd()", cellId->cellId);
1648 if(duGetCellCb(cellId->cellId, &cellCb) != ROK)
1651 if((cellCb->cellStatus == ACTIVATED) || (cellCb->cellStatus == DELETION_IN_PROGRESS))
1653 DU_LOG("\nINFO --> DU APP : 5G-NR Cell %d is DOWN", cellId->cellId);
1654 if(sendCellDeleteReqToMac(cellId->cellId) == RFAILED)
1656 DU_LOG("\nERROR --> DU APP : duHandleStopInd(): Failed to send Cell delete req to MAC for\
1657 cellId[%d]", cellId->cellId);
1663 DU_LOG("\nINFO --> DU APP : Raise cell down alarm for cell id=%d", cellId->cellId);
1664 raiseCellAlrm(CELL_DOWN_ALARM_ID, cellId->cellId);
1665 setCellOpState(cellId->cellId, DISABLED, INACTIVE);
1669 if((pst->selector == ODU_SELECTOR_LWLC) || (pst->selector == ODU_SELECTOR_TC))
1670 DU_FREE_SHRABL_BUF(MAC_MEM_REGION, pst->pool, cellId, sizeof(OduCellId));
1672 cellCb->cellStatus = CELL_OUT_OF_SERVICE; //TODO: cell status must be set to OOS after all UE and cell cleanup which is not
1678 /*******************************************************************
1680 * @brief Handles slot indication from MAC
1684 * Function : duHandleUlCcchInd
1687 * Handles UL CCCH indication from MAC
1689 * @params[in] Post structure pointer
1690 * UL CCCH Ind pointer
1691 * @return ROK - success
1694 * ****************************************************************/
1695 uint8_t duHandleUlCcchInd(Pst *pst, UlCcchIndInfo *ulCcchIndInfo)
1698 DU_LOG("\nINFO --> DU APP : UL CCCH Indication received");
1700 return (duProcUlCcchInd(ulCcchIndInfo));
1703 /*******************************************************************
1705 * @brief Process UL RRC Message from RLC
1709 * Function : DuProcRlcUlRrcMsgTrans
1711 * Functionality: Process UL RRC Message from RLC
1713 * @params[in] Post structure
1714 * UL RRC Message Info
1715 * @return ROK - success
1718 * ****************************************************************/
1719 uint8_t DuProcRlcUlRrcMsgTrans(Pst *pst, RlcUlRrcMsgInfo *ulRrcMsgInfo)
1722 DuCellCb *cellCb = NULLP;
1723 DuUeCb *ueCb = NULLP;
1725 duGetCellCb(ulRrcMsgInfo->cellId, &cellCb);
1728 if(ulRrcMsgInfo->ueId > 0)
1730 if(cellCb->ueCb[ulRrcMsgInfo->ueId -1].gnbDuUeF1apId == ulRrcMsgInfo->ueId)
1731 ueCb = &cellCb->ueCb[ulRrcMsgInfo->ueId -1];
1735 /* If UL message is received for a UE in handover, it signifies that UE is now
1736 * attached to GNB. Hence marking this UE as active and requesting MAC to
1737 * release the dedicated RACH resources */
1738 if(ueCb->ueState == UE_HANDIN_IN_PROGRESS)
1740 ueCb->ueState = UE_ACTIVE;
1741 cellCb->numActvUes++;
1743 /* Release RACH resources */
1744 memset(&ueCb->cfraResource, 0, sizeof(MacCfraResource));
1745 if(duBuildAndSendRachRsrcRelToMac(ulRrcMsgInfo->cellId, ueCb) != ROK)
1747 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Failed to send RACH resource release to MAC");
1751 if(BuildAndSendULRRCMessageTransfer(ueCb, ulRrcMsgInfo->lcId, ulRrcMsgInfo->msgLen, ulRrcMsgInfo->rrcMsg) != ROK)
1753 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Failed to build and send UL RRC Message Transfer");
1759 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : UE ID [%d] not found", ulRrcMsgInfo->ueId);
1765 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Invalid UE ID [%d]", ulRrcMsgInfo->ueId);
1771 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Cell ID [%d] not found", ulRrcMsgInfo->cellId);
1775 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulRrcMsgInfo->rrcMsg, ulRrcMsgInfo->msgLen);
1776 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
1780 /*******************************************************************
1782 * @brief Process RRC delivery report from RLC
1786 * Function : DuProcRlcRrcDeliveryReport
1788 * Functionality: Process RRC delivery Message from RLC
1790 * @params[in] Post structure
1791 * UL RRC Message Info
1792 * @return ROK - success
1795 * ****************************************************************/
1796 uint8_t DuProcRlcRrcDeliveryReport(Pst *pst, RrcDeliveryReport *rrcDeliveryReport)
1798 DuCellCb *cellCb = NULLP;
1800 uint8_t ret = RFAILED;
1802 if(duGetCellCb(rrcDeliveryReport->cellId, &cellCb) != ROK)
1805 ueCb = cellCb->ueCb[rrcDeliveryReport->ueId -1];
1806 ret = BuildAndSendRrcDeliveryReport(ueCb.gnbCuUeF1apId, ueCb.gnbDuUeF1apId,rrcDeliveryReport);
1808 DU_FREE_SHRABL_BUF(pst->region, pst->pool, rrcDeliveryReport, sizeof(RrcDeliveryReport));
1812 /*******************************************************************
1814 * @brief Process UL user data from RLC
1818 * Function : DuProcRlcUlUserDataTrans
1820 * Functionality: Process UL user data from RLC
1822 * @params[in] Post structure
1824 * @return ROK - success
1827 * ****************************************************************/
1828 uint8_t DuProcRlcUlUserDataTrans(Pst *pst, RlcUlUserDatInfo *ulUserData)
1834 DU_LOG("\nDEBUG --> DU APP : Received UL user data");
1836 /* Fill EGTP header */
1837 egtpMsg.msgHdr.msgType = EGTPU_MSG_GPDU;
1838 egtpMsg.msgHdr.nPdu.pres = FALSE;
1839 egtpMsg.msgHdr.seqNum.pres = FALSE;
1840 egtpMsg.msgHdr.extHdr.udpPort.pres = FALSE;
1841 egtpMsg.msgHdr.extHdr.pdcpNmb.pres = FALSE;
1843 /* Fetch EGTP tunnel info */
1844 for(teIdx = 0; teIdx < duCb.numTeId; teIdx++)
1846 /*TODO: If multiple Cell Support is enables then CellId also needs to be validated alongwith ueId and DrbId*/
1847 if((duCb.upTnlCfg[teIdx] != NULLP) && (duCb.upTnlCfg[teIdx]->ueId == ulUserData->ueId) && \
1848 (duCb.upTnlCfg[teIdx]->drbId == ulUserData->rbId))
1850 if(duCb.upTnlCfg[teIdx]->tnlCfg1)
1852 egtpMsg.msgHdr.teId = duCb.upTnlCfg[teIdx]->tnlCfg1->teId; /*As we are supporting only 1 tunnel per DRB*/
1858 if (ODU_GET_MSG_BUF(DU_APP_MEM_REGION, DU_POOL, &mBuf) != ROK)
1860 DU_LOG("\nERROR --> DU APP : Failed to allocated buffer memory in DuProcRlcUlUserDataTrans");
1861 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData->userData, ulUserData->msgLen);
1862 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData, sizeof(RlcUlUserDatInfo));
1865 oduCpyFixBufToMsg(ulUserData->userData, mBuf, ulUserData->msgLen);
1866 ODU_PRINT_MSG(mBuf, 0, 0);
1868 egtpHdlDatInd(egtpMsg);
1870 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData->userData, ulUserData->msgLen);
1871 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData, sizeof(RlcUlUserDatInfo));
1875 /*******************************************************************
1877 * @brief process the slice cfg rsp received from MAC
1881 * Function : DuProcMacSliceCfgRsp
1883 * Functionality: process the slice cfg rsp received from MAC
1885 * @params[in] Post structure, MacSliceCfgRsp *cfgRsp
1887 * @return ROK - success
1890 **********************************************************************/
1891 uint8_t DuProcMacSliceCfgRsp(Pst *pst, MacSliceCfgRsp *cfgRsp)
1895 if(cfgRsp->rsp == MAC_DU_APP_RSP_OK)
1897 duCb.sliceState = SLICE_CONFIGURED;
1898 DU_LOG("\nINFO --> DU_APP : Slice configured successfully ");
1902 DU_LOG("\nERROR --> DU_APP : Slice not available");
1904 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, cfgRsp, sizeof(MacSliceCfgRsp));
1909 /*******************************************************************
1911 * @brief Fill the slice configration and rrm policy related
1912 * information received form O1
1916 * Function : BuildAndSendSliceConfigReq
1918 * Functionality: Fill the slice configration and rrm policy related
1920 * @params[in] RrmPolicy *rrmPolicy[], uint8_t totalRrmPolicy, uint8_t
1923 * @return ROK - success
1926 * ****************************************************************/
1927 uint8_t BuildAndSendSliceConfigReq()
1930 MacSliceCfgReq *sliceCfgReq;
1932 DU_ALLOC_SHRABL_BUF(sliceCfgReq, sizeof(MacSliceCfgReq));
1933 if(sliceCfgReq == NULLP)
1935 DU_LOG("\nERROR --> DU_APP : Memory allocation failed in BuildAndSendSliceConfigReq");
1940 memcpy(sliceCfgReq, &duCfgParam.tempSliceCfg, sizeof(MacSliceCfgReq));
1941 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_SLICE_CFG_REQ);
1943 DU_LOG("\nDEBUG --> DU_APP : Sending Slice Cfg Request to MAC ");
1944 if((*packMacSliceCfgReqOpts[pst.selector])(&pst, sliceCfgReq) == RFAILED)
1946 DU_LOG("\nERROR --> DU_APP : Failed to send Slice Cfg Req to MAC");
1947 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, sliceCfgReq, sizeof(MacSliceCfgReq));
1953 /*******************************************************************
1955 * @brief Fill the slice configration and rrm policy related
1956 * information received form O1
1960 * Function : BuildAndSendSliceRecfgReq
1962 * Functionality: Fill the slice configration and rrm policy related
1964 * @params[in] RrmPolicy rrmPolicy[], uint8_t totalSliceCount
1966 * @return ROK - success
1969 * ****************************************************************/
1970 uint8_t BuildAndSendSliceRecfgReq()
1973 MacSliceRecfgReq *sliceRecfgReq = NULLP;
1975 DU_LOG("\nINFO --> DU_APP : Slice ReConfiguration Request received");
1977 DU_ALLOC_SHRABL_BUF(sliceRecfgReq, sizeof(MacSliceRecfgReq));
1978 if(sliceRecfgReq == NULLP)
1980 DU_LOG("\nERROR --> DU_APP : Memory allocation failed to BuildAndSendSliceRecfgReq");
1985 memcpy(sliceRecfgReq, &duCfgParam.tempSliceCfg, sizeof(MacSliceRecfgReq));
1987 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_SLICE_RECFG_REQ);
1989 DU_LOG("\nDEBUG --> DU_APP: Sending Slice ReCfg Request to MAC ");
1990 if( (*packMacSliceRecfgReqOpts[pst.selector])(&pst, sliceRecfgReq) == RFAILED)
1992 DU_LOG("\nERROR --> DU_APP: Failed to send Slice ReCfg Req to MAC");
1993 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, sliceRecfgReq, sizeof(MacSliceRecfgReq));
1998 /*******************************************************************
2000 * @brief process the slice ReCfg rsp received from MAC
2004 * Function : DuProcMacSliceRecfgRsp
2006 * Functionality: process the slice ReCfg rsp received from MAC
2008 * @params[in] Post structure, MacSliceRecfgRsp *ReCfgRsp
2010 * @return ROK - success
2013 **********************************************************************/
2014 uint8_t DuProcMacSliceRecfgRsp(Pst *pst, MacSliceRecfgRsp *recfgRsp)
2018 if(recfgRsp->rsp == MAC_DU_APP_RSP_OK)
2020 duCb.sliceState = SLICE_RECONFIGURED;
2021 DU_LOG("\nINFO --> DU_APP : Slice Reconfigured successfully ");
2025 DU_LOG("\nERROR --> DU_APP : Slice not available");
2027 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, recfgRsp, sizeof(MacSliceCfgRsp));
2032 /*******************************************************************
2034 * @brief Handles received Slice Metrics from RLC and forward it to O1
2038 * Function : DuProcRlcSliceMetrics
2041 * Handles received Slice Metrics from RLC and forward it to O1
2043 * @params[in] Post structure pointer
2044 * SlicePmList *sliceStats
2046 * @return ROK - success
2049 * ****************************************************************/
2050 uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats)
2052 uint8_t sliceRecord = 0;
2054 DU_LOG("\nDEBUG --> DU APP : Received Slice Metrics");
2055 if(sliceStats == NULLP)
2057 DU_LOG("\nERROR --> DU APP : Empty Metrics");
2061 for(sliceRecord = 0; sliceRecord < sliceStats->numSlice; sliceRecord++)
2063 DU_LOG("\nINFO --> DU_APP: SliceId[SST-SD]:%d-%d, DlTput %.5lf, UlTput:%.5lf", sliceStats->sliceRecord[sliceRecord].networkSliceIdentifier.sst,\
2064 sliceStats->sliceRecord[sliceRecord].networkSliceIdentifier.sd,sliceStats->sliceRecord[sliceRecord].ThpDl,\
2065 sliceStats->sliceRecord[sliceRecord].ThpUl);
2070 sendSliceMetric((SliceMetricList*) sliceStats);
2074 DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats->sliceRecord, (sliceStats->numSlice) * (sizeof(SlicePm)));
2075 DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats, sizeof(SlicePmList));
2081 /*******************************************************************
2083 * @brief Send Statistics request to MAC
2087 * Function : BuildAndSendStatsReqToMac()
2089 * Functionality: Send Statistics Request To Mac
2093 * @return ROK - success
2096 * ****************************************************************/
2097 uint8_t BuildAndSendStatsReqToMac(uint64_t subscriptionId, RicSubscription *ricSubscriptionInfo)
2100 uint8_t actionIdx = 0, grpIdx = 0, statsIdx = 0;
2101 ActionInfo *actionDb = NULLP;
2102 ActionDefFormat1 *format1Action = NULLP;
2103 MacStatsReq *macStatsReq = NULLP;
2105 /* Fill MAC statistics request */
2106 DU_ALLOC_SHRABL_BUF(macStatsReq, sizeof(MacStatsReq));
2107 if(macStatsReq == NULLP)
2109 DU_LOG("\nERROR --> DU_APP : Memory allocation failed for macStatsReq in BuildAndSendStatsReqToMac");
2113 macStatsReq->subscriptionId = subscriptionId;
2114 for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++)
2116 if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
2118 actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
2119 macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id;
2120 switch(actionDb->definition.formatType)
2124 format1Action = &actionDb->definition.choice.format1;
2125 macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod;
2127 CmLList *node = NULLP;
2128 MeasurementInfo *measInfo = NULLP;
2130 /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
2131 node = cmLListFirst(&format1Action->measurementInfoList);
2134 measInfo = (MeasurementInfo *)(node->node);
2135 switch(measInfo->measurementTypeId)
2139 macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE;
2144 macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE;
2149 DU_LOG("\nERROR --> DU_APP : Invalid measurement name BuildAndSendStatsReqToMac");
2155 macStatsReq->statsGrpList[grpIdx].numStats = statsIdx;
2160 DU_LOG("\nERROR --> DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported");
2164 if(macStatsReq->statsGrpList[grpIdx].numStats)
2168 macStatsReq->numStatsGroup = grpIdx;
2170 if(macStatsReq->numStatsGroup)
2172 DU_LOG("\nDEBUG --> DU_APP: Sending Statistics Request to MAC ");
2173 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_STATISTICS_REQ);
2175 if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == ROK)
2178 DU_LOG("\nERROR --> DU_APP: Failed to send Statistics Request to MAC");
2181 DU_LOG("\nERROR --> DU_APP: No Statistics group found valid. Hence statistics request is not sent to MAC");
2182 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq));
2186 /*******************************************************************
2188 * @brief Fetch statistics details from Action Definition Format 1
2192 * Function : FetchStatsFromActionDefFormat1()
2194 * Functionality: Fetch statistics details from Action
2195 * Definition Format 1 received in an E2 message from
2198 * @params[in] ActionDefFormat1
2200 * @return Statistics
2202 * ****************************************************************/
2203 Statistics FetchStatsFromActionDefFormat1(ActionDefFormat1 format1)
2207 /* TODO : When E2AP subscription procedure is implemented:
2208 * Measurement info list is traveresed
2209 * Based on KPI type, stats.macStatsReq or stats.rlcstatsReq is filled */
2211 /* Hardcoding values for now for testing purpose
2212 * Will be removed in next gerrit */
2213 stats.macStatsReq.subscriptionId = 1;
2214 stats.macStatsReq.numStatsGroup = 1;
2215 stats.macStatsReq.statsGrpList[0].groupId = 1;
2216 stats.macStatsReq.statsGrpList[0].periodicity = 100;
2217 stats.macStatsReq.statsGrpList[0].numStats = 2;
2218 stats.macStatsReq.statsGrpList[0].statsList[0] = MAC_DL_TOTAL_PRB_USAGE;
2219 stats.macStatsReq.statsGrpList[0].statsList[1] = MAC_UL_TOTAL_PRB_USAGE;
2224 /*******************************************************************
2226 * @brief Send Statistics request to DU layers
2230 * Function : BuildAndSendStatsReq()
2232 * Functionality: Check if there is an update in statistics
2233 * reporting configuration. If so, send the update to
2236 * @params[in] Subscription Info
2238 * @return ROK - success
2241 * ****************************************************************/
2242 uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo)
2244 uint64_t subscriptionId = 0;
2246 /* Calculate 64 bit subscription-ID :
2247 * First 16 MSB is unused
2248 * Next 16 MSB = RAN-Function-ID
2249 * Next 16 MSB = Requestor-ID in RIC-Request-ID
2250 * Last 16 LSB = Instance-ID in RIC-Request-ID
2252 subscriptionId = ricSubscriptionInfo->requestId.instanceId;
2253 subscriptionId |= ((uint64_t)ricSubscriptionInfo->requestId.requestorId << 16);
2254 subscriptionId |= ((uint64_t)ranFuncId << 32);
2256 /* Build and sent subscription information to MAC in Statistics Request */
2257 if(BuildAndSendStatsReqToMac(subscriptionId, ricSubscriptionInfo) != ROK)
2259 DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToMac()");
2263 /* TODO : When KPI collection from RLC will be supported, this function will be
2264 * called to configure KPIs to be colled */
2266 if(BuildAndSendStatsReqToRlc() != ROK)
2268 DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToRlc()");
2276 /*******************************************************************
2278 * @brief Converts DU specific failure cause to E2 interface
2283 * Function : convertDuCauseToE2Cause
2285 * Functionality: Converts DU specific failure cause to E2
2286 * interface failure cause
2288 * @params[in] DU specific failure cause
2289 * E2 specific failure cause
2293 * ****************************************************************/
2294 void convertDuCauseToE2Cause(CauseOfResult l2Cause, E2FailureCause *failureCause)
2300 failureCause->causeType = E2_RIC_REQUEST;
2301 failureCause->cause = E2_ACTION_NOT_SUPPORTED;
2304 case RESOURCE_UNAVAILABLE:
2306 failureCause->causeType = E2_RIC_REQUEST;
2307 failureCause->cause = E2_FUNCTION_RESOURCE_LIMIT;
2312 failureCause->causeType = E2_RIC_REQUEST;
2313 failureCause->cause = E2_RIC_REQUEST_CAUSE_UNSPECIFIED;
2319 /*******************************************************************
2321 * @brief Rejects all actions received in a subscription request
2325 * Function : duRejectAllStatsGroup
2327 * Functionality: Rejects all actions received in a subscription
2329 * a. Removing the subscription entry from RAN function
2330 * b. Sending RIC Subscription Failure to RIC with appropriate
2333 * @params[in] RAN Function DB
2334 * Subscription entry in RAN Function subscription list
2335 * Statistics Response from MAC
2337 * @return ROK - success
2340 * ****************************************************************/
2341 uint8_t duRejectAllStatsGroup(RanFunction *ranFuncDb, CmLList *ricSubscriptionNode, MacStatsRsp *statsRsp)
2344 RicRequestId requestId;
2345 E2FailureCause failureCause;
2347 /* Delete subcription from RAN Function */
2348 memcpy(&requestId, &((RicSubscription *)ricSubscriptionNode->node)->requestId, sizeof(RicRequestId));
2349 cmLListDelFrm(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2350 DU_FREE(ricSubscriptionNode->node, sizeof(RicSubscription));
2351 DU_FREE(ricSubscriptionNode, sizeof(CmLList));
2353 convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[0].cause, &failureCause);
2355 /* Send RIC subscription failure to RIC */
2356 ret = BuildAndSendRicSubscriptionFailure(requestId, ranFuncDb->id, failureCause);
2360 /*******************************************************************
2362 * @brief Process statistics response from MAC
2366 * Function : DuProcMacStatsRsp
2368 * Functionality: Processes statistics configuration response
2369 * from MAC. If configuration is succsessful, DUAPP starts
2370 * reporting period timer for this subscription request
2375 * @return ROK - success
2378 * ****************************************************************/
2379 uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp)
2382 uint8_t actionId = 0;
2383 uint16_t ranFuncId = 0;
2384 RicRequestId ricReqId;
2385 RanFunction *ranFuncDb = NULLP;
2386 CmLList *ricSubscriptionNode = NULLP;
2387 RicSubscription *ricSubscriptionInfo = NULLP;
2388 PendingSubsRspInfo *pendingSubsRsp = NULLP;
2390 DU_LOG("\nINFO --> DU_APP : DuProcMacStatsRsp: Received Statistics Response from MAC");
2395 DU_LOG("\n Subscription Id [%ld]", statsRsp->subscriptionId);
2397 DU_LOG("\n Number of Accepted Groups [%d]", statsRsp->numGrpAccepted);
2398 for(idx=0; idx<statsRsp->numGrpAccepted; idx++)
2400 DU_LOG("\n Group Id [%d]", statsRsp->statsGrpAcceptedList[idx]);
2403 DU_LOG("\n Number of Rejected Groups [%d]", statsRsp->numGrpRejected);
2404 for(idx=0; idx<statsRsp->numGrpRejected; idx++)
2406 DU_LOG("\n Group Id [%d]", statsRsp->statsGrpRejectedList[idx].groupId);
2410 /* Extract following from 64 bit subscription-ID :
2411 * First 16 MSB is unused
2412 * Next 16 MSB = RAN-Function-ID
2413 * Next 16 MSB = Requestor-ID in RIC-Request-ID
2414 * Last 16 LSB = Instance-ID in RIC-Request-ID
2416 ricReqId.instanceId = statsRsp->subscriptionId & 0xFFFF;
2417 ricReqId.requestorId = (statsRsp->subscriptionId >> 16) & 0xFFFF;
2418 ranFuncId = (statsRsp->subscriptionId >> 32) & 0xFFFF;
2420 /* Fetch RAN Function DB */
2421 if(duCb.e2apDb.ranFunction[ranFuncId-1].id == ranFuncId)
2423 ranFuncDb = &duCb.e2apDb.ranFunction[ranFuncId-1];
2427 DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Invalid RAN Function ID[%d] with Subscription ID [%ld]", \
2428 ranFuncId, statsRsp->subscriptionId);
2429 DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
2433 /* Fetch subscription detail in RAN Function DB */
2434 CM_LLIST_FIRST_NODE(&ranFuncDb->subscriptionList, ricSubscriptionNode);
2435 while(ricSubscriptionNode)
2437 ricSubscriptionInfo = (RicSubscription *)ricSubscriptionNode->node;
2438 if(ricSubscriptionInfo && (ricSubscriptionInfo->requestId.requestorId == ricReqId.requestorId) &&
2439 (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
2443 ricSubscriptionNode = ricSubscriptionNode->next;
2446 if(ricSubscriptionNode == NULLP)
2448 DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Subscription not found for Requestor ID [%d] Instance ID [%d]",\
2449 ricReqId.requestorId, ricReqId.instanceId);
2450 DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
2454 /* Fetch pre-stored statistics response info by DU APP */
2455 for(idx=0; idx<ranFuncDb->numPendingSubsRsp; idx++)
2457 if((ranFuncDb->pendingSubsRspInfo[idx].requestId.requestorId == ricReqId.requestorId) &&
2458 (ricSubscriptionInfo->requestId.instanceId == ricReqId.instanceId))
2460 pendingSubsRsp = &ranFuncDb->pendingSubsRspInfo[idx];
2465 /* If no action is accepted
2466 * a. Remove subcription entry from RAN Function
2467 * b. Send RIC subscription failure */
2468 if(statsRsp->numGrpAccepted == 0)
2470 duRejectAllStatsGroup(ranFuncDb, ricSubscriptionNode, statsRsp);
2474 /* If even 1 action is accepted :
2476 * For accepted groups:
2477 * Mark subscribed-action's -> action = CONFIG_UNKNOWN
2478 * Add to accepted-action-list of subscription response
2480 for(idx=0; idx<statsRsp->numGrpAccepted; idx++)
2482 actionId = statsRsp->statsGrpAcceptedList[idx];
2483 if((ricSubscriptionInfo->actionSequence[actionId-1].id == actionId) &&
2484 (ricSubscriptionInfo->actionSequence[actionId-1].action == CONFIG_ADD))
2486 ricSubscriptionInfo->actionSequence[actionId-1].action = CONFIG_UNKNOWN;
2488 pendingSubsRsp->acceptedActionList[pendingSubsRsp->numOfAcceptedActions++] = actionId;
2492 /* For rejected groups:
2493 * Remove entry from DU's RAN Function->subscription->actionList
2494 * Add to rejected-action-list in subscription response
2496 for(idx=0; idx<statsRsp->numGrpRejected; idx++)
2498 actionId = statsRsp->statsGrpRejectedList[idx].groupId;
2499 if(ricSubscriptionInfo->actionSequence[actionId-1].id == actionId)
2501 memset(&ricSubscriptionInfo->actionSequence[actionId-1], 0, sizeof(ActionInfo));
2502 ricSubscriptionInfo->numOfActions--;
2504 pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].id = actionId;
2505 convertDuCauseToE2Cause(statsRsp->statsGrpRejectedList[idx].cause, \
2506 &pendingSubsRsp->rejectedActionList[pendingSubsRsp->numOfRejectedActions].failureCause);
2507 pendingSubsRsp->numOfRejectedActions++;
2511 /* Send subscription response with accepted and rejected action lists to
2513 BuildAndSendRicSubscriptionRsp(pendingSubsRsp);
2516 memset(pendingSubsRsp, 0, sizeof(PendingSubsRspInfo));
2517 DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
2521 DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Received NULL Pointer");
2525 /*******************************************************************
2527 * @brief Process statistics indication from MAC
2531 * Function : DuProcMacStatsInd
2533 * Functionality: Processes statistics indication from MAC.
2537 * @return ROK - success
2540 * ****************************************************************/
2541 uint8_t DuProcMacStatsInd(Pst *pst, MacStatsInd *statsInd)
2546 DU_LOG("\nDEBUG --> DU_APP : DuProcMacStatsInd: Received Statistics Indication");
2547 DU_LOG("\n Subscription Id [%ld]", statsInd->subscriptionId);
2548 DU_LOG("\n Group Id [%d]", statsInd->groupId);
2549 for(int idx = 0; idx < statsInd->numStats; idx++)
2551 DU_LOG("\n Meas type [%d] Meas Value [%lf]", statsInd->measuredStatsList[idx].type,\
2552 statsInd->measuredStatsList[idx].value);
2556 /* TODO : When stats indication is received
2557 * DU APP searches for the message type in E2AP RIC subscription database
2558 * and stores in the value in the list of subscribed measurements
2560 * This will be implemented in next gerrit.
2563 DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsInd, sizeof(MacStatsInd));
2567 DU_LOG("\nINFO --> DU_APP : DuProcMacStatsInd: Received NULL Pointer");
2571 /**********************************************************************
2573 **********************************************************************/