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: LTE-RLC Layer - Upper Interface Functions
25 Desc: Source code for RLC Upper Interface Module
26 This file contains following functions
39 **********************************************************************/
40 static const char* RLOG_MODULE_NAME="UIM";
41 static int RLOG_MODULE_ID=2048;
42 static int RLOG_FILE_ID=205;
46 * @brief RLC Upper Interface Module
49 #define KW_MODULE KW_DBGMASK_INF
52 /* header (.h) include files */
53 #include "common_def.h"
54 #include "lkw.h" /* LKW defines */
55 #include "ckw.h" /* CKW defines */
56 #include "kwu.h" /* KWU defines */
57 #include "rgu.h" /* RGU defines */
58 #include "kw_env.h" /* RLC environment options */
59 #include "kw.h" /* RLC defines */
64 /* extern (.x) include files */
65 #include "lkw.x" /* LKW */
66 #include "ckw.x" /* CKW */
67 #include "kwu.x" /* KWU */
68 #include "rgu.x" /* RGU */
76 /*****************************************************************************
78 ****************************************************************************/
82 * Handler for binding the RLC upper layer service user with
86 * This function is used by RLC user to request for binding to
87 * RLC. This function is called by the CKW interface to bind
88 * RLC's SAP (identified by spId) with the service user's
89 * SAP (identified by suId).
91 * @param[in] pst Post structure
92 * @param[in] suId Service User ID
93 * @param[in] spId Service provider ID
101 PUBLIC S16 KwUiCkwBndReq
108 PUBLIC S16 KwUiCkwBndReq (pst, suId, spId)
119 #if (ERRCLASS & ERRCLS_INT_PAR)
120 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
126 tKwCb = KW_GET_KWCB(pst->dstInst);
128 RLOG2(L_DEBUG, "spId(%d), suId(%d)", spId, suId);
129 ckwSap = &(tKwCb->u.ulCb->ckwSap);
130 /* Take action based on the current state of the SAP */
131 switch(ckwSap->state)
133 /* SAP is configured but not bound */
137 /* copy bind configuration parameters in SSAP sap */
139 ckwSap->pst.dstProcId = pst->srcProcId;
140 ckwSap->pst.dstEnt = pst->srcEnt;
141 ckwSap->pst.dstInst = pst->srcInst;
143 /* Update the State */
144 ckwSap->state = KW_SAP_BND;
146 RLOG1(L_DEBUG, "KwUiCkwBndReq: state (%d)", ckwSap->state);
151 /* Sap is already bound check source, destination Entity and
153 if (ckwSap->pst.dstProcId != pst->srcProcId ||
154 ckwSap->pst.dstEnt != pst->srcEnt ||
155 ckwSap->pst.dstInst != pst->srcInst ||
156 ckwSap->suId != suId)
158 KW_SEND_SAPID_ALARM(tKwCb,
160 LKW_EVENT_CKW_BND_REQ,
161 LCM_CAUSE_INV_PAR_VAL);
163 RLOG0(L_ERROR, "CKW SAP already Bound");
164 KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
171 #if (ERRCLASS & ERRCLS_INT_PAR)
172 RLOG0(L_ERROR, "Invalid CKW SAP State in Bind Req");
173 KW_SEND_SAPID_ALARM(tKwCb,
175 LKW_EVENT_CKW_BND_REQ,
176 LCM_CAUSE_INV_STATE);
177 #endif /* ERRCLASS & ERRCLS_INT_PAR */
178 KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
184 KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_OK);
191 * Handler for unbinding the RLC upper layer service user CKW with
195 * This function is used by RLC user to request for unbinding
196 * with RLC.This function is called by the CKW interface to
199 * @param[in] pst Post structure
200 * @param[in] spId Service provider SAP ID
201 * @param[in] reason Reason for Unbinding
208 PUBLIC S16 KwUiCkwUbndReq
215 PUBLIC S16 KwUiCkwUbndReq(pst, spId, reason)
225 #if (ERRCLASS & ERRCLS_INT_PAR)
226 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
230 #endif /* ERRCLASS & ERRCLS_INT_PAR */
231 tKwCb = KW_GET_KWCB(pst->dstInst);
233 RLOG2(L_DEBUG,"spId(%d), reason(%d)",
239 #if (ERRCLASS & ERRCLS_INT_PAR)
240 KW_GET_AND_VALIDATE_CKWSAP(tKwCb,
241 (&(tKwCb->u.ulCb->ckwSap)),
244 #endif /* ERRCLASS & ERRCLS_INT_PAR */
246 /* disable upper sap (CKW) */
247 tKwCb->u.ulCb->ckwSap.state = KW_SAP_CFG;
251 /*******************************************************************
253 * @brief Handler for UE create request
257 * Function : RlcDuappProcUeCreateReq
260 * Handler for UE create request
262 * @params[in] pst - Post Structure
263 * cfg - Configuration information for one or more RLC entities
264 * @return ROK - success
267 * ****************************************************************/
268 PUBLIC S16 RlcDuappProcUeCreateReq(Pst *pst, CkwCfgInfo *ueCfg)
275 for(idx = 0; idx < ueCfg->numEnt; idx++)
277 ueCfg->entCfg[idx].cfgType = CKW_CFG_ADD;
280 ret = KwUiCkwCfgReq(pst, ueCfg);
283 } /* RlcDuappUeCreateReq */
288 * Handler for configuring RLC entities.
291 * This function is used by RRC to configure(add/delete/modify)
292 * one or more RLC entities.
294 * @param[in] pst - Post structure
295 * @param[in] spId - Serive Provider ID
296 * @param[in] cfg - Configuration information for one or more RLC entities.
303 PUBLIC S16 KwUiCkwCfgReq
310 //PUBLIC S16 KwUiCkwCfgReq(pst, spId, cfg)
311 PUBLIC S16 KwUiCkwCfgReq(pst, cfg)
318 KwUlCfgTmpData *cfgTmpData;
320 static U32 transCount;
325 #if (ERRCLASS & ERRCLS_INT_PAR)
326 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
328 KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
332 tKwCb = KW_GET_KWCB(pst->dstInst);
334 KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
336 if (cfgTmpData == NULLP)
338 KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
343 cfgTmpData->uprLyrTransId = cfg->transId; /*Save User TransId*/
344 cfgTmpData->transId = ++transCount; /*Generate new TransId*/
345 cfg->transId = cfgTmpData->transId;
346 cfgTmpData->cfgInfo = cfg;
348 if (kwDbmAddUlTransaction(tKwCb, cfgTmpData) != ROK)
350 RLOG0(L_ERROR, "Addition to UL transId Lst Failed");
351 KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
356 kwHdlUiCkwUlCfgReq(tKwCb, cfgTmpData, cfg);
358 KwUlUdxCfgReq(&(KW_GET_UDX_SAP(tKwCb)->pst),KW_GET_UDX_SAP(tKwCb)->spId,cfg);
365 * Handler to change the UeId
368 * This primitive is used by RRC to change the UeId for the existing UE
371 * @param[in] pst - Point to the pst structure
372 * @param[in] spId - The ID of the service provider SAP in the RLC layer
373 * @param[in] transId - Transaction ID. This field uniquily identifies
374 * transaction between RRC and RLC
375 * @param[in] ueInfo - Old UE Id Info for which the change request has come
376 * @param[in] newUeInfo - New UE Id Info for existing UE context
383 PUBLIC S16 KwUiCkwUeIdChgReq
392 PUBLIC S16 KwUiCkwUeIdChgReq(pst, spId, transId, ueInfo, newUeInfo)
397 CkwUeInfo *newUeInfo;
402 KwUlCfgTmpData *cfgTmpData = NULLP;
404 TRC3(KwUiCkwUeIdChgReq)
408 #if (ERRCLASS & ERRCLS_INT_PAR)
409 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
416 tKwCb = KW_GET_KWCB(pst->dstInst);
418 RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId,
419 "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%ld))",
423 RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId,
424 "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%d))\n",
429 KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
436 cfgTmpData->transId = transId;
437 cfgTmpData->ueInfo = ueInfo;
438 cfgTmpData->newUeInfo = newUeInfo;
440 if (kwDbmAddUlTransaction(tKwCb, cfgTmpData))
442 RLOG0(L_ERROR, "Addition to UL transId Lst Failed");
450 /* there was an error in the processing, free up all the memory
451 * that was passed and could have been allocated in this function
453 /* Freeing from proper region */
454 KW_PST_FREE(pst->region, pst->pool, newUeInfo, sizeof(CkwUeInfo));
455 KW_PST_FREE(pst->region, pst->pool, ueInfo, sizeof(CkwUeInfo));
459 KW_FREE(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
464 if(ROK != kwCfgValidateUeIdChng(tKwCb,ueInfo,newUeInfo,cfgTmpData))
466 RLOG_ARG0(L_ERROR,DBG_CELLID,cfgTmpData->ueInfo->cellId,
467 "Validation Failure for UeId change");
470 KwUlUdxUeIdChgReq(&(KW_GET_UDX_SAP(tKwCb)->pst),
471 KW_GET_UDX_SAP(tKwCb)->spId,
482 * Handler for Configuration Request
484 * @param[in] gCb RLC Instance Control Block
485 * @param[in] cfgTmpData Configuration stored in Transaction Block
486 * @param[in] cfg Configuration block
493 PUBLIC Void kwHdlUiCkwUlCfgReq
496 KwUlCfgTmpData *cfgTmpData,
500 PUBLIC Void kwHdlUiCkwUlCfgReq(gCb, cfgTmpData, cfg)
502 KwUlCfgTmpData *cfgTmpData;
508 TRC3(kwHdlUiCkwUlCfgReq)
510 cfgTmpData->ueId = cfg->ueId;
511 cfgTmpData->cellId = cfg->cellId;
512 for (idx = 0; idx < cfg->numEnt; idx++)
514 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_OK;
515 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbId = cfg->entCfg[idx].rbId;
516 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbType = cfg->entCfg[idx].rbType;
517 switch(cfg->entCfg[idx].cfgType)
524 if(cfg->entCfg[idx].dir & KW_DIR_UL)
526 /* Configuration is for UL , thus validating */
527 if(ROK != kwCfgValidateUlRb(gCb,
529 &cfgTmpData->cfgEntData[idx],
532 RLOG_ARG2(L_ERROR,DBG_UEID, cfgTmpData->ueId,
533 "CELLID [%u]:Validation Failure for UL RB [%d]",
534 cfg->cellId,cfg->entCfg[idx].rbId);
535 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
536 /*Validation is getting failed so no need to do configuration at DL.
537 *Set dir as UL, so that no configuration is done at DL */
538 cfg->entCfg[idx].dir = KW_DIR_UL;
541 if(cfg->entCfg[idx].dir == KW_DIR_UL)
543 /*If the configuration is for UL only then apply it */
544 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
548 &cfgTmpData->cfgEntData[idx],
554 case CKW_CFG_REESTABLISH:
556 if(cfg->entCfg[idx].dir & KW_DIR_UL)
558 if(ROK != kwCfgValidateReEstRb(gCb,
562 &cfgTmpData->cfgEntData[idx]))
564 RLOG_ARG2(L_ERROR,DBG_UEID,cfg->ueId,
565 "CellID [%u]:Validation Failure for Reest UL RB [%d]",
566 cfg->cellId,cfg->entCfg[idx].rbId);
567 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
568 /* Setting dir as UL, so that no configuration is done at DL */
569 cfg->entCfg[idx].dir = KW_DIR_UL;
573 if(cfg->entCfg[idx].dir == KW_DIR_UL)
575 /*If the configuration is for UL only then apply it */
576 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
578 kwCfgApplyReEstUlRb(gCb,
582 &cfgTmpData->cfgEntData[idx]);
587 case CKW_CFG_DELETE_UE :
589 if(ROK != kwCfgValidateDelUlUe(gCb,
591 &cfgTmpData->cfgEntData[idx],
594 RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->cellId,
595 "UL UEID [%d]:Validation Failure",
597 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
598 /* Setting dir as UL, so that no configuration is done at DL */
599 cfg->entCfg[idx].dir = KW_DIR_UL;
603 case CKW_CFG_DELETE_CELL :
605 if(ROK != kwCfgValidateDelUlCell(gCb,
608 &cfgTmpData->cfgEntData[idx],
611 RLOG_ARG0(L_ERROR,DBG_CELLID,cfg->cellId,
612 "Del UL Cell Validation Failure");
613 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
614 /* Setting dir as UL, so that no configuration is done at DL */
615 cfg->entCfg[idx].dir = KW_DIR_UL;
625 /*****************************************************************************
627 ****************************************************************************/
630 * Handler for binding the RLC upper layer service user with
634 * This function is used by RLC user to request for binding to
635 * RLC.This function is called by the KWU interface to bind
636 * RLC's SAP (identified by spId) with the service user's
637 * SAP (identified by suId).
639 * @param[in] pst Post structure
640 * @param[in] suId Service user SAP ID
641 * @param[in] spId Service provider ID
649 PUBLIC S16 KwUiKwuBndReq
656 PUBLIC S16 KwUiKwuBndReq (pst, suId, spId)
662 KwKwuSapCb *kwuSap; /* SAP Config Block */
667 #if (ERRCLASS & ERRCLS_INT_PAR)
668 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
673 tKwCb = KW_GET_KWCB(pst->dstInst);
674 RLOG2(L_DEBUG, "KwUiKwuBndReq(pst, spId(%d), suId(%d))", spId, suId);
676 /* Validation of input parameters */
677 #if (ERRCLASS & ERRCLS_INT_PAR)
678 if(!((spId < (S16) tKwCb->genCfg.maxKwuSaps) && (spId >=0)))
680 RLOG0(L_ERROR,"Invalid spId");
681 KW_SEND_SAPID_ALARM(tKwCb,spId, LKW_EVENT_KWU_BND_REQ, LCM_CAUSE_INV_SAP);
686 /* Get Sap control block */
687 kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
688 (tKwCb->u.dlCb->kwuDlSap + spId):
689 (tKwCb->u.ulCb->kwuUlSap + spId);
691 /* Take action based on the current state of the SAP */
692 switch(kwuSap->state)
694 /* SAP is configured but not bound */
698 /* copy bind configuration parameters in sap */
700 kwuSap->pst.dstProcId = pst->srcProcId;
701 kwuSap->pst.dstEnt = pst->srcEnt;
702 kwuSap->pst.dstInst = pst->srcInst;
704 /* Update the State */
705 kwuSap->state = KW_SAP_BND;
707 RLOG1(L_DEBUG, "KwUiKwuBndReq: state (%d)", kwuSap->state);
712 /* Sap is already bound check source, destination Entity and Proc Id */
713 if (kwuSap->pst.dstProcId != pst->srcProcId ||
714 kwuSap->pst.dstEnt != pst->srcEnt ||
715 kwuSap->pst.dstInst != pst->srcInst ||
716 kwuSap->suId != suId)
718 KW_SEND_SAPID_ALARM(tKwCb,
720 LKW_EVENT_KWU_BND_REQ,
721 LCM_CAUSE_INV_PAR_VAL);
722 RLOG1(L_ERROR,"RLC Mode [%d] : KWU SAP already Bound",
723 tKwCb->genCfg.rlcMode);
724 KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK);
732 #if (ERRCLASS & ERRCLS_INT_PAR)
733 RLOG1(L_ERROR,"RLC Mode [%d]:Invalid KWU SAP State in Bind Req",
734 tKwCb->genCfg.rlcMode);
735 KW_SEND_SAPID_ALARM(tKwCb,
737 LKW_EVENT_KWU_BND_REQ,
738 LCM_CAUSE_INV_STATE);
739 #endif /* ERRCLASS & ERRCLS_INT_PAR */
740 KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK);
744 KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_OK);
751 * Handler for unbinding the RLC upper layer service user with
755 * This function is used by RLC user to request for unbinding
756 * with RLC.This function is called by the KWU interface to
759 * @param[in] pst Post structure
760 * @param[in] spId Service provider SAP ID
761 * @param[in] reason Reason for Unbinding
768 PUBLIC S16 KwUiKwuUbndReq
775 PUBLIC S16 KwUiKwuUbndReq(pst, spId, reason)
781 KwKwuSapCb *kwuSap; /* KWU SAP control block */
786 #if (ERRCLASS & ERRCLS_INT_PAR)
787 if ((pst->dstInst >= KW_MAX_RLC_INSTANCES) ||
788 (spId >= (S16) kwCb[pst->dstInst]->genCfg.maxKwuSaps) ||
795 tKwCb = KW_GET_KWCB(pst->dstInst);
797 RLOG2(L_DEBUG, "spId(%d), reason(%d)",
801 /* Get Sap control block */
802 kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
803 (tKwCb->u.dlCb->kwuDlSap + spId):
804 (tKwCb->u.ulCb->kwuUlSap + spId);
806 kwuSap->state = KW_SAP_CFG;
812 * @brief Handler for receiving the data(SDU) from upper layer.
815 * This function is used by RLC service user (PDCP) to
816 * transfer data (SDU) to RLC.
818 * @param[in] pst Post structure
819 * @param[in] spId Service Provider SAP ID
820 * @param[in] datreq Data Request Information
821 * @param[in] mBuf Data Buffer (SDU)
828 PUBLIC S16 KwUiKwuDatReq
831 KwuDatReqInfo *datReq,
835 PUBLIC S16 KwUiKwuDatReq(pst, datReq, mBuf)
837 KwuDatReqInfo *datReq;
841 S16 ret = ROK; /* Return Value */
842 KwDlRbCb *rbCb; /* RB Control Block */
847 DU_LOG("\nRLC : Received DL Data");
849 #if (ERRCLASS & ERRCLS_INT_PAR)
850 if(pst->dstInst >= KW_MAX_RLC_INSTANCES)
857 tKwCb = KW_GET_KWCB(pst->dstInst);
860 kwDbmFetchDlRbCbByRbId(tKwCb, &datReq->rlcId, &rbCb);
863 RLOG_ARG2(L_WARNING, DBG_UEID,datReq->rlcId.ueId, "CellId[%u]:DL RbId [%d] not found",
864 datReq->rlcId.cellId,datReq->rlcId.rbId);
870 /* Dispatch according to mode of the rbCb */
875 /* Verify the user */
876 if (pst->srcEnt != ENTNH)
878 /* kw002.201 Freeing from proper region */
879 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datReq,
880 sizeof(KwuDatReqInfo));
886 kwTmmQSdu(tKwCb,rbCb, datReq, mBuf);
891 kwUmmQSdu(tKwCb,rbCb, datReq, mBuf);
897 kwAmmQSdu(tKwCb,rbCb, mBuf, datReq);
902 RLOG0(L_ERROR, "Invalid RB Mode");
912 * Handler for discarding a SDU.
915 * This function is used by RLC AM and RLC UM entities.
916 * This function is called by the service user to discard a particular
917 * RLC SDU if it is present in the SDU queue of the RB control block
918 * and if it is not mapped to any PDU.
920 * @param[in] pst Post structure
921 * @param[in] spId Service Provider SAP ID
922 * @param[in] discSdu SDU discard Information
929 PUBLIC S16 KwUiKwuDiscSduReq
933 KwuDiscSduInfo *discSdu
936 PUBLIC S16 KwUiKwuDiscSduReq(pst, spId, discSdu)
939 KwuDiscSduInfo *discSdu;
942 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, discSdu, sizeof(KwuDiscSduInfo));
946 /********************************************************************30**
948 **********************************************************************/