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 /********************************************************************20**
21 Name: NR RLC Layer - Upper Interface Functions
25 Desc: Source code for RLC Upper Interface Module
26 This file contains following functions
39 **********************************************************************/
41 * @file rlc_upr_inf_mgr.c
42 * @brief RLC Upper Interface Module
45 #define RLC_MODULE RLC_DBGMASK_INF
48 /* header (.h) include files */
49 #include "common_def.h"
50 #include "lkw.h" /* LKW defines */
51 #include "ckw.h" /* CKW defines */
52 #include "kwu.h" /* KWU defines */
53 #include "rgu.h" /* RGU defines */
54 #include "rlc_env.h" /* RLC environment options */
58 /* extern (.x) include files */
59 #include "lkw.x" /* LKW */
60 #include "ckw.x" /* CKW */
61 #include "kwu.x" /* KWU */
62 #include "rgu.x" /* RGU */
64 #include "rlc_utils.h" /* RLC defines */
65 #include "rlc_dl_ul_inf.h"
68 /*****************************************************************************
70 ****************************************************************************/
74 * Handler for binding the RLC upper layer service user with
78 * This function is used by RLC user to request for binding to
79 * RLC. This function is called by the CKW interface to bind
80 * RLC's SAP (identified by spId) with the service user's
81 * SAP (identified by suId).
83 * @param[in] pst Post structure
84 * @param[in] suId Service User ID
85 * @param[in] spId Service provider ID
102 #if (ERRCLASS & ERRCLS_INT_PAR)
103 if (pst->dstInst >= MAX_RLC_INSTANCES)
109 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
111 DU_LOG("\nDEBUG --> RLC_UL : spId(%d), suId(%d)", spId, suId);
112 ckwSap = &(tRlcCb->u.ulCb->ckwSap);
113 /* Take action based on the current state of the SAP */
114 switch(ckwSap->state)
116 /* SAP is configured but not bound */
120 /* copy bind configuration parameters in SSAP sap */
122 ckwSap->pst.dstProcId = pst->srcProcId;
123 ckwSap->pst.dstEnt = pst->srcEnt;
124 ckwSap->pst.dstInst = pst->srcInst;
126 /* Update the State */
127 ckwSap->state = RLC_SAP_BND;
129 DU_LOG("\nDEBUG --> RLC_UL : RlcUiCkwBndReq: state (%d)", ckwSap->state);
134 /* Sap is already bound check source, destination Entity and
136 if (ckwSap->pst.dstProcId != pst->srcProcId ||
137 ckwSap->pst.dstEnt != pst->srcEnt ||
138 ckwSap->pst.dstInst != pst->srcInst ||
139 ckwSap->suId != suId)
141 RLC_SEND_SAPID_ALARM(tRlcCb,
143 LKW_EVENT_CKW_BND_REQ,
144 LCM_CAUSE_INV_PAR_VAL);
146 DU_LOG("\nERROR --> RLC_UL : CKW SAP already Bound");
147 RlcUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
154 #if (ERRCLASS & ERRCLS_INT_PAR)
155 DU_LOG("\nERROR --> RLC_UL : Invalid CKW SAP State in Bind Req");
156 RLC_SEND_SAPID_ALARM(tRlcCb,
158 LKW_EVENT_CKW_BND_REQ,
159 LCM_CAUSE_INV_STATE);
160 #endif /* ERRCLASS & ERRCLS_INT_PAR */
161 RlcUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
167 RlcUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_OK);
174 * Handler for unbinding the RLC upper layer service user CKW with
178 * This function is used by RLC user to request for unbinding
179 * with RLC.This function is called by the CKW interface to
182 * @param[in] pst Post structure
183 * @param[in] spId Service provider SAP ID
184 * @param[in] reason Reason for Unbinding
199 #if (ERRCLASS & ERRCLS_INT_PAR)
200 if (pst->dstInst >= MAX_RLC_INSTANCES)
204 #endif /* ERRCLASS & ERRCLS_INT_PAR */
205 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
207 DU_LOG("\nDEBUG --> RLC_UL : spId(%d), reason(%d)",
213 #if (ERRCLASS & ERRCLS_INT_PAR)
214 RLC_GET_AND_VALIDATE_CKWSAP(tRlcCb,
215 (&(tRlcCb->u.ulCb->ckwSap)),
218 #endif /* ERRCLASS & ERRCLS_INT_PAR */
220 /* disable upper sap (CKW) */
221 tRlcCb->u.ulCb->ckwSap.state = RLC_SAP_CFG;
227 * Handler for configuring RLC entities.
230 * This function is used by RRC to configure(add/delete/modify)
231 * one or more RLC entities.
233 * @param[in] pst - Post structure
234 * @param[in] spId - Serive Provider ID
235 * @param[in] cfg - Configuration information for one or more RLC entities.
249 RlcUlCfgTmpData *cfgTmpData;
251 static uint32_t transCount;
253 #if (ERRCLASS & ERRCLS_INT_PAR)
254 if (pst->dstInst >= MAX_RLC_INSTANCES)
256 for(cfgIdx=0; cfgIdx<cfg->numEnt; cfgIdx++)
258 RLC_PST_FREE(pst->region, pst->pool, cfg->entCfg[cfgIdx].snssai, sizeof(Snssai));
260 RLC_PST_FREE(pst->region, pst->pool, cfg, sizeof(RlcCfgInfo));
264 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
266 RLC_ALLOC(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
268 if (cfgTmpData == NULLP)
270 for(cfgIdx=0; cfgIdx<cfg->numEnt; cfgIdx++)
272 RLC_PST_FREE(pst->region, pst->pool, cfg->entCfg[cfgIdx].snssai, sizeof(Snssai));
274 RLC_PST_FREE(pst->region, pst->pool, cfg, sizeof(RlcCfgInfo));
278 cfgTmpData->uprLyrTransId = cfg->transId; /*Save User TransId*/
279 cfgTmpData->transId = ++transCount; /*Generate new TransId*/
280 cfg->transId = cfgTmpData->transId;
281 cfgTmpData->cfgInfo = cfg;
284 tRlcCb->u.ulCb->rlcUlUdxEventType = pst->event;
285 if (rlcDbmAddUlTransaction(tRlcCb, cfgTmpData) != ROK)
287 DU_LOG("\nERROR --> RLC_UL : Addition to UL transId Lst Failed");
288 for(cfgIdx=0; cfgIdx<cfg->numEnt; cfgIdx++)
290 RLC_PST_FREE(pst->region, pst->pool, cfg->entCfg[cfgIdx].snssai, sizeof(Snssai));
292 RLC_PST_FREE(pst->region, pst->pool, cfg, sizeof(RlcCfgInfo));
297 rlcUlHdlCfgReq(tRlcCb, cfgTmpData, cfg);
298 rlcUlUdxCfgReq(&(RLC_GET_UDX_SAP(tRlcCb)->pst),RLC_GET_UDX_SAP(tRlcCb)->spId,cfg);
305 * Handler to change the UeId
308 * This primitive is used by RRC to change the UeId for the existing UE
311 * @param[in] pst - Point to the pst structure
312 * @param[in] spId - The ID of the service provider SAP in the RLC layer
313 * @param[in] transId - Transaction ID. This field uniquily identifies
314 * transaction between RRC and RLC
315 * @param[in] ueInfo - Old UE Id Info for which the change request has come
316 * @param[in] newUeInfo - New UE Id Info for existing UE context
322 S16 RlcUiCkwUeIdChgReq
333 RlcUlCfgTmpData *cfgTmpData = NULLP;
337 #if (ERRCLASS & ERRCLS_INT_PAR)
338 if (pst->dstInst >= MAX_RLC_INSTANCES)
345 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
347 DU_LOG("\nDEBUG --> RLC_UL : RlcUiCkwUeIdChgReq(pst, spId(%d), transId(%ld))",
351 DU_LOG("\nDEBUG --> RLC_UL : RlcUiCkwUeIdChgReq(pst, spId(%d), transId(%d))\n",
355 RLC_ALLOC(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
362 cfgTmpData->transId = transId;
363 cfgTmpData->ueInfo = ueInfo;
364 cfgTmpData->newUeInfo = newUeInfo;
366 if (rlcDbmAddUlTransaction(tRlcCb, cfgTmpData))
368 DU_LOG("\nERROR --> RLC_UL : Addition to UL transId Lst Failed");
376 /* there was an error in the processing, free up all the memory
377 * that was passed and could have been allocated in this function
379 /* Freeing from proper region */
380 RLC_PST_FREE(pst->region, pst->pool, newUeInfo, sizeof(CkwUeInfo));
381 RLC_PST_FREE(pst->region, pst->pool, ueInfo, sizeof(CkwUeInfo));
385 RLC_FREE(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
390 if(ROK != rlcCfgValidateUeIdChng(tRlcCb,ueInfo,newUeInfo,cfgTmpData))
392 DU_LOG("\nERROR --> RLC_UL : Validation Failure for UeId change");
395 rlcUlUdxUeIdChgReq(&(RLC_GET_UDX_SAP(tRlcCb)->pst),
396 RLC_GET_UDX_SAP(tRlcCb)->spId,
407 * Handler for Configuration Request
409 * @param[in] gCb RLC Instance Control Block
410 * @param[in] cfgTmpData Configuration stored in Transaction Block
411 * @param[in] cfg Configuration block
420 RlcUlCfgTmpData *cfgTmpData,
426 cfgTmpData->ueId = cfg->ueId;
427 cfgTmpData->cellId = cfg->cellId;
428 for (idx = 0; idx < cfg->numEnt; idx++)
430 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_OK;
431 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbId = cfg->entCfg[idx].rbId;
432 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbType = cfg->entCfg[idx].rbType;
433 switch(cfg->entCfg[idx].cfgType)
440 if(cfg->entCfg[idx].dir & RLC_DIR_UL)
442 /* Configuration is for UL , thus validating */
443 if(ROK != rlcCfgValidateUlRb(gCb,
445 &cfgTmpData->cfgEntData[idx],
448 DU_LOG("\nERROR --> RLC_UL : CELLID [%u]:Validation Failure for UL RB [%d]",
449 cfg->cellId,cfg->entCfg[idx].rbId);
450 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
451 /*Validation is getting failed so no need to do configuration at DL.
452 *Set dir as UL, so that no configuration is done at DL */
453 cfg->entCfg[idx].dir = RLC_DIR_UL;
456 if(cfg->entCfg[idx].dir == RLC_DIR_UL)
458 /*If the configuration is for UL only then apply it */
459 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
463 &cfgTmpData->cfgEntData[idx],
469 case CKW_CFG_REESTABLISH:
471 if(cfg->entCfg[idx].dir & RLC_DIR_UL)
473 if(ROK != rlcCfgValidateReEstRb(gCb,
477 &cfgTmpData->cfgEntData[idx]))
479 DU_LOG("\nERROR --> RLC_UL : CellID [%u]:Validation Failure for Reest UL RB [%d]",
480 cfg->cellId,cfg->entCfg[idx].rbId);
481 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
482 /* Setting dir as UL, so that no configuration is done at DL */
483 cfg->entCfg[idx].dir = RLC_DIR_UL;
487 if(cfg->entCfg[idx].dir == RLC_DIR_UL)
489 /*If the configuration is for UL only then apply it */
490 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
492 rlcCfgApplyReEstUlRb(gCb,
496 &cfgTmpData->cfgEntData[idx]);
501 case CKW_CFG_DELETE_UE :
503 if(ROK != rlcCfgValidateDelUlUe(gCb,
505 &cfgTmpData->cfgEntData[idx],
508 DU_LOG("\nERROR --> RLC_UL : UL UEID [%d]:Validation Failure",
510 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
511 /* Setting dir as UL, so that no configuration is done at DL */
512 cfg->entCfg[idx].dir = RLC_DIR_UL;
516 case CKW_CFG_DELETE_CELL :
518 if(ROK != rlcCfgValidateDelUlCell(gCb,
521 &cfgTmpData->cfgEntData[idx],
524 DU_LOG("\nERROR --> RLC_UL : Del UL Cell Validation Failure");
525 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
526 /* Setting dir as UL, so that no configuration is done at DL */
527 cfg->entCfg[idx].dir = RLC_DIR_UL;
537 /*****************************************************************************
539 ****************************************************************************/
542 * Handler for binding the RLC upper layer service user with
546 * This function is used by RLC user to request for binding to
547 * RLC.This function is called by the KWU interface to bind
548 * RLC's SAP (identified by spId) with the service user's
549 * SAP (identified by suId).
551 * @param[in] pst Post structure
552 * @param[in] suId Service user SAP ID
553 * @param[in] spId Service provider ID
567 RlcKwuSapCb *rlckwuSap; /* SAP Config Block */
570 #if (ERRCLASS & ERRCLS_INT_PAR)
571 if (pst->dstInst >= MAX_RLC_INSTANCES)
576 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
577 DU_LOG("\nDEBUG --> RLC_UL : RlcUiKwuBndReq(pst, spId(%d), suId(%d))", spId, suId);
579 /* Validation of input parameters */
580 #if (ERRCLASS & ERRCLS_INT_PAR)
581 if(!((spId < (S16) tRlcCb->genCfg.maxKwuSaps) && (spId >=0)))
583 DU_LOG("\nERROR --> RLC_UL : Invalid spId");
584 RLC_SEND_SAPID_ALARM(tRlcCb,spId, LKW_EVENT_KWU_BND_REQ, LCM_CAUSE_INV_SAP);
589 /* Get Sap control block */
590 rlckwuSap = (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
591 (tRlcCb->u.dlCb->rlcKwuDlSap + spId):
592 (tRlcCb->u.ulCb->rlcKwuUlSap + spId);
594 /* Take action based on the current state of the SAP */
595 switch(rlckwuSap->state)
597 /* SAP is configured but not bound */
601 /* copy bind configuration parameters in sap */
602 rlckwuSap->suId = suId;
603 rlckwuSap->pst.dstProcId = pst->srcProcId;
604 rlckwuSap->pst.dstEnt = pst->srcEnt;
605 rlckwuSap->pst.dstInst = pst->srcInst;
607 /* Update the State */
608 rlckwuSap->state = RLC_SAP_BND;
610 DU_LOG("\nDEBUG --> RLC_UL : RlcUiKwuBndReq: state (%d)", rlckwuSap->state);
615 /* Sap is already bound check source, destination Entity and Proc Id */
616 if (rlckwuSap->pst.dstProcId != pst->srcProcId ||
617 rlckwuSap->pst.dstEnt != pst->srcEnt ||
618 rlckwuSap->pst.dstInst != pst->srcInst ||
619 rlckwuSap->suId != suId)
621 RLC_SEND_SAPID_ALARM(tRlcCb,
623 LKW_EVENT_KWU_BND_REQ,
624 LCM_CAUSE_INV_PAR_VAL);
625 DU_LOG("\nERROR --> RLC_UL : RLC Mode [%d] : KWU SAP already Bound",
626 tRlcCb->genCfg.rlcMode);
627 RlcUiKwuBndCfm(&(rlckwuSap->pst), rlckwuSap->suId, CM_BND_NOK);
635 #if (ERRCLASS & ERRCLS_INT_PAR)
636 DU_LOG("\nERROR --> RLC_UL : RLC Mode [%d]:Invalid KWU SAP State in Bind Req",
637 tRlcCb->genCfg.rlcMode);
638 RLC_SEND_SAPID_ALARM(tRlcCb,
640 LKW_EVENT_KWU_BND_REQ,
641 LCM_CAUSE_INV_STATE);
642 #endif /* ERRCLASS & ERRCLS_INT_PAR */
643 RlcUiKwuBndCfm(&(rlckwuSap->pst), rlckwuSap->suId, CM_BND_NOK);
647 RlcUiKwuBndCfm(&(rlckwuSap->pst), rlckwuSap->suId, CM_BND_OK);
654 * Handler for unbinding the RLC upper layer service user with
658 * This function is used by RLC user to request for unbinding
659 * with RLC.This function is called by the KWU interface to
662 * @param[in] pst Post structure
663 * @param[in] spId Service provider SAP ID
664 * @param[in] reason Reason for Unbinding
677 RlcKwuSapCb *rlckwuSap; /* KWU SAP control block */
680 #if (ERRCLASS & ERRCLS_INT_PAR)
681 if ((pst->dstInst >= MAX_RLC_INSTANCES) ||
682 (spId >= (S16) rlcCb[pst->dstInst]->genCfg.maxKwuSaps) ||
689 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
691 DU_LOG("\nDEBUG --> RLC_UL : spId(%d), reason(%d)",
695 /* Get Sap control block */
696 rlckwuSap = (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
697 (tRlcCb->u.dlCb->rlcKwuDlSap + spId):
698 (tRlcCb->u.ulCb->rlcKwuUlSap + spId);
700 rlckwuSap->state = RLC_SAP_CFG;
706 * @brief Handler for receiving the data(SDU) from upper layer.
709 * This function is used by RLC service user (PDCP) to
710 * transfer data (SDU) to RLC.
712 * @param[in] pst Post structure
713 * @param[in] spId Service Provider SAP ID
714 * @param[in] datreq Data Request Information
715 * @param[in] mBuf Data Buffer (SDU)
721 uint8_t rlcProcDlData(Pst *pst, RlcDatReqInfo *datReq, Buffer *mBuf)
723 uint8_t ret = ROK; /* Return Value */
724 RlcDlRbCb *rbCb; /* RB Control Block */
727 DU_LOG("\nDEBUG --> RLC_DL : Received DL Data");
729 #if (ERRCLASS & ERRCLS_INT_PAR)
730 if(pst->dstInst >= MAX_RLC_INSTANCES)
732 ODU_PUT_MSG_BUF(mBuf);
737 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
740 rlcDbmFetchDlRbCbByRbId(tRlcCb, &datReq->rlcId, &rbCb);
743 DU_LOG("\nERROR --> RLC_DL : CellId[%u]:DL RbId [%d] not found",
744 datReq->rlcId.cellId,datReq->rlcId.rbId);
745 ODU_PUT_MSG_BUF(mBuf);
750 /* Dispatch according to mode of the rbCb */
755 /* Verify the user */
756 if (pst->srcEnt != ENTNH)
758 /* kw002.201 Freeing from proper region */
759 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datReq,
760 sizeof(RlcDatReqInfo));
761 ODU_PUT_MSG_BUF(mBuf);
766 rlcTmmQSdu(tRlcCb,rbCb, datReq, mBuf);
771 rlcUmmQSdu(tRlcCb,rbCb, datReq, mBuf);
776 rlcAmmQSdu(tRlcCb,rbCb, mBuf, datReq);
781 DU_LOG("\nERROR --> RLC_DL : Invalid RB Mode");
791 * Handler for discarding a SDU.
794 * This function is used by RLC AM and RLC UM entities.
795 * This function is called by the service user to discard a particular
796 * RLC SDU if it is present in the SDU queue of the RB control block
797 * and if it is not mapped to any PDU.
799 * @param[in] pst Post structure
800 * @param[in] spId Service Provider SAP ID
801 * @param[in] discSdu SDU discard Information
807 S16 RlcUiKwuDiscSduReq
811 KwuDiscSduInfo *discSdu
814 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, discSdu, sizeof(KwuDiscSduInfo));
821 * Handler for Creating, Searching or Deleting SnssnaiTput List.
824 * This function is called whenever a new LC is configured with a snssai.
825 * This function is called to search for Snssai Node during RLC SDU formation
827 * @param[in] gCb RlcCb
828 * @param[in] snssai Snssai to be handled
829 * @param[in] Action Type of action to be handled(Create,Search,Delete)
831 * @return RlcTptPerSnssai
835 RlcTptPerSnssai* rlcHandleSnssaiTputlist(RlcCb *gCb, Snssai *snssai, RlcSnssaiActionType action, Direction dir)
837 CmLListCp *snssaiList = NULLP;
838 CmLList *node = NULLP;
839 RlcTptPerSnssai *snssaiNode = NULLP;
844 snssaiList = gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList;
847 if(snssaiList == NULLP)
849 RLC_ALLOC(gCb, gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList, sizeof(CmLListCp));
850 snssaiList = gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList;
851 cmLListInit(snssaiList);
856 if(snssaiList == NULLP)
858 DU_LOG("\nERROR --> RLC: SNSSAI DL list doesnt exist!");
863 else if(dir == DIR_UL)
865 snssaiList = gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList;
868 if(snssaiList == NULLP)
870 RLC_ALLOC(gCb, gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList, sizeof(CmLListCp));
871 snssaiList = gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList;
872 cmLListInit(snssaiList);
877 if(snssaiList == NULLP)
879 DU_LOG("\nERROR --> RLC: SNSSAI UL list doesnt exist!");
886 DU_LOG("\nERROR --> RLC : Direction:%d is invalid", dir);
890 node = snssaiList->first;
892 /*Traversing the LC LinkList*/
895 snssaiNode = (RlcTptPerSnssai *)node->node;
896 if(memcmp(snssaiNode->snssai, snssai, sizeof(Snssai)) == 0)
898 DU_LOG("\nDEBUG --> RLC : SNSSAI found in LL");
922 /*Allocate the List*/
923 RLC_ALLOC(gCb, snssaiNode, sizeof(RlcTptPerSnssai));
926 RLC_ALLOC(gCb, snssaiNode->snssai, sizeof(Snssai));
927 if(snssaiNode->snssai == NULLP)
929 DU_LOG("\nERROR --> RLC : Allocation of SNSSAI node failed");
932 memcpy(snssaiNode->snssai,snssai,sizeof(Snssai));
933 snssaiNode->dataVol = 0;
937 DU_LOG("\nERROR --> RLC : Allocation of SNSSAI node failed");
942 RLC_ALLOC(gCb, node, sizeof(CmLList));
945 node->node = (PTR)snssaiNode;
946 cmLListAdd2Tail(snssaiList, node);
950 DU_LOG("\nERROR --> RLC : Allocation of SNSSAI node failed");
953 DU_LOG("\nDEBUG --> RLC : SNSSAI node added successfully");
961 node = cmLListDelFrm(snssaiList, node);
962 RLC_FREE(gCb, node, sizeof(CmLList));
963 RLC_FREE(gCb, snssaiNode, sizeof(RlcTptPerSnssai));
964 DU_LOG("\nDEBUG --> RLC : SNSSAI node found and deletion performed");
966 if(snssaiList->count == 0)
968 RLC_FREE(gCb, snssaiList, sizeof(CmLListCp));
969 DU_LOG("\nINFO --> RLC : This SNSSAI was last in the list thus freeing the list also");
974 DU_LOG("\nERROR --> RLC : SNSSAI node not found in List thus no deletion performed");
984 * Handler for Deleting SnssnaiTput List.
987 * This function is called during Shutdown to remove all the snssai entries
988 * and deallocate the SNSSAI tput list as well
990 * @param[in] gCb RlcCb
992 * @return uint_8 (ROK/RFAILED)
995 uint8_t rlcDelTputSnssaiList(RlcCb *gCb, Direction dir)
997 CmLListCp *snssaiList = NULLP;
998 CmLList *node = NULLP, *next = NULLP;
999 RlcTptPerSnssai *snssaiNode = NULLP;
1002 snssaiList = gCb->rlcThpt.snssaiTputInfo.dlTputPerSnssaiList;
1004 else if(dir == DIR_UL)
1006 snssaiList = gCb->rlcThpt.snssaiTputInfo.ulTputPerSnssaiList;
1010 DU_LOG("\nERROR --> RLC: Invalid direction:%d",dir);
1013 if(snssaiList == NULLP)
1015 DU_LOG("\nERROR --> RLC: SnssaiList not exist");
1018 node = snssaiList->first;
1020 /*Traversing the LC LinkList*/
1023 snssaiNode = (RlcTptPerSnssai *)node->node;
1025 node = cmLListDelFrm(snssaiList, node);
1026 RLC_FREE(gCb, node, sizeof(CmLList));
1027 RLC_FREE(gCb, snssaiNode, sizeof(RlcTptPerSnssai));
1030 if(snssaiList->count == 0)
1032 RLC_FREE(gCb, snssaiList, sizeof(CmLListCp));
1033 DU_LOG("\nDEBUG --> RLC : This SNSSAI was last in the list thus freeing the list also");
1040 * Handler for calculating the Tput for each SNSSAI in Tput list after expiry.
1043 * This function is called whenever SNSSAI Tput timer expires and calculate
1044 * Tput for each Snssai in list
1046 * @param[in] SnssaiList A list of Snssai
1051 uint8_t rlcCalculateTputPerSnssai(CmLListCp *snssaiList, Direction dir)
1053 CmLList *node = NULLP;
1054 RlcTptPerSnssai *snssaiNode = NULLP;
1055 uint8_t snssaiCnt = 0;
1057 node = snssaiList->first;
1060 DU_LOG("\n No SNSSAI in list");
1063 /*Traversing the LC LinkList*/
1066 snssaiNode = (RlcTptPerSnssai *)node->node;
1067 snssaiNode->tpt = (double)(snssaiNode->dataVol * 8)/(double)(ODU_SNSSAI_THROUGHPUT_PRINT_TIME_INTERVAL * 0.001);
1071 DU_LOG("\nDEBUG --> RLC_DL: SNSSAI(sst:%d,sd [%d,%d, %d]), DL Tpt : %.5lf", snssaiNode->snssai->sst,\
1072 snssaiNode->snssai->sd[0], snssaiNode->snssai->sd[1],snssaiNode->snssai->sd[2] , snssaiNode->tpt);
1076 DU_LOG("\nDEBUG --> RLC_UL: SNSSAI(sst:%d,sd [%d,%d, %d]), UL Tpt : %.5lf", snssaiNode->snssai->sst,\
1077 snssaiNode->snssai->sd[0], snssaiNode->snssai->sd[1],snssaiNode->snssai->sd[2] , snssaiNode->tpt);
1080 snssaiNode->dataVol = 0;
1087 /********************************************************************30**
1089 **********************************************************************/