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"
33 #include "du_app_rlc_inf.h"
37 #include "du_f1ap_msg_hdl.h"
38 #include "du_ue_mgr.h"
42 #include "du_cell_mgr.h"
46 #include "AlarmInterface.h"
47 #include "CmInterface.h"
48 #include "PmInterface.h"
53 uint8_t numRlcDlSaps = 0;
55 uint8_t numRlcMacSaps = 0;
57 uint8_t macCfgInst = 0;
59 DuCfgParams duCfgParam;
60 uint8_t packRlcConfigReq(Pst *pst, RlcMngmt *cfg);
61 uint8_t cmPkLkwCntrlReq(Pst *pst, RlcMngmt *cfg);
62 uint8_t cmPkLrgCfgReq(Pst *pst, RgMngmt *cfg);
63 uint8_t egtpHdlDatInd(EgtpMsg egtpMsg);
64 uint8_t BuildAndSendDUConfigUpdate();
65 uint16_t getTransId();
66 uint8_t cmPkLrgSchCfgReq(Pst * pst,RgMngmt * cfg);
67 uint8_t sendCellDeleteReqToMac(uint16_t cellId);
69 packMacCellCfgReq packMacCellCfgOpts[] =
71 packMacCellCfg, /* packing for loosely coupled */
72 MacProcCellCfgReq, /* packing for tightly coupled */
73 packMacCellCfg, /* packing for light weight loosly coupled */
76 DuMacCellStart packMacCellStartOpts[] =
78 packMacCellStart, /* Loose coupling */
79 MacProcCellStart, /* TIght coupling */
80 packMacCellStart /* Light weight-loose coupling */
83 DuMacCellStop packMacCellStopOpts[] =
85 packMacCellStop, /* Loose coupling */
86 MacProcCellStop, /* TIght coupling */
87 packMacCellStop /* Light weight-loose coupling */
90 DuMacSliceCfgReq packMacSliceCfgReqOpts[] =
92 packDuMacSliceCfgReq, /* Loose coupling */
93 MacProcSliceCfgReq, /* TIght coupling */
94 packDuMacSliceCfgReq /* Light weight-loose coupling */
98 DuMacSliceRecfgReq packMacSliceRecfgReqOpts[] =
100 packDuMacSliceRecfgReq, /* Loose coupling */
101 MacProcSliceRecfgReq, /* TIght coupling */
102 packDuMacSliceRecfgReq /* Light weight-loose coupling */
105 DuMacStatsReqFunc packMacStatsReqOpts[]=
107 packDuMacStatsReq, /* Loose Coupling */
108 MacProcStatsReq, /* Tight Coupling */
109 packDuMacStatsReq /* Light weight-loose coupling */
112 /**************************************************************************
113 * @brief Function to fill configs required by RLC
117 * Function : duBuildRlcCfg
120 * Initiates general Configs towards RLC
122 * @param[in] Inst Specifies if RLC UL or RLC DL instance
123 * @return ROK - success
126 ***************************************************************************/
127 uint8_t duBuildRlcCfg(Inst inst)
130 RlcGenCfg *genCfg = NULLP;
133 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
134 DU_SET_ZERO(&pst, sizeof(Pst));
136 genCfg = &(rlcMngmt.t.cfg.s.gen);
138 /*----------- Fill General Configuration Parameters ---------*/
139 genCfg->maxUe = duCfgParam.maxUe;
140 genCfg->maxKwuSaps = 2;
141 genCfg->maxUdxSaps = 1;
142 genCfg->rlcMode = (inst == RLC_UL_INST) ?
143 LKW_RLC_MODE_UL : LKW_RLC_MODE_DL;
145 genCfg->maxRguSaps = DEFAULT_CELLS;
147 /*----------- Fill lmPst
148 * Parameters ---------*/
149 genCfg->lmPst.dstProcId = DU_PROC;
150 genCfg->lmPst.srcProcId = DU_PROC;
151 genCfg->lmPst.dstEnt = ENTDUAPP;
152 genCfg->lmPst.dstInst = DU_INST;
153 genCfg->lmPst.srcEnt = ENTRLC;
154 genCfg->lmPst.srcInst = inst;
155 genCfg->lmPst.prior = PRIOR0;
156 genCfg->lmPst.route = RTESPEC;
157 genCfg->lmPst.region = (inst == RLC_UL_INST) ?
158 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
159 genCfg->lmPst.pool = RLC_POOL;
160 genCfg->lmPst.selector = ODU_SELECTOR_LC;
163 rlcMngmt.hdr.msgType = TCFG;
164 rlcMngmt.hdr.msgLen = 0;
165 rlcMngmt.hdr.entId.ent = ENTRLC;
166 rlcMngmt.hdr.entId.inst = (Inst)0;
167 rlcMngmt.hdr.elmId.elmnt = STGEN;
168 rlcMngmt.hdr.seqNmb = 0;
169 rlcMngmt.hdr.version = 0;
170 rlcMngmt.hdr.transId = 0;
171 rlcMngmt.hdr.response.prior = PRIOR0;
172 rlcMngmt.hdr.response.route = RTESPEC;
173 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
174 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
175 rlcMngmt.hdr.response.mem.pool = DU_POOL;
176 rlcMngmt.hdr.response.selector = ODU_SELECTOR_LC;
179 pst.selector = ODU_SELECTOR_LC;
180 pst.srcEnt = ENTDUAPP;
183 pst.dstProcId = DU_PROC;
184 pst.srcProcId = DU_PROC;
185 pst.region = duCb.init.region;
187 DU_LOG("\nDEBUG --> DU_APP : RLC Gen Cfg Req sent for inst %d", inst);
189 /* Send the request to RLC */
190 packRlcConfigReq(&pst, &rlcMngmt);
195 /**************************************************************************
196 * @brief Function to fill configs required by RLC
200 * Function : duBuildRlcLsapCfg
203 * Initiates general Configs towards RLC
205 * @param[in] Inst Specifies if RLC UL or RLC DL instance
206 * @return ROK - success
209 ***************************************************************************/
210 uint8_t duBuildRlcLsapCfg(Ent ent, Inst inst, uint8_t lsapInst)
214 RlcSapCfg *lSap = NULLP;
217 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
218 DU_SET_ZERO(&pst, sizeof(Pst));
221 rlcMngmt.hdr.msgType = TCFG;
222 rlcMngmt.hdr.entId.ent = ENTRLC;
223 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
224 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
226 rlcMngmt.hdr.response.mem.pool = RLC_POOL;
229 pst.selector = ODU_SELECTOR_LC;
230 pst.srcEnt = ENTDUAPP;
232 pst.dstProcId = DU_PROC;
234 pst.srcProcId = DU_PROC;
235 pst.region = duCb.init.region;
236 lSap = &(rlcMngmt.t.cfg.s.sap);
238 lSap->mem.region = (inst == RLC_UL_INST) ?
239 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
240 lSap->mem.pool = RLC_POOL;
242 lSap->bndTmrIntvl = 10;
243 lSap->priority = PRIOR0;
244 lSap->route = RTESPEC;
247 lSap->procId = DU_PROC;
249 lSap->inst = lsapInst;
250 lSap->sapId = lsapInst; /* SapId will be stored as suId in MAC */
251 lSap->selector = (inst == RLC_UL_INST) ? ODU_SELECTOR_LWLC : ODU_SELECTOR_TC;
252 rlcMngmt.hdr.elmId.elmnt = STRGUSAP;
253 DU_LOG("\nDEBUG --> DU_APP : RLC MAC Lower Sap Cfg Req sent for inst %d", inst);
258 lSap->procId = DU_PROC;
260 lSap->inst = (inst == RLC_UL_INST) ?
261 RLC_DL_INST : RLC_UL_INST;
263 lSap->selector = ODU_SELECTOR_LC;
264 rlcMngmt.hdr.elmId.elmnt = STUDXSAP;
265 DU_LOG("\nDEBUG --> DU_APP : RLC DL/UL Lower Sap Cfg Req sent for inst %d", inst);
268 packRlcConfigReq(&pst, &rlcMngmt);
272 /**************************************************************************
273 * @brief Function to fill configs required by RLC
277 * Function : duBuildRlcUsapCfg
280 * Initiates general Configs towards RLC
282 * @param[in] Inst Specifies if RLC UL or RLC DL instance
283 * @return ROK - success
286 ***************************************************************************/
287 uint8_t duBuildRlcUsapCfg(uint8_t elemId, Ent ent, Inst inst)
290 RlcSapCfg *uSap = NULLP;
293 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
294 DU_SET_ZERO(&pst, sizeof(Pst));
296 uSap = &(rlcMngmt.t.cfg.s.sap);
298 uSap->selector = ODU_SELECTOR_LC;
299 uSap->mem.region = (inst == RLC_UL_INST) ?
300 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
301 uSap->mem.pool = RLC_POOL;
304 uSap->procId = DU_PROC;
308 uSap->inst = (inst == RLC_UL_INST) ?
309 RLC_DL_INST : RLC_UL_INST;
310 uSap->bndTmrIntvl = 1000;
311 uSap->priority = PRIOR0;
312 uSap->route = RTESPEC;
315 rlcMngmt.hdr.msgType = TCFG;
316 rlcMngmt.hdr.entId.ent = ENTRLC;
317 rlcMngmt.hdr.elmId.elmnt = STUDXSAP;
318 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
319 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
321 rlcMngmt.hdr.response.mem.pool = RLC_POOL;
324 pst.selector = ODU_SELECTOR_LC;
325 pst.srcEnt = ENTDUAPP;
327 pst.dstProcId = DU_PROC;
329 pst.srcProcId = DU_PROC;
330 pst.region = duCb.init.region;
332 DU_LOG("\nDEBUG --> DU_APP : RLC Kwu Upper Sap Cfg Req sent for inst %d", inst);
333 packRlcConfigReq(&pst, &rlcMngmt);
338 /**************************************************************************
339 * @brief Function to populate internal DS of DU APP
343 * Function : duProcCfgComplete
346 * Populates internal data structures of DU APP after
347 * receiving configurations.
350 * @return ROK - success
353 ***************************************************************************/
354 uint8_t duProcCfgComplete()
358 for(idx=0; idx< DEFAULT_CELLS; idx++)
360 DuCellCb *cell = NULLP;
361 DU_ALLOC(cell, sizeof(DuCellCb));
364 DU_LOG("\nERROR --> DU_APP : Memory Allocation failed in duProcCfgComplete");
370 memset(cell, 0, sizeof(DuCellCb));
371 cell->cellId = NR_CELL_ID; //++cellId;
372 memset(&cell->cellInfo.nrEcgi.plmn, 0, sizeof(Plmn));
373 cell->cellInfo.nrEcgi.plmn.mcc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[0];
374 cell->cellInfo.nrEcgi.plmn.mcc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[1];
375 cell->cellInfo.nrEcgi.plmn.mcc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[2];
376 cell->cellInfo.nrEcgi.plmn.mnc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[0];
377 cell->cellInfo.nrEcgi.plmn.mnc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[1];
378 cell->cellInfo.nrEcgi.plmn.mnc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[2];
379 cell->cellInfo.nrEcgi.cellId = cell->cellId;
380 cell->cellInfo.nrPci = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.nrPci;
381 cell->cellInfo.fiveGsTac = duCfgParam.srvdCellLst[0].duCellInfo.tac;
382 memset(&cell->cellInfo.plmn[idx1], 0, sizeof(Plmn));
383 for(idx1=0; idx1<MAX_PLMN; idx1++)
385 cell->cellInfo.plmn[idx1].mcc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[0];
386 cell->cellInfo.plmn[idx1].mcc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[1];
387 cell->cellInfo.plmn[idx1].mcc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mcc[2];
388 cell->cellInfo.plmn[idx1].mnc[0] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[0];
389 cell->cellInfo.plmn[idx1].mnc[1] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[1];
390 cell->cellInfo.plmn[idx1].mnc[2] = duCfgParam.srvdCellLst[0].duCellInfo.cellInfo.srvdPlmn[0].plmn.mnc[2];
392 cell->cellInfo.maxUe = duCfgParam.maxUe;
393 cell->cellStatus = CELL_OUT_OF_SERVICE;
394 gCellStatus = CELL_DOWN;
395 duCb.cfgCellLst[duCb.numCfgCells] = cell;
401 //Start layer configs
402 ret = duSendRlcUlCfg();
406 /**************************************************************************
407 * @brief Function to invoke DU Layer Configs
411 * Function : duSendRlcUlCfg
414 * Initiates Configs towards layers of DU
417 * @return ROK - success
420 ***************************************************************************/
421 uint8_t duSendRlcUlCfg()
425 duBuildRlcCfg((Inst)RLC_UL_INST);
426 for(cellIdx = 0; cellIdx < DEFAULT_CELLS; cellIdx++)
428 duBuildRlcLsapCfg(ENTMAC, (Inst)RLC_UL_INST, cellIdx);
430 duBuildRlcLsapCfg(ENTRLC, (Inst)RLC_UL_INST, 0);
435 /**************************************************************************
436 * @brief Function to invoke DU Layer Configs
440 * Function : duSendRlcDlCfg
443 * Initiates Configs towards layers of DU
446 * @return ROK - success
449 ***************************************************************************/
450 uint8_t duSendRlcDlCfg()
454 duBuildRlcCfg((Inst)RLC_DL_INST);
455 duBuildRlcUsapCfg(STUDXSAP, ENTRLC, (Inst)RLC_DL_INST);
456 for(cellIdx = 0; cellIdx < DEFAULT_CELLS; cellIdx++)
458 duBuildRlcLsapCfg(ENTMAC, (Inst)RLC_DL_INST, cellIdx);
463 /**************************************************************************
464 * @brief Function to handle Config Confirm from RLC
468 * Function : DuHdlRlcCfgComplete
471 * Handles Gen Config Confirm from RLC
473 * @param[in] Pst *pst, Post structure of the primitive.
474 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC
475 * @return ROK - success
478 ***************************************************************************/
479 uint8_t DuHdlRlcCfgComplete(Pst *pst, RlcMngmt *cfm)
482 if (pst->srcInst == RLC_UL_INST)
484 ret = duProcRlcUlCfgComplete(pst, cfm);
488 ret = duProcRlcDlCfgComplete(pst, cfm);
493 /**************************************************************************
494 * @brief Function to handle Control Config Confirm from RLC
498 * Function : duHdlRlcCntrlCfgComplete
501 * Handles Control Config Confirm from RLC
503 * @param[in] Pst *pst, Post structure of the primitive.
504 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC
505 * @return ROK - success
508 ***************************************************************************/
509 uint8_t duHdlRlcCntrlCfgComplete(Pst *pst, RlcMngmt *cntrl)
513 if (cntrl->cfm.status == LCM_PRIM_OK)
515 switch (cntrl->hdr.elmId.elmnt)
519 if (pst->srcInst == RLC_DL_INST)
521 DU_LOG("\nDEBUG --> DU_APP : BIND OF RLC DL TO MAC (RGU) SAP SUCCESSFUL");
523 if(macCfgInst < DEFAULT_CELLS)
526 duBindUnbindRlcToMacSap((Inst) RLC_DL_INST, ABND);
530 duBindUnbindRlcToMacSap((Inst) RLC_UL_INST, ABND);
535 DU_LOG("\nDEBUG --> DU_APP : BIND OF RLC UL TO MAC (RGU) SAP SUCCESSFUL");
537 if(macCfgInst < DEFAULT_CELLS)
539 duBindUnbindRlcToMacSap((Inst) RLC_UL_INST, ABND);
553 /**************************************************************************
554 * @brief Function to handle Config Confirm from RLC UL
558 * Function : duHdlRlcUlCfgComplete
561 * Handles Config Confirm from RLC UL
563 * @param[in] Pst *pst, Post structure of the primitive.
564 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC UL
565 * @return ROK - success
568 ***************************************************************************/
569 uint8_t duProcRlcUlCfgComplete(Pst *pst, RlcMngmt *cfm)
573 DU_LOG("\nDEBUG --> DU_APP : RLC UL Cfg Status %d", cfm->cfm.status);
574 if (cfm->cfm.status == LCM_PRIM_OK)
576 switch(cfm->hdr.elmId.elmnt)
580 rlcUlCfg |= RLC_GEN_CFG;
586 if(numRlcMacSaps == DEFAULT_CELLS)
588 rlcUlCfg |= RLC_MAC_SAP_CFG;
595 rlcUlCfg |= RLC_UDX_SAP_CFG;
602 DU_LOG("\nDEBUG --> DU_APP : RLC UL Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
603 if(rlcUlCfg == DU_RLC_UL_CONFIGURED)
607 //Start configuration of RLC DL
614 DU_LOG("\nERROR --> DU_APP : Config confirm NOK from RLC UL");
620 /**************************************************************************
621 * @brief Function to handle Config Confirm from RLC DL
625 * Function : duHdlRlcDlCfgComplete
628 * Handles Config Confirm from RLC DL
630 * @param[in] Pst *pst, Post structure of the primitive.
631 * @param[in] RlcMngmt *cfm, Unpacked primitive info received from RLC DL
632 * @return ROK - success
635 ***************************************************************************/
636 uint8_t duProcRlcDlCfgComplete(Pst *pst, RlcMngmt *cfm)
638 DU_LOG("\nDEBUG --> DU_APP : RLC DL Cfg Status %d", cfm->cfm.status);
639 if (cfm->cfm.status == LCM_PRIM_OK)
641 switch(cfm->hdr.elmId.elmnt)
645 rlcDlCfg |= RLC_GEN_CFG;
651 if(numRlcMacSaps == DEFAULT_CELLS)
653 rlcDlCfg |= RLC_MAC_SAP_CFG;
660 rlcDlCfg |= RLC_UDX_SAP_CFG;
668 DU_LOG("\nDEBUG --> DU_APP : RLC DL Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
669 if(rlcDlCfg == DU_RLC_DL_CONFIGURED)
672 //Start configuration of MAC
679 DU_LOG("\nERROR --> DU_APP : Config confirm NOK from RLC DL");
684 /**************************************************************************
685 * @brief Function to send configs to MAC
689 * Function : duSendMacCfg
692 * Initiates Configs towards MAC layer
695 * @return ROK - success
698 ***************************************************************************/
699 uint8_t duSendMacCfg()
702 duBuildMacUsapCfg(RLC_UL_INST);
703 duBuildMacUsapCfg(RLC_DL_INST);
708 /**************************************************************************
709 * @brief Function to fill gen config required by MAC
713 * Function : duBuildMacGenCfg
716 * Initiates general Configs towards MAC
719 * @return ROK - success
722 ***************************************************************************/
723 uint8_t duBuildMacGenCfg()
726 RgGenCfg *genCfg=NULLP;
729 DU_SET_ZERO(&pst, sizeof(Pst));
730 DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
732 genCfg = &(rgMngmt.t.cfg.s.genCfg);
734 /*----------- Fill General Configuration Parameters ---------*/
735 genCfg->mem.region = MAC_MEM_REGION;
736 genCfg->mem.pool = MAC_POOL;
738 genCfg->numRguSaps = 2;
740 genCfg->lmPst.dstProcId = DU_PROC;
741 genCfg->lmPst.srcProcId = DU_PROC;
742 genCfg->lmPst.dstEnt = ENTDUAPP;
743 genCfg->lmPst.dstInst = 0;
744 genCfg->lmPst.srcEnt = ENTMAC;
745 genCfg->lmPst.srcInst = macCfgInst;
746 genCfg->lmPst.prior = PRIOR0;
747 genCfg->lmPst.route = RTESPEC;
748 genCfg->lmPst.region = MAC_MEM_REGION;
749 genCfg->lmPst.pool = MAC_POOL;
750 genCfg->lmPst.selector = ODU_SELECTOR_LC;
753 rgMngmt.hdr.msgType = TCFG;
754 rgMngmt.hdr.msgLen = 0;
755 rgMngmt.hdr.entId.ent = ENTMAC;
756 rgMngmt.hdr.entId.inst = (Inst)0;
757 rgMngmt.hdr.elmId.elmnt = STGEN;
758 rgMngmt.hdr.seqNmb = 0;
759 rgMngmt.hdr.version = 0;
760 rgMngmt.hdr.transId = 0;
762 rgMngmt.hdr.response.prior = PRIOR0;
763 rgMngmt.hdr.response.route = RTESPEC;
764 rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
765 rgMngmt.hdr.response.mem.pool = MAC_POOL;
766 rgMngmt.hdr.response.selector = ODU_SELECTOR_LC;
769 pst.selector = ODU_SELECTOR_LC;
770 pst.srcEnt = ENTDUAPP;
772 pst.dstInst = macCfgInst;
773 pst.dstProcId = DU_PROC;
774 pst.srcProcId = DU_PROC;
775 pst.region = duCb.init.region;
777 DU_LOG("\nDEBUG --> DU_APP : MAC Gen Cfg Req sent");
779 /* Send the request to MAC */
780 cmPkLrgCfgReq(&pst, &rgMngmt);
785 /**************************************************************************
786 * @brief Function to fill USAP config required by MAC
790 * Function : duBuildMacUsapCfg
793 * Initiates USAP Configs towards MAC
795 * @param[in] SpId Specifies if RLC UL or RLC DL instance
796 * @return ROK - success
799 ***************************************************************************/
800 uint8_t duBuildMacUsapCfg(SpId sapId)
803 RgUpSapCfg *uSap = NULLP;
806 DU_SET_ZERO(&pst, sizeof(Pst));
807 DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
809 uSap = &(rgMngmt.t.cfg.s.rguSap);
811 uSap->mem.region = MAC_MEM_REGION;
812 uSap->mem.pool = MAC_POOL;
815 uSap->procId = DU_PROC;
818 uSap->prior = PRIOR0;
819 uSap->route = RTESPEC;
820 uSap->selector = ODU_SELECTOR_LC ;
823 rgMngmt.hdr.msgType = TCFG;
824 rgMngmt.hdr.entId.ent = ENTMAC;
825 rgMngmt.hdr.entId.inst = (Inst)0;
826 rgMngmt.hdr.elmId.elmnt = STRGUSAP;
827 rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
828 rgMngmt.hdr.response.mem.pool = MAC_POOL;
831 pst.selector = ODU_SELECTOR_LC;
832 pst.srcEnt = ENTDUAPP;
834 pst.dstInst = macCfgInst;
835 pst.dstProcId = DU_PROC;
836 pst.srcProcId = DU_PROC;
837 pst.region = duCb.init.region;
839 DU_LOG("\nDEBUG --> DU_APP : MAC Rgu USap Cfg Req sent");
841 /* Send the request to MAC */
842 cmPkLrgCfgReq(&pst, &rgMngmt);
847 /**************************************************************************
848 * @brief Function to handle Config Confirm from MAC
852 * Function : duHdlMacCfgComplete
855 * Handles Gen Config Confirm from MAC
857 * @param[in] Pst *pst, Post structure of the primitive.
858 * @param[in] RgMngmt *cfm, Unpacked primitive info received from MAC
859 * @return ROK - success
862 ***************************************************************************/
863 uint8_t duHdlMacCfgComplete(Pst *pst, RgMngmt *cfm)
867 if (cfm->cfm.status == LCM_PRIM_OK)
869 switch (cfm->hdr.elmId.elmnt)
873 macCfg |= MAC_GEN_CFG;
878 macCfg |= MAC_SAP_CFG;
885 DU_LOG("\nDEBUG --> DU_APP : MAC Cfg Cfm received for the element %d ",cfm->hdr.elmId.elmnt);
886 if(macCfg == MAC_CONFIGURED && numRlcMacSaps == MAX_MAC_SAP)
889 DU_LOG("\nDEBUG --> DU_APP : Completed sending Configs");
891 duBindUnbindRlcToMacSap(RLC_DL_INST, ABND);
897 DU_LOG("\nERROR --> DU_APP : Config confirm NOK from MAC");
903 /**************************************************************************
904 * @brief Function to bind/unbind RLC to MAC SAP
908 * Function : duBindUnbindRlcToMacSap
911 * Initiates Bind/Unbind from RLC to MAC
913 * @param[in] Inst Specifies if RLC UL or RLC DL instance
914 * @param[in] action Specifies if action is bind or unbind
915 * @return ROK - success
918 ***************************************************************************/
919 uint8_t duBindUnbindRlcToMacSap(uint8_t inst, uint8_t action)
921 RlcCntrl *cntrl = NULLP;
926 DU_SET_ZERO(&rlcMngmt, sizeof(RlcMngmt));
927 DU_SET_ZERO(&pst, sizeof(Pst));
931 DU_LOG("\nDEBUG --> DU_APP : Cntrl Req to RLC inst %d to bind MAC sap", inst);
935 DU_LOG("\nDEBUG --> DU_APP : Cntrl Req to RLC inst %d to unbind MAC sap", inst);
937 cntrl = &(rlcMngmt.t.cntrl);
939 cntrl->action = action;
940 cntrl->subAction = DU_ZERO_VAL;
941 cntrl->s.sapCntrl.suId = macCfgInst;
942 cntrl->s.sapCntrl.spId = inst;
945 rlcMngmt.hdr.msgType = TCNTRL;
946 rlcMngmt.hdr.entId.ent = ENTRLC;
947 rlcMngmt.hdr.entId.inst = inst;
948 rlcMngmt.hdr.elmId.elmnt = 186; /* ambiguous defines in lkw.h and lrg.h so direct hardcoded*/
949 rlcMngmt.hdr.response.mem.region = (inst == RLC_UL_INST) ?
950 RLC_UL_MEM_REGION:RLC_DL_MEM_REGION;
951 rlcMngmt.hdr.response.mem.pool = RLC_POOL;
954 pst.selector = ODU_SELECTOR_LC;
955 pst.srcEnt = ENTDUAPP;
957 pst.dstProcId = DU_PROC;
959 pst.srcProcId = DU_PROC;
960 pst.region = duCb.init.region;
962 cmPkLkwCntrlReq(&pst, &rlcMngmt);
966 /*******************************************************************
968 * @brief Handles SCTP notifications
972 * Function : duSctpNtfyHdl
975 * Handles SCTP notification
977 * @params[in] Message Buffer
980 * @return ROK - success
983 * ****************************************************************/
985 uint8_t duSctpNtfyHdl(Buffer *mBuf, CmInetSctpNotification *ntfy)
987 if(f1Params.assocId == ntfy->u.assocChange.assocId)
989 if(BuildAndSendF1SetupReq() != ROK)
994 else if(ricParams.assocId == ntfy->u.assocChange.assocId)
1000 DU_LOG("\nERROR --> DU_APP : Invalid assocId %d received", ntfy->u.assocChange.assocId);
1006 /*******************************************************************
1008 * @brief Fills Pst struct for ENTEGTP
1012 * Function : duFillEgtpPst
1015 * Fills Pst struct for ENTEGTP
1018 * @return ROK - success
1021 * ****************************************************************/
1022 uint8_t duFillEgtpPst(Pst *pst, Event event)
1024 memset(pst, 0, sizeof(Pst));
1025 pst->srcEnt = (Ent)ENTDUAPP;
1026 pst->srcInst = (Inst)DU_INST;
1027 pst->srcProcId = DU_PROC;
1028 pst->dstEnt = (Ent)ENTEGTP;
1029 pst->dstInst = (Inst)EGTP_INST;
1030 pst->dstProcId = pst->srcProcId;
1032 pst->selector = ODU_SELECTOR_LC;
1039 /*******************************************************************
1041 * @brief Function to configure EGTP
1045 * Function : duBuildEgtpCfgReq
1048 * Function to configure EGTP
1051 * @return ROK - success
1054 * ****************************************************************/
1056 uint8_t duBuildEgtpCfgReq()
1061 DU_LOG("\nDEBUG --> DU_APP : Sending EGTP config request");
1063 memset(&egtpCfg, 0, sizeof(EgtpConfig));
1064 memcpy(&egtpCfg, &duCfgParam.egtpParams, sizeof(EgtpConfig));
1066 duFillEgtpPst(&pst, EVTCFGREQ);
1067 packEgtpCfgReq(&pst, egtpCfg);
1072 /*******************************************************************
1074 * @brief Function to configure EGTP
1078 * Function : duBuildEgtpCfgReq
1081 * Function to configure EGTP
1084 * @return ROK - success
1087 * ****************************************************************/
1088 uint8_t duHdlEgtpCfgComplete(CmStatus cfm)
1092 if(cfm.status == LCM_PRIM_OK)
1094 DU_LOG("\nDEBUG --> DU_APP : EGTP configuraton complete");
1095 duSendEgtpSrvOpenReq();
1099 DU_LOG("\nERROR --> DU_APP : EGTP configuraton failed");
1106 /*******************************************************************
1108 * @brief Sends server open request to EGTP
1112 * Function : duSendEgtpSrvOpenReq
1115 * Sends server open request to EGTP
1118 * @return ROK - success
1121 * ****************************************************************/
1123 uint8_t duSendEgtpSrvOpenReq()
1127 DU_LOG("\nDEBUG --> DU_APP : Sending EGTP server open request");
1129 duFillEgtpPst(&pst, EVTSRVOPENREQ);
1130 packEgtpSrvOpenReq(&pst);
1135 /*******************************************************************
1137 * @brief Handles server open confirmation
1141 * Function : duHdlEgtpSrvOpenComplete
1144 * Handles server open confirmation
1147 * @return ROK - success
1150 *****************************************************************/
1152 uint8_t duHdlEgtpSrvOpenComplete(CmStatus cfm)
1156 if(cfm.status == LCM_PRIM_OK)
1158 DU_LOG("\nDEBUG --> DU_APP : EGTP server opened successfully");
1162 DU_LOG("\nERROR --> DU_APP : EGTP server opening failed");
1169 /*******************************************************************
1171 * @brief Sends tunnel management request
1175 * Function : duSendEgtpTnlMgmtReq
1178 * Builds and sends tunnel management request to EGTP
1180 * @params[in] Action
1181 * Local tunnel endpoint id
1182 * Remote tunnel endpoint id
1183 * @return ROK - success
1186 * ****************************************************************/
1188 uint8_t duSendEgtpTnlMgmtReq(uint8_t action, uint32_t teIdTobeMod, GtpTnlCfg *ueCbTnlCfg)
1194 DU_LOG("\nDEBUG --> DU_APP : Sending EGTP tunnel management request for teId [%d]", ueCbTnlCfg->teId);
1196 /* ADD/MOD/DEL per tunnel */
1197 tnlEvt.action = action;
1198 tnlEvt.remTeid = ueCbTnlCfg->teId;
1199 if(action != EGTP_TNL_MGMT_ADD)
1201 tnlEvt.lclTeid = teIdTobeMod;
1205 tnlEvt.lclTeid = ueCbTnlCfg->teId;
1207 duFillEgtpPst(&pst, EVTTNLMGMTREQ);
1208 ret = egtpTnlMgmtReq(&pst, tnlEvt);
1212 /*******************************************************************
1214 * @brief Handles Tunnel management confirm
1218 * Function : duHdlEgtpTnlMgmtCfm
1221 * Handles tunnel management confirm received from Egtp
1223 * @params[in] Tunnel Event
1224 * @return ROK - success
1227 * ****************************************************************/
1228 uint8_t duHdlEgtpTnlMgmtCfm(EgtpTnlEvt tnlEvtCfm)
1232 if(tnlEvtCfm.cfmStatus.status == LCM_PRIM_OK)
1234 DU_LOG("\nDEBUG --> DU_APP: Tunnel management confirm OK");
1238 DU_LOG("\nERROR --> DU_APP: Tunnel management failed");
1245 /*******************************************************************
1247 * @brief Sends UL user data over to EGTP
1251 * Function : duSendEgtpDatInd
1253 * Functionality: Sends UL user data over to EGTP
1255 * @params[in] UL data buffer
1256 * @return ROK - success
1259 * ****************************************************************/
1260 uint8_t duSendEgtpDatInd(Buffer *mBuf)
1264 /* Fill EGTP header */
1265 egtpMsg.msgHdr.msgType = EGTPU_MSG_GPDU;
1266 egtpMsg.msgHdr.nPdu.pres = FALSE;
1267 egtpMsg.msgHdr.seqNum.pres = FALSE;
1268 egtpMsg.msgHdr.extHdr.udpPort.pres = FALSE;
1269 egtpMsg.msgHdr.extHdr.pdcpNmb.pres = FALSE;
1270 egtpMsg.msgHdr.teId = 1;
1273 egtpHdlDatInd(egtpMsg);
1279 /**************************************************************************
1280 * @brief Function to send configs to SCH
1284 * Function : duSendSchCfg
1287 * Sends general config to Scheduler via MAC layer
1290 * @return ROK - success
1293 ***************************************************************************/
1294 uint8_t duSendSchCfg()
1297 RgSchInstCfg *cfg = NULLP;
1300 DU_SET_ZERO(&pst, sizeof(Pst));
1301 DU_SET_ZERO(&rgMngmt, sizeof(RgMngmt));
1303 cfg = &(rgMngmt.t.cfg.s.schInstCfg);
1305 /* Filling of Instance Id */
1306 cfg->instId = DEFAULT_CELLS + 1;
1307 /* Filling of Gen config */
1308 cfg->genCfg.mem.region = MAC_MEM_REGION;
1309 cfg->genCfg.mem.pool = MAC_POOL;
1310 cfg->genCfg.tmrRes = 1;
1313 cfg->genCfg.forceCntrlSrbBoOnPCel = FALSE;
1314 cfg->genCfg.isSCellActDeactAlgoEnable = TRUE;
1316 cfg->genCfg.startCellId = 1;
1317 cfg->genCfg.lmPst.dstProcId = DU_PROC;
1318 cfg->genCfg.lmPst.srcProcId = DU_PROC;
1319 cfg->genCfg.lmPst.dstEnt = ENTDUAPP;
1320 cfg->genCfg.lmPst.dstInst = DU_INST;
1321 cfg->genCfg.lmPst.srcEnt = ENTMAC;
1322 cfg->genCfg.lmPst.srcInst = DEFAULT_CELLS + 1;
1323 cfg->genCfg.lmPst.prior = PRIOR0;
1324 cfg->genCfg.lmPst.route = RTESPEC;
1325 cfg->genCfg.lmPst.region = MAC_MEM_REGION;
1326 cfg->genCfg.lmPst.pool = MAC_POOL;
1327 cfg->genCfg.lmPst.selector = ODU_SELECTOR_LC;
1330 rgMngmt.hdr.msgType = TCFG;
1331 rgMngmt.hdr.entId.ent = ENTMAC;
1332 rgMngmt.hdr.entId.inst = DU_INST;
1333 rgMngmt.hdr.elmId.elmnt = STSCHINST;
1334 rgMngmt.hdr.response.mem.region = MAC_MEM_REGION;
1335 rgMngmt.hdr.response.mem.pool = MAC_POOL;
1338 pst.selector = ODU_SELECTOR_LC;
1339 pst.srcEnt = ENTDUAPP;
1340 pst.dstEnt = ENTMAC;
1341 pst.dstProcId = DU_PROC;
1342 pst.srcProcId = DU_PROC;
1343 pst.srcInst = DU_INST;
1345 pst.region = duCb.init.region;
1346 pst.event = (Event) EVTMACSCHGENCFGREQ;
1348 DU_LOG("\nDEBUG --> DU_APP : MAC Sch Cfg sent");
1350 /* Send the request to MAC */
1351 cmPkLrgSchCfgReq(&pst, &rgMngmt);
1357 /**************************************************************************
1358 * @brief Function to configure SCTP params and
1359 * responsible for F1 and E2 interfaces
1363 * Function : duLayerConfigComplete
1366 * Configures SCTP Params and responsible for handling
1367 * F1 and E2 interface.
1370 * @return ROK - success
1373 ***************************************************************************/
1374 uint8_t duLayerConfigComplete()
1378 DU_LOG("\nINFO --> DU_APP : Configuring all Layer is complete");
1380 if((ret = duSctpCfgReq(duCfgParam.sctpParams)) != ROK)
1382 DU_LOG("\nERROR --> DU_APP : Failed configuring Sctp Params");
1385 if((ret = duSctpAssocReq(F1_INTERFACE)) != ROK)
1387 DU_LOG("\nERROR --> DU_APP : Failed to send AssocReq F1");
1390 if((ret = duSctpAssocReq(E2_INTERFACE)) != ROK)
1392 DU_LOG("\nERROR --> DU_APP : Failed to send AssocReq E2");
1399 /**************************************************************************
1400 * @brief Function to handle SCH Config Confirm from MAC
1404 * Function : duHdlSchCfgComplete
1407 * Handles Scheduler Gen Config Confirm from MAC
1409 * @param[in] Pst *pst, Post structure of the primitive.
1410 * @param[in] RgMngmt *cfm, Unpacked primitive info received from MAC
1411 * @return ROK - success
1414 ***************************************************************************/
1415 uint8_t duHdlSchCfgComplete(Pst *pst, RgMngmt *cfm)
1417 if (cfm->cfm.status == LCM_PRIM_OK)
1419 switch (cfm->hdr.elmId.elmnt)
1423 DU_LOG("\nDEBUG --> DU_APP : Received SCH CFG CFM at DU APP");
1430 duLayerConfigComplete();
1431 duBuildEgtpCfgReq();
1435 /**************************************************************************
1436 * @brief Function to fill and send MacCellconfig
1440 * Function : duBuildAndSendMacCellCfg
1443 * Initiates MAC Configs towards MAC
1446 * @return ROK - success
1449 ***************************************************************************/
1450 uint8_t duBuildAndSendMacCellCfg(uint16_t cellId)
1453 MacCellCfg *duMacCellCfg = NULLP;
1455 DU_ALLOC_SHRABL_BUF(duMacCellCfg, sizeof(MacCellCfg));
1456 if(duMacCellCfg == NULLP)
1461 /* store the address in the duCellCb so that we can free on confirm msg */
1462 if(duCb.actvCellLst[cellId-1])
1463 duCb.actvCellLst[cellId-1]->duMacCellCfg = duMacCellCfg;
1466 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, duMacCellCfg, sizeof(MacCellCfg));
1470 /* copy the mac config structure from duCfgParams */
1471 memcpy(duMacCellCfg,&duCfgParam.macCellCfg,sizeof(MacCellCfg));
1474 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_CONFIG_REQ);
1476 /* Send MAC cell config to MAC */
1477 return (*packMacCellCfgOpts[pst.selector])(&pst, duMacCellCfg);
1480 /**************************************************************************
1481 * @brief Function to Handle MAC cell config confirm
1485 * Function : duHandleMacCellCfgCfm
1488 * Initiates general Configs towards MAC
1491 * @return ROK - success
1494 ***************************************************************************/
1495 uint8_t duHandleMacCellCfgCfm(Pst *pst, MacCellCfgCfm *macCellCfgCfm)
1497 uint8_t actvCellIdx = 0;
1500 for(actvCellIdx = 0; actvCellIdx < MAX_NUM_CELL; actvCellIdx++)
1502 if((duCb.actvCellLst[actvCellIdx]) && (macCellCfgCfm->cellId == duCb.actvCellLst[actvCellIdx]->cellId))
1504 duCb.actvCellLst[actvCellIdx]->duMacCellCfg = NULLP;
1507 if(macCellCfgCfm->rsp == ROK)
1509 /* Build and send GNB-DU config update */
1510 ret = BuildAndSendDUConfigUpdate(SERV_CELL_TO_MODIFY);
1512 /* Build and Send Cell Start Req to MAC */
1513 ret = duBuildAndSendMacCellStart();
1517 /* TODO : Action to be taken if cell configuration fails.
1518 * Should CU be informed? */
1520 DU_LOG("\nERROR --> DU_APP : Mac cell cfg failed");
1526 /*******************************************************************
1528 * @brief Builds and sends cell start request to MAC
1532 * Function : duBuildAndSendMacCellStart
1535 * Builds and sends cell start request to MAC
1538 * @return ROK - success
1541 * ****************************************************************/
1542 uint8_t duBuildAndSendMacCellStart()
1545 CellStartInfo *cellStart = NULL;
1547 DU_LOG("\nINFO --> DU APP : Building and Sending cell start request to MAC");
1549 /* Send Cell Start Request to MAC */
1550 DU_ALLOC_SHRABL_BUF(cellStart, sizeof(CellStartInfo));
1553 DU_LOG("\nERROR --> DU APP : Memory alloc failed while building cell start request");
1557 for(uint8_t id = 0; id < MAX_NUM_CELL; id++)
1559 if(duCb.actvCellLst[id])
1561 cellStart->cellId = duCb.actvCellLst[id]->cellId;
1564 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_START);
1566 return (*packMacCellStartOpts[pst.selector])(&pst, cellStart);
1572 /*******************************************************************
1574 * @brief Builds and sends cell stop request to MAC
1578 * Function : duBuildAndSendMacCellStop
1581 * Builds and sends cell stop request to MAC
1584 * @return ROK - success
1587 * ****************************************************************/
1588 uint8_t duBuildAndSendMacCellStop(uint16_t cellId)
1592 CellStopInfo *cellStop = NULL;
1594 DU_LOG("\nINFO --> DU APP : Building and Sending cell stop request to MAC");
1596 GET_CELL_IDX(cellId, cellIdx);
1597 if(duCb.actvCellLst[cellIdx] != NULLP)
1599 /* Send Cell Stop Request to MAC */
1600 DU_ALLOC_SHRABL_BUF(cellStop, sizeof(CellStopInfo));
1603 DU_LOG("\nERROR --> DU APP : Memory alloc failed while building cell stop request");
1606 memset(cellStop, 0, sizeof(CellStopInfo));
1607 cellStop->cellId = duCb.actvCellLst[cellIdx]->cellId;
1610 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_CELL_STOP);
1612 return (*packMacCellStopOpts[pst.selector])(&pst, cellStop);
1616 DU_LOG("\nERROR --> DU APP : duBuildAndSendMacCellStop(): cellId[%d] doesnot exists", cellId);
1622 /*******************************************************************
1624 * @brief Handles stop indication from MAC
1628 * Function : duHandleStopInd
1631 * Handles stop indication from MAC
1633 * @params[in] Post structure pointer
1634 * @return ROK - success
1637 * ****************************************************************/
1638 uint8_t duHandleStopInd(Pst *pst, OduCellId *cellId)
1640 DuCellCb *cellCb = NULLP;
1642 if(cellId->cellId <=0 || cellId->cellId > MAX_NUM_CELL)
1644 DU_LOG("\nERROR --> DU APP : Invalid Cell Id %d in duHandleStopInd()", cellId->cellId);
1647 if(duGetCellCb(cellId->cellId, &cellCb) != ROK)
1650 if((cellCb->cellStatus == ACTIVATED) || (cellCb->cellStatus == DELETION_IN_PROGRESS))
1652 DU_LOG("\nINFO --> DU APP : 5G-NR Cell %d is DOWN", cellId->cellId);
1653 if(sendCellDeleteReqToMac(cellId->cellId) == RFAILED)
1655 DU_LOG("\nERROR --> DU APP : duHandleStopInd(): Failed to send Cell delete req to MAC for\
1656 cellId[%d]", cellId->cellId);
1662 DU_LOG("\nINFO --> DU APP : Raise cell down alarm for cell id=%d", cellId->cellId);
1663 raiseCellAlrm(CELL_DOWN_ALARM_ID, cellId->cellId);
1664 setCellOpState(cellId->cellId, DISABLED, INACTIVE);
1668 if((pst->selector == ODU_SELECTOR_LWLC) || (pst->selector == ODU_SELECTOR_TC))
1669 DU_FREE_SHRABL_BUF(MAC_MEM_REGION, pst->pool, cellId, sizeof(OduCellId));
1671 cellCb->cellStatus = CELL_OUT_OF_SERVICE; //TODO: cell status must be set to OOS after all UE and cell cleanup which is not
1677 /*******************************************************************
1679 * @brief Handles slot indication from MAC
1683 * Function : duHandleUlCcchInd
1686 * Handles UL CCCH indication from MAC
1688 * @params[in] Post structure pointer
1689 * UL CCCH Ind pointer
1690 * @return ROK - success
1693 * ****************************************************************/
1694 uint8_t duHandleUlCcchInd(Pst *pst, UlCcchIndInfo *ulCcchIndInfo)
1697 DU_LOG("\nINFO --> DU APP : UL CCCH Indication received");
1699 return (duProcUlCcchInd(ulCcchIndInfo));
1702 /*******************************************************************
1704 * @brief Process UL RRC Message from RLC
1708 * Function : DuProcRlcUlRrcMsgTrans
1710 * Functionality: Process UL RRC Message from RLC
1712 * @params[in] Post structure
1713 * UL RRC Message Info
1714 * @return ROK - success
1717 * ****************************************************************/
1718 uint8_t DuProcRlcUlRrcMsgTrans(Pst *pst, RlcUlRrcMsgInfo *ulRrcMsgInfo)
1721 DuCellCb *cellCb = NULLP;
1722 DuUeCb *ueCb = NULLP;
1724 duGetCellCb(ulRrcMsgInfo->cellId, &cellCb);
1727 if(ulRrcMsgInfo->ueId > 0)
1729 if(cellCb->ueCb[ulRrcMsgInfo->ueId -1].gnbDuUeF1apId == ulRrcMsgInfo->ueId)
1730 ueCb = &cellCb->ueCb[ulRrcMsgInfo->ueId -1];
1734 /* If UL message is received for a UE in handover, it signifies that UE is now
1735 * attached to GNB. Hence marking this UE as active and requesting MAC to
1736 * release the dedicated RACH resources */
1737 if(ueCb->ueState == UE_HANDIN_IN_PROGRESS)
1739 ueCb->ueState = UE_ACTIVE;
1740 cellCb->numActvUes++;
1742 /* Release RACH resources */
1743 memset(&ueCb->cfraResource, 0, sizeof(MacCfraResource));
1744 if(duBuildAndSendRachRsrcRelToMac(ulRrcMsgInfo->cellId, ueCb) != ROK)
1746 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Failed to send RACH resource release to MAC");
1750 if(BuildAndSendULRRCMessageTransfer(ueCb, ulRrcMsgInfo->lcId, ulRrcMsgInfo->msgLen, ulRrcMsgInfo->rrcMsg) != ROK)
1752 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Failed to build and send UL RRC Message Transfer");
1758 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : UE ID [%d] not found", ulRrcMsgInfo->ueId);
1764 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Invalid UE ID [%d]", ulRrcMsgInfo->ueId);
1770 DU_LOG("\nERROR --> DU_APP : DuProcRlcUlRrcMsgTrans() : Cell ID [%d] not found", ulRrcMsgInfo->cellId);
1774 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulRrcMsgInfo->rrcMsg, ulRrcMsgInfo->msgLen);
1775 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
1779 /*******************************************************************
1781 * @brief Process RRC delivery report from RLC
1785 * Function : DuProcRlcRrcDeliveryReport
1787 * Functionality: Process RRC delivery Message from RLC
1789 * @params[in] Post structure
1790 * UL RRC Message Info
1791 * @return ROK - success
1794 * ****************************************************************/
1795 uint8_t DuProcRlcRrcDeliveryReport(Pst *pst, RrcDeliveryReport *rrcDeliveryReport)
1797 DuCellCb *cellCb = NULLP;
1799 uint8_t ret = RFAILED;
1801 if(duGetCellCb(rrcDeliveryReport->cellId, &cellCb) != ROK)
1804 ueCb = cellCb->ueCb[rrcDeliveryReport->ueId -1];
1805 ret = BuildAndSendRrcDeliveryReport(ueCb.gnbCuUeF1apId, ueCb.gnbDuUeF1apId,rrcDeliveryReport);
1807 DU_FREE_SHRABL_BUF(pst->region, pst->pool, rrcDeliveryReport, sizeof(RrcDeliveryReport));
1811 /*******************************************************************
1813 * @brief Process UL user data from RLC
1817 * Function : DuProcRlcUlUserDataTrans
1819 * Functionality: Process UL user data from RLC
1821 * @params[in] Post structure
1823 * @return ROK - success
1826 * ****************************************************************/
1827 uint8_t DuProcRlcUlUserDataTrans(Pst *pst, RlcUlUserDatInfo *ulUserData)
1833 DU_LOG("\nDEBUG --> DU APP : Received UL user data");
1835 /* Fill EGTP header */
1836 egtpMsg.msgHdr.msgType = EGTPU_MSG_GPDU;
1837 egtpMsg.msgHdr.nPdu.pres = FALSE;
1838 egtpMsg.msgHdr.seqNum.pres = FALSE;
1839 egtpMsg.msgHdr.extHdr.udpPort.pres = FALSE;
1840 egtpMsg.msgHdr.extHdr.pdcpNmb.pres = FALSE;
1842 /* Fetch EGTP tunnel info */
1843 for(teIdx = 0; teIdx < duCb.numTeId; teIdx++)
1845 /*TODO: If multiple Cell Support is enables then CellId also needs to be validated alongwith ueId and DrbId*/
1846 if((duCb.upTnlCfg[teIdx] != NULLP) && (duCb.upTnlCfg[teIdx]->ueId == ulUserData->ueId) && \
1847 (duCb.upTnlCfg[teIdx]->drbId == ulUserData->rbId))
1849 if(duCb.upTnlCfg[teIdx]->tnlCfg1)
1851 egtpMsg.msgHdr.teId = duCb.upTnlCfg[teIdx]->tnlCfg1->teId; /*As we are supporting only 1 tunnel per DRB*/
1857 if (ODU_GET_MSG_BUF(DU_APP_MEM_REGION, DU_POOL, &mBuf) != ROK)
1859 DU_LOG("\nERROR --> DU APP : Failed to allocated buffer memory in DuProcRlcUlUserDataTrans");
1860 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData->userData, ulUserData->msgLen);
1861 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData, sizeof(RlcUlUserDatInfo));
1864 oduCpyFixBufToMsg(ulUserData->userData, mBuf, ulUserData->msgLen);
1865 ODU_PRINT_MSG(mBuf, 0, 0);
1867 egtpHdlDatInd(egtpMsg);
1869 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData->userData, ulUserData->msgLen);
1870 DU_FREE_SHRABL_BUF(pst->region, pst->pool, ulUserData, sizeof(RlcUlUserDatInfo));
1874 /*******************************************************************
1876 * @brief process the slice cfg rsp received from MAC
1880 * Function : DuProcMacSliceCfgRsp
1882 * Functionality: process the slice cfg rsp received from MAC
1884 * @params[in] Post structure, MacSliceCfgRsp *cfgRsp
1886 * @return ROK - success
1889 **********************************************************************/
1890 uint8_t DuProcMacSliceCfgRsp(Pst *pst, MacSliceCfgRsp *cfgRsp)
1894 if(cfgRsp->rsp == MAC_DU_APP_RSP_OK)
1896 duCb.sliceState = SLICE_CONFIGURED;
1897 DU_LOG("\nINFO --> DU_APP : Slice configured successfully ");
1901 DU_LOG("\nERROR --> DU_APP : Slice not available");
1903 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, cfgRsp, sizeof(MacSliceCfgRsp));
1908 /*******************************************************************
1910 * @brief Fill the slice configration and rrm policy related
1911 * information received form O1
1915 * Function : BuildAndSendSliceConfigReq
1917 * Functionality: Fill the slice configration and rrm policy related
1919 * @params[in] RrmPolicy *rrmPolicy[], uint8_t totalRrmPolicy, uint8_t
1922 * @return ROK - success
1925 * ****************************************************************/
1926 uint8_t BuildAndSendSliceConfigReq()
1929 MacSliceCfgReq *sliceCfgReq;
1931 DU_ALLOC_SHRABL_BUF(sliceCfgReq, sizeof(MacSliceCfgReq));
1932 if(sliceCfgReq == NULLP)
1934 DU_LOG("\nERROR --> DU_APP : Memory allocation failed in BuildAndSendSliceConfigReq");
1939 memcpy(sliceCfgReq, &duCfgParam.tempSliceCfg, sizeof(MacSliceCfgReq));
1940 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_SLICE_CFG_REQ);
1942 DU_LOG("\nDEBUG --> DU_APP : Sending Slice Cfg Request to MAC ");
1943 if((*packMacSliceCfgReqOpts[pst.selector])(&pst, sliceCfgReq) == RFAILED)
1945 DU_LOG("\nERROR --> DU_APP : Failed to send Slice Cfg Req to MAC");
1946 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, sliceCfgReq, sizeof(MacSliceCfgReq));
1952 /*******************************************************************
1954 * @brief Fill the slice configration and rrm policy related
1955 * information received form O1
1959 * Function : BuildAndSendSliceRecfgReq
1961 * Functionality: Fill the slice configration and rrm policy related
1963 * @params[in] RrmPolicy rrmPolicy[], uint8_t totalSliceCount
1965 * @return ROK - success
1968 * ****************************************************************/
1969 uint8_t BuildAndSendSliceRecfgReq()
1972 MacSliceRecfgReq *sliceRecfgReq = NULLP;
1974 DU_LOG("\nINFO --> DU_APP : Slice ReConfiguration Request received");
1976 DU_ALLOC_SHRABL_BUF(sliceRecfgReq, sizeof(MacSliceRecfgReq));
1977 if(sliceRecfgReq == NULLP)
1979 DU_LOG("\nERROR --> DU_APP : Memory allocation failed to BuildAndSendSliceRecfgReq");
1984 memcpy(sliceRecfgReq, &duCfgParam.tempSliceCfg, sizeof(MacSliceRecfgReq));
1986 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_SLICE_RECFG_REQ);
1988 DU_LOG("\nDEBUG --> DU_APP: Sending Slice ReCfg Request to MAC ");
1989 if( (*packMacSliceRecfgReqOpts[pst.selector])(&pst, sliceRecfgReq) == RFAILED)
1991 DU_LOG("\nERROR --> DU_APP: Failed to send Slice ReCfg Req to MAC");
1992 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, sliceRecfgReq, sizeof(MacSliceRecfgReq));
1997 /*******************************************************************
1999 * @brief process the slice ReCfg rsp received from MAC
2003 * Function : DuProcMacSliceRecfgRsp
2005 * Functionality: process the slice ReCfg rsp received from MAC
2007 * @params[in] Post structure, MacSliceRecfgRsp *ReCfgRsp
2009 * @return ROK - success
2012 **********************************************************************/
2013 uint8_t DuProcMacSliceRecfgRsp(Pst *pst, MacSliceRecfgRsp *recfgRsp)
2017 if(recfgRsp->rsp == MAC_DU_APP_RSP_OK)
2019 duCb.sliceState = SLICE_RECONFIGURED;
2020 DU_LOG("\nINFO --> DU_APP : Slice Reconfigured successfully ");
2024 DU_LOG("\nERROR --> DU_APP : Slice not available");
2026 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, recfgRsp, sizeof(MacSliceCfgRsp));
2031 /*******************************************************************
2033 * @brief Handles received Slice Metrics from RLC and forward it to O1
2037 * Function : DuProcRlcSliceMetrics
2040 * Handles received Slice Metrics from RLC and forward it to O1
2042 * @params[in] Post structure pointer
2043 * SlicePmList *sliceStats
2045 * @return ROK - success
2048 * ****************************************************************/
2049 uint8_t DuProcRlcSliceMetrics(Pst *pst, SlicePmList *sliceStats)
2051 uint8_t sliceRecord = 0;
2053 DU_LOG("\nDEBUG --> DU APP : Received Slice Metrics");
2054 if(sliceStats == NULLP)
2056 DU_LOG("\nERROR --> DU APP : Empty Metrics");
2060 for(sliceRecord = 0; sliceRecord < sliceStats->numSlice; sliceRecord++)
2062 DU_LOG("\nINFO --> DU_APP: SliceId[SST-SD]:%d-%d, DlTput %.5lf, UlTput:%.5lf", sliceStats->sliceRecord[sliceRecord].networkSliceIdentifier.sst,\
2063 sliceStats->sliceRecord[sliceRecord].networkSliceIdentifier.sd,sliceStats->sliceRecord[sliceRecord].ThpDl,\
2064 sliceStats->sliceRecord[sliceRecord].ThpUl);
2069 sendSliceMetric((SliceMetricList*) sliceStats);
2073 DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats->sliceRecord, (sliceStats->numSlice) * (sizeof(SlicePm)));
2074 DU_FREE_SHRABL_BUF(pst->region, pst->pool,sliceStats, sizeof(SlicePmList));
2080 /*******************************************************************
2082 * @brief Send Statistics request to MAC
2086 * Function : BuildAndSendStatsReqToMac()
2088 * Functionality: Send Statistics Request To Mac
2092 * @return ROK - success
2095 * ****************************************************************/
2096 uint8_t BuildAndSendStatsReqToMac(uint64_t subscriptionId, RicSubscription *ricSubscriptionInfo)
2099 uint8_t actionIdx = 0, grpIdx = 0, statsIdx = 0;
2100 ActionInfo *actionDb = NULLP;
2101 ActionDefFormat1 *format1Action = NULLP;
2102 MacStatsReq *macStatsReq = NULLP;
2104 /* Fill MAC statistics request */
2105 DU_ALLOC_SHRABL_BUF(macStatsReq, sizeof(MacStatsReq));
2106 if(macStatsReq == NULLP)
2108 DU_LOG("\nERROR --> DU_APP : Memory allocation failed for macStatsReq in BuildAndSendStatsReqToMac");
2112 macStatsReq->subscriptionId = subscriptionId;
2113 for(actionIdx = 0; actionIdx < ricSubscriptionInfo->numOfActions; actionIdx++)
2115 if(ricSubscriptionInfo->actionSequence[actionIdx].action == CONFIG_ADD)
2117 actionDb = &ricSubscriptionInfo->actionSequence[actionIdx];
2118 macStatsReq->statsGrpList[grpIdx].groupId = actionDb->id;
2119 switch(actionDb->definition.formatType)
2123 format1Action = &actionDb->definition.choice.format1;
2124 macStatsReq->statsGrpList[grpIdx].periodicity = format1Action->granularityPeriod;
2126 CmLList *node = NULLP;
2127 MeasurementInfo *measInfo = NULLP;
2129 /* Update DL PRB Usage for all stats group which requested for DL Total PRB Usage */
2130 node = cmLListFirst(&format1Action->measurementInfoList);
2133 measInfo = (MeasurementInfo *)(node->node);
2134 switch(measInfo->measurementTypeId)
2138 macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_DL_TOTAL_PRB_USAGE;
2143 macStatsReq->statsGrpList[grpIdx].statsList[statsIdx++] = MAC_UL_TOTAL_PRB_USAGE;
2148 DU_LOG("\nERROR --> DU_APP : Invalid measurement name BuildAndSendStatsReqToMac");
2154 macStatsReq->statsGrpList[grpIdx].numStats = statsIdx;
2159 DU_LOG("\nERROR --> DU_APP : BuildAndSendStatsReqToMac: Only Action Definition Format 1 supported");
2163 if(macStatsReq->statsGrpList[grpIdx].numStats)
2167 macStatsReq->numStatsGroup = grpIdx;
2169 if(macStatsReq->numStatsGroup)
2171 DU_LOG("\nDEBUG --> DU_APP: Sending Statistics Request to MAC ");
2172 FILL_PST_DUAPP_TO_MAC(pst, EVENT_MAC_STATISTICS_REQ);
2174 if( (*packMacStatsReqOpts[pst.selector])(&pst, macStatsReq) == ROK)
2177 DU_LOG("\nERROR --> DU_APP: Failed to send Statistics Request to MAC");
2180 DU_LOG("\nERROR --> DU_APP: No Statistics group found valid. Hence statistics request is not sent to MAC");
2181 DU_FREE_SHRABL_BUF(DU_APP_MEM_REGION, DU_POOL, macStatsReq, sizeof(MacStatsReq));
2185 /*******************************************************************
2187 * @brief Fetch statistics details from Action Definition Format 1
2191 * Function : FetchStatsFromActionDefFormat1()
2193 * Functionality: Fetch statistics details from Action
2194 * Definition Format 1 received in an E2 message from
2197 * @params[in] ActionDefFormat1
2199 * @return Statistics
2201 * ****************************************************************/
2202 Statistics FetchStatsFromActionDefFormat1(ActionDefFormat1 format1)
2206 /* TODO : When E2AP subscription procedure is implemented:
2207 * Measurement info list is traveresed
2208 * Based on KPI type, stats.macStatsReq or stats.rlcstatsReq is filled */
2210 /* Hardcoding values for now for testing purpose
2211 * Will be removed in next gerrit */
2212 stats.macStatsReq.subscriptionId = 1;
2213 stats.macStatsReq.numStatsGroup = 1;
2214 stats.macStatsReq.statsGrpList[0].groupId = 1;
2215 stats.macStatsReq.statsGrpList[0].periodicity = 100;
2216 stats.macStatsReq.statsGrpList[0].numStats = 2;
2217 stats.macStatsReq.statsGrpList[0].statsList[0] = MAC_DL_TOTAL_PRB_USAGE;
2218 stats.macStatsReq.statsGrpList[0].statsList[1] = MAC_UL_TOTAL_PRB_USAGE;
2223 /*******************************************************************
2225 * @brief Send Statistics request to DU layers
2229 * Function : BuildAndSendStatsReq()
2231 * Functionality: Check if there is an update in statistics
2232 * reporting configuration. If so, send the update to
2235 * @params[in] Subscription Info
2237 * @return ROK - success
2240 * ****************************************************************/
2241 uint8_t BuildAndSendStatsReq(uint16_t ranFuncId, RicSubscription *ricSubscriptionInfo)
2243 uint64_t subscriptionId = 0;
2245 /* Calculate 64 bit subscription-ID :
2246 * First 16 MSB is unused
2247 * Next 16 MSB = RAN-Function-ID
2248 * Next 16 MSB = Requestor-ID in RIC-Request-ID
2249 * Last 16 LSB = Instance-ID in RIC-Request-ID
2251 subscriptionId = ricSubscriptionInfo->requestId.instanceId;
2252 subscriptionId |= ((uint64_t)ricSubscriptionInfo->requestId.requestorId << 16);
2253 subscriptionId |= ((uint64_t)ranFuncId << 32);
2255 /* Build and sent subscription information to MAC in Statistics Request */
2256 if(BuildAndSendStatsReqToMac(subscriptionId, ricSubscriptionInfo) != ROK)
2258 DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToMac()");
2262 /* TODO : When KPI collection from RLC will be supported, this function will be
2263 * called to configure KPIs to be colled */
2265 if(BuildAndSendStatsReqToRlc() != ROK)
2267 DU_LOG("\nERROR --> DU_APP : Failed at BuildAndSendStatsReqToRlc()");
2275 /*******************************************************************
2277 * @brief Process statistics response from MAC
2281 * Function : DuProcMacStatsRsp
2283 * Functionality: Processes statistics configuration response
2284 * from MAC. If configuration is succsessful, DUAPP starts
2285 * reporting period timer for this subscription request
2290 * @return ROK - success
2293 * ****************************************************************/
2294 uint8_t DuProcMacStatsRsp(Pst *pst, MacStatsRsp *statsRsp)
2296 DU_LOG("\nINFO --> DU_APP : DuProcMacStatsRsp: Received Statistics Response from MAC");
2302 DU_LOG("\n Subscription Id [%ld]", statsRsp->subscriptionId);
2304 DU_LOG("\n Number of Accepted Groups [%d]", statsRsp->numGrpAccepted);
2305 for(idx=0; idx<statsRsp->numGrpAccepted; idx++)
2307 DU_LOG("\n Group Id [%d]", statsRsp->statsGrpAcceptedList[idx]);
2310 DU_LOG("\n Number of Rejected Groups [%d]", statsRsp->numGrpRejected);
2311 for(idx=0; idx<statsRsp->numGrpRejected; idx++)
2313 DU_LOG("\n Group Id [%d]", statsRsp->statsGrpRejectedList[idx]);
2318 * For accepted groups:
2319 * Mark scubscrbed-action's -> action = CONFIG_UNKNOWN
2320 * Add action ID to accpeted-action-list in Subscription response
2322 * For rejected groups:
2323 * Remove entry from DU's RAN Function->subscription->actionList
2324 * Add Rejected action Id to reject-action-list created by DU APP while
2325 * processing of subscription request.
2327 * Send subscription response with accepted and rejected action lists to
2331 DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsRsp, sizeof(MacStatsRsp));
2335 DU_LOG("\nERROR --> DU_APP : DuProcMacStatsRsp: Received NULL Pointer");
2339 /*******************************************************************
2341 * @brief Process statistics indication from MAC
2345 * Function : DuProcMacStatsInd
2347 * Functionality: Processes statistics indication from MAC.
2351 * @return ROK - success
2354 * ****************************************************************/
2355 uint8_t DuProcMacStatsInd(Pst *pst, MacStatsInd *statsInd)
2360 DU_LOG("\nDEBUG --> DU_APP : DuProcMacStatsInd: Received Statistics Indication");
2361 DU_LOG("\n Subscription Id [%ld]", statsInd->subscriptionId);
2362 DU_LOG("\n Group Id [%d]", statsInd->groupId);
2363 for(int idx = 0; idx < statsInd->numStats; idx++)
2365 DU_LOG("\n Meas type [%d] Meas Value [%lf]", statsInd->measuredStatsList[idx].type,\
2366 statsInd->measuredStatsList[idx].value);
2370 /* TODO : When stats indication is received
2371 * DU APP searches for the message type in E2AP RIC subscription database
2372 * and stores in the value in the list of subscribed measurements
2374 * This will be implemented in next gerrit.
2377 DU_FREE_SHRABL_BUF(pst->region, pst->pool, statsInd, sizeof(MacStatsInd));
2381 DU_LOG("\nINFO --> DU_APP : DuProcMacStatsInd: Received NULL Pointer");
2385 /**********************************************************************
2387 **********************************************************************/