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 "envopt.h" /* environment options */
54 #include "envdep.h" /* environment dependent */
55 #include "envind.h" /* environment independent */
57 #include "gen.h" /* general */
58 #include "ssi.h" /* system services */
59 #include "cm5.h" /* common timer defines */
60 #include "cm_tkns.h" /* common tokens defines */
61 #include "cm_mblk.h" /* common memory allocation library defines */
62 #include "cm_llist.h" /* common link list defines */
63 #include "cm_hash.h" /* common hash list defines */
64 #include "cm_lte.h" /* common LTE defines */
65 #include "lkw.h" /* LKW defines */
66 #include "ckw.h" /* CKW defines */
67 #include "kwu.h" /* KWU defines */
68 #include "rgu.h" /* RGU defines */
69 #include "kw_env.h" /* RLC environment options */
70 #include "kw.h" /* RLC defines */
75 /* extern (.x) include files */
76 #include "gen.x" /* general */
77 #include "ssi.x" /* system services */
79 #include "cm5.x" /* common timer library */
80 #include "cm_tkns.x" /* common tokens */
81 #include "cm_mblk.x" /* common memory allocation */
82 #include "cm_llist.x" /* common link list */
83 #include "cm_hash.x" /* common hash list */
84 #include "cm_lte.x" /* common LTE includes */
85 #include "cm_lib.x" /* common memory allocation library */
86 #include "lkw.x" /* LKW */
87 #include "ckw.x" /* CKW */
88 #include "kwu.x" /* KWU */
89 #include "rgu.x" /* RGU */
97 /*****************************************************************************
99 ****************************************************************************/
103 * Handler for binding the RLC upper layer service user with
107 * This function is used by RLC user to request for binding to
108 * RLC. This function is called by the CKW interface to bind
109 * RLC's SAP (identified by spId) with the service user's
110 * SAP (identified by suId).
112 * @param[in] pst Post structure
113 * @param[in] suId Service User ID
114 * @param[in] spId Service provider ID
122 PUBLIC S16 KwUiCkwBndReq
129 PUBLIC S16 KwUiCkwBndReq (pst, suId, spId)
140 #if (ERRCLASS & ERRCLS_INT_PAR)
141 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
147 tKwCb = KW_GET_KWCB(pst->dstInst);
149 RLOG2(L_DEBUG, "spId(%d), suId(%d)", spId, suId);
150 ckwSap = &(tKwCb->u.ulCb->ckwSap);
151 /* Take action based on the current state of the SAP */
152 switch(ckwSap->state)
154 /* SAP is configured but not bound */
158 /* copy bind configuration parameters in SSAP sap */
160 ckwSap->pst.dstProcId = pst->srcProcId;
161 ckwSap->pst.dstEnt = pst->srcEnt;
162 ckwSap->pst.dstInst = pst->srcInst;
164 /* Update the State */
165 ckwSap->state = KW_SAP_BND;
167 RLOG1(L_DEBUG, "KwUiCkwBndReq: state (%d)", ckwSap->state);
172 /* Sap is already bound check source, destination Entity and
174 if (ckwSap->pst.dstProcId != pst->srcProcId ||
175 ckwSap->pst.dstEnt != pst->srcEnt ||
176 ckwSap->pst.dstInst != pst->srcInst ||
177 ckwSap->suId != suId)
179 KW_SEND_SAPID_ALARM(tKwCb,
181 LKW_EVENT_CKW_BND_REQ,
182 LCM_CAUSE_INV_PAR_VAL);
184 RLOG0(L_ERROR, "CKW SAP already Bound");
185 KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
192 #if (ERRCLASS & ERRCLS_INT_PAR)
193 RLOG0(L_ERROR, "Invalid CKW SAP State in Bind Req");
194 KW_SEND_SAPID_ALARM(tKwCb,
196 LKW_EVENT_CKW_BND_REQ,
197 LCM_CAUSE_INV_STATE);
198 #endif /* ERRCLASS & ERRCLS_INT_PAR */
199 KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
205 KwUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_OK);
212 * Handler for unbinding the RLC upper layer service user CKW with
216 * This function is used by RLC user to request for unbinding
217 * with RLC.This function is called by the CKW interface to
220 * @param[in] pst Post structure
221 * @param[in] spId Service provider SAP ID
222 * @param[in] reason Reason for Unbinding
229 PUBLIC S16 KwUiCkwUbndReq
236 PUBLIC S16 KwUiCkwUbndReq(pst, spId, reason)
246 #if (ERRCLASS & ERRCLS_INT_PAR)
247 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
251 #endif /* ERRCLASS & ERRCLS_INT_PAR */
252 tKwCb = KW_GET_KWCB(pst->dstInst);
254 RLOG2(L_DEBUG,"spId(%d), reason(%d)",
260 #if (ERRCLASS & ERRCLS_INT_PAR)
261 KW_GET_AND_VALIDATE_CKWSAP(tKwCb,
262 (&(tKwCb->u.ulCb->ckwSap)),
265 #endif /* ERRCLASS & ERRCLS_INT_PAR */
267 /* disable upper sap (CKW) */
268 tKwCb->u.ulCb->ckwSap.state = KW_SAP_CFG;
275 * Handler for configuring RLC entities.
278 * This function is used by RRC to configure(add/delete/modify)
279 * one or more RLC entities.
281 * @param[in] pst - Post structure
282 * @param[in] spId - Serive Provider ID
283 * @param[in] cfg - Configuration information for one or more RLC entities.
290 PUBLIC S16 KwUiCkwCfgReq
297 PUBLIC S16 KwUiCkwCfgReq(pst, spId, cfg)
305 KwUlCfgTmpData *cfgTmpData;
307 static U32 transCount;
312 #if (ERRCLASS & ERRCLS_INT_PAR)
313 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
315 KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
319 tKwCb = KW_GET_KWCB(pst->dstInst);
321 RLOG1(L_DEBUG, "spId(%d)", spId);
323 /* Validate SAP ID under ERRORCLS */
324 KW_VALDATE_SAP(tKwCb, spId, (&(tKwCb->u.ulCb->ckwSap)), ret);
327 KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
331 KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
333 if (cfgTmpData == NULLP)
335 KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
340 cfgTmpData->uprLyrTransId = cfg->transId; /*Save User TransId*/
341 cfgTmpData->transId = ++transCount; /*Generate new TransId*/
342 cfg->transId = cfgTmpData->transId;
343 cfgTmpData->cfgInfo = cfg;
345 if (kwDbmAddUlTransaction(tKwCb, cfgTmpData) != ROK)
347 RLOG0(L_ERROR, "Addition to UL transId Lst Failed");
348 KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo));
353 kwHdlUiCkwUlCfgReq(tKwCb, cfgTmpData, cfg);
355 KwUlUdxCfgReq(&(KW_GET_UDX_SAP(tKwCb)->pst),KW_GET_UDX_SAP(tKwCb)->spId,cfg);
362 * Handler to change the UeId
365 * This primitive is used by RRC to change the UeId for the existing UE
368 * @param[in] pst - Point to the pst structure
369 * @param[in] spId - The ID of the service provider SAP in the RLC layer
370 * @param[in] transId - Transaction ID. This field uniquily identifies
371 * transaction between RRC and RLC
372 * @param[in] ueInfo - Old UE Id Info for which the change request has come
373 * @param[in] newUeInfo - New UE Id Info for existing UE context
380 PUBLIC S16 KwUiCkwUeIdChgReq
389 PUBLIC S16 KwUiCkwUeIdChgReq(pst, spId, transId, ueInfo, newUeInfo)
394 CkwUeInfo *newUeInfo;
399 KwUlCfgTmpData *cfgTmpData = NULLP;
401 TRC3(KwUiCkwUeIdChgReq)
405 #if (ERRCLASS & ERRCLS_INT_PAR)
406 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
413 tKwCb = KW_GET_KWCB(pst->dstInst);
415 RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId,
416 "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%ld))",
420 RLOG_ARG2(L_DEBUG,DBG_CELLID,newUeInfo->cellId,
421 "KwUiCkwUeIdChgReq(pst, spId(%d), transId(%d))\n",
426 KW_ALLOC(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
433 cfgTmpData->transId = transId;
434 cfgTmpData->ueInfo = ueInfo;
435 cfgTmpData->newUeInfo = newUeInfo;
437 if (kwDbmAddUlTransaction(tKwCb, cfgTmpData))
439 RLOG0(L_ERROR, "Addition to UL transId Lst Failed");
447 /* there was an error in the processing, free up all the memory
448 * that was passed and could have been allocated in this function
450 /* Freeing from proper region */
451 KW_PST_FREE(pst->region, pst->pool, newUeInfo, sizeof(CkwUeInfo));
452 KW_PST_FREE(pst->region, pst->pool, ueInfo, sizeof(CkwUeInfo));
456 KW_FREE(tKwCb, cfgTmpData, sizeof (KwUlCfgTmpData));
461 if(ROK != kwCfgValidateUeIdChng(tKwCb,ueInfo,newUeInfo,cfgTmpData))
463 RLOG_ARG0(L_ERROR,DBG_CELLID,cfgTmpData->ueInfo->cellId,
464 "Validation Failure for UeId change");
467 KwUlUdxUeIdChgReq(&(KW_GET_UDX_SAP(tKwCb)->pst),
468 KW_GET_UDX_SAP(tKwCb)->spId,
479 * Handler for Configuration Request
481 * @param[in] gCb RLC Instance Control Block
482 * @param[in] cfgTmpData Configuration stored in Transaction Block
483 * @param[in] cfg Configuration block
490 PUBLIC Void kwHdlUiCkwUlCfgReq
493 KwUlCfgTmpData *cfgTmpData,
497 PUBLIC Void kwHdlUiCkwUlCfgReq(gCb, cfgTmpData, cfg)
499 KwUlCfgTmpData *cfgTmpData;
505 TRC3(kwHdlUiCkwUlCfgReq)
507 cfgTmpData->ueId = cfg->ueId;
508 cfgTmpData->cellId = cfg->cellId;
509 for (idx = 0; idx < cfg->numEnt; idx++)
511 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_OK;
512 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbId = cfg->entCfg[idx].rbId;
513 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbType = cfg->entCfg[idx].rbType;
514 switch(cfg->entCfg[idx].cfgType)
521 if(cfg->entCfg[idx].dir & KW_DIR_UL)
523 /* Configuration is for UL , thus validating */
524 if(ROK != kwCfgValidateUlRb(gCb,
526 &cfgTmpData->cfgEntData[idx],
529 RLOG_ARG2(L_ERROR,DBG_UEID, cfgTmpData->ueId,
530 "CELLID [%u]:Validation Failure for UL RB [%d]",
531 cfg->cellId,cfg->entCfg[idx].rbId);
532 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
533 /*Validation is getting failed so no need to do configuration at DL.
534 *Set dir as UL, so that no configuration is done at DL */
535 cfg->entCfg[idx].dir = KW_DIR_UL;
538 if(cfg->entCfg[idx].dir == KW_DIR_UL)
540 /*If the configuration is for UL only then apply it */
541 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
545 &cfgTmpData->cfgEntData[idx],
551 case CKW_CFG_REESTABLISH:
553 if(cfg->entCfg[idx].dir & KW_DIR_UL)
555 if(ROK != kwCfgValidateReEstRb(gCb,
559 &cfgTmpData->cfgEntData[idx]))
561 RLOG_ARG2(L_ERROR,DBG_UEID,cfg->ueId,
562 "CellID [%u]:Validation Failure for Reest UL RB [%d]",
563 cfg->cellId,cfg->entCfg[idx].rbId);
564 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
565 /* Setting dir as UL, so that no configuration is done at DL */
566 cfg->entCfg[idx].dir = KW_DIR_UL;
570 if(cfg->entCfg[idx].dir == KW_DIR_UL)
572 /*If the configuration is for UL only then apply it */
573 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
575 kwCfgApplyReEstUlRb(gCb,
579 &cfgTmpData->cfgEntData[idx]);
584 case CKW_CFG_DELETE_UE :
586 if(ROK != kwCfgValidateDelUlUe(gCb,
588 &cfgTmpData->cfgEntData[idx],
591 RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->cellId,
592 "UL UEID [%d]:Validation Failure",
594 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
595 /* Setting dir as UL, so that no configuration is done at DL */
596 cfg->entCfg[idx].dir = KW_DIR_UL;
600 case CKW_CFG_DELETE_CELL :
602 if(ROK != kwCfgValidateDelUlCell(gCb,
605 &cfgTmpData->cfgEntData[idx],
608 RLOG_ARG0(L_ERROR,DBG_CELLID,cfg->cellId,
609 "Del UL Cell Validation Failure");
610 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
611 /* Setting dir as UL, so that no configuration is done at DL */
612 cfg->entCfg[idx].dir = KW_DIR_UL;
622 /*****************************************************************************
624 ****************************************************************************/
627 * Handler for binding the RLC upper layer service user with
631 * This function is used by RLC user to request for binding to
632 * RLC.This function is called by the KWU interface to bind
633 * RLC's SAP (identified by spId) with the service user's
634 * SAP (identified by suId).
636 * @param[in] pst Post structure
637 * @param[in] suId Service user SAP ID
638 * @param[in] spId Service provider ID
646 PUBLIC S16 KwUiKwuBndReq
653 PUBLIC S16 KwUiKwuBndReq (pst, suId, spId)
659 KwKwuSapCb *kwuSap; /* SAP Config Block */
664 #if (ERRCLASS & ERRCLS_INT_PAR)
665 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
670 tKwCb = KW_GET_KWCB(pst->dstInst);
671 RLOG2(L_DEBUG, "KwUiKwuBndReq(pst, spId(%d), suId(%d))", spId, suId);
673 /* Validation of input parameters */
674 #if (ERRCLASS & ERRCLS_INT_PAR)
675 if(!((spId < (S16) tKwCb->genCfg.maxKwuSaps) && (spId >=0)))
677 RLOG0(L_ERROR,"Invalid spId");
678 KW_SEND_SAPID_ALARM(tKwCb,spId, LKW_EVENT_KWU_BND_REQ, LCM_CAUSE_INV_SAP);
683 /* Get Sap control block */
684 kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
685 (tKwCb->u.dlCb->kwuDlSap + spId):
686 (tKwCb->u.ulCb->kwuUlSap + spId);
688 /* Take action based on the current state of the SAP */
689 switch(kwuSap->state)
691 /* SAP is configured but not bound */
695 /* copy bind configuration parameters in sap */
697 kwuSap->pst.dstProcId = pst->srcProcId;
698 kwuSap->pst.dstEnt = pst->srcEnt;
699 kwuSap->pst.dstInst = pst->srcInst;
701 /* Update the State */
702 kwuSap->state = KW_SAP_BND;
704 RLOG1(L_DEBUG, "KwUiKwuBndReq: state (%d)", kwuSap->state);
709 /* Sap is already bound check source, destination Entity and Proc Id */
710 if (kwuSap->pst.dstProcId != pst->srcProcId ||
711 kwuSap->pst.dstEnt != pst->srcEnt ||
712 kwuSap->pst.dstInst != pst->srcInst ||
713 kwuSap->suId != suId)
715 KW_SEND_SAPID_ALARM(tKwCb,
717 LKW_EVENT_KWU_BND_REQ,
718 LCM_CAUSE_INV_PAR_VAL);
719 RLOG1(L_ERROR,"RLC Mode [%d] : KWU SAP already Bound",
720 tKwCb->genCfg.rlcMode);
721 KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK);
729 #if (ERRCLASS & ERRCLS_INT_PAR)
730 RLOG1(L_ERROR,"RLC Mode [%d]:Invalid KWU SAP State in Bind Req",
731 tKwCb->genCfg.rlcMode);
732 KW_SEND_SAPID_ALARM(tKwCb,
734 LKW_EVENT_KWU_BND_REQ,
735 LCM_CAUSE_INV_STATE);
736 #endif /* ERRCLASS & ERRCLS_INT_PAR */
737 KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_NOK);
741 KwUiKwuBndCfm(&(kwuSap->pst), kwuSap->suId, CM_BND_OK);
748 * Handler for unbinding the RLC upper layer service user with
752 * This function is used by RLC user to request for unbinding
753 * with RLC.This function is called by the KWU interface to
756 * @param[in] pst Post structure
757 * @param[in] spId Service provider SAP ID
758 * @param[in] reason Reason for Unbinding
765 PUBLIC S16 KwUiKwuUbndReq
772 PUBLIC S16 KwUiKwuUbndReq(pst, spId, reason)
778 KwKwuSapCb *kwuSap; /* KWU SAP control block */
783 #if (ERRCLASS & ERRCLS_INT_PAR)
784 if ((pst->dstInst >= KW_MAX_RLC_INSTANCES) ||
785 (spId >= (S16) kwCb[pst->dstInst]->genCfg.maxKwuSaps) ||
792 tKwCb = KW_GET_KWCB(pst->dstInst);
794 RLOG2(L_DEBUG, "spId(%d), reason(%d)",
798 /* Get Sap control block */
799 kwuSap = (tKwCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
800 (tKwCb->u.dlCb->kwuDlSap + spId):
801 (tKwCb->u.ulCb->kwuUlSap + spId);
803 kwuSap->state = KW_SAP_CFG;
809 * @brief Handler for receiving the data(SDU) from upper layer.
812 * This function is used by RLC service user (PDCP) to
813 * transfer data (SDU) to RLC.
815 * @param[in] pst Post structure
816 * @param[in] spId Service Provider SAP ID
817 * @param[in] datreq Data Request Information
818 * @param[in] mBuf Data Buffer (SDU)
825 PUBLIC S16 KwUiKwuDatReq
829 KwuDatReqInfo *datReq,
833 PUBLIC S16 KwUiKwuDatReq(pst, spId, datReq, mBuf)
836 KwuDatReqInfo *datReq;
840 S16 ret = ROK; /* Return Value */
841 KwDlRbCb *rbCb; /* RB Control Block */
842 KwKwuSapCb *kwuSap; /* SAP Config Block */
847 #if (ERRCLASS & ERRCLS_INT_PAR)
848 if ((pst->dstInst >= KW_MAX_RLC_INSTANCES) ||
849 (spId >= (S16) kwCb[pst->dstInst]->genCfg.maxKwuSaps) ||
857 tKwCb = KW_GET_KWCB(pst->dstInst);
859 /* Get Sap control block */
860 kwuSap = tKwCb->u.dlCb->kwuDlSap + spId;
862 /* Validate SAP ID under ERRORCLS */
863 KW_VALDATE_SAP(tKwCb,spId, kwuSap, ret);
871 kwDbmFetchDlRbCbByRbId(tKwCb, &datReq->rlcId, &rbCb);
874 RLOG_ARG2(L_WARNING, DBG_UEID,datReq->rlcId.ueId, "CellId[%u]:DL RbId [%d] not found",
875 datReq->rlcId.cellId,datReq->rlcId.rbId);
881 /* kw005.201 update the spId received in datReq to update statistics */
882 rbCb->kwuSapId = spId;
883 /* Dispatch according to mode of the rbCb */
888 /* Verify the user */
889 if (pst->srcEnt != ENTNH)
891 /* kw002.201 Freeing from proper region */
892 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datReq,
893 sizeof(KwuDatReqInfo));
899 kwTmmQSdu(tKwCb,rbCb, datReq, mBuf);
900 /* kw005.201 ccpu00117318, updated statistics */
906 kwUmmQSdu(tKwCb,rbCb, datReq, mBuf);
908 /* kw005.201 ccpu00117318, updated statistics */
914 kwAmmQSdu(tKwCb,rbCb, mBuf, datReq);
915 /* kw005.201 ccpu00117318, updated statistics */
921 RLOG0(L_ERROR, "Invalid RB Mode");
931 * Handler for discarding a SDU.
934 * This function is used by RLC AM and RLC UM entities.
935 * This function is called by the service user to discard a particular
936 * RLC SDU if it is present in the SDU queue of the RB control block
937 * and if it is not mapped to any PDU.
939 * @param[in] pst Post structure
940 * @param[in] spId Service Provider SAP ID
941 * @param[in] discSdu SDU discard Information
948 PUBLIC S16 KwUiKwuDiscSduReq
952 KwuDiscSduInfo *discSdu
955 PUBLIC S16 KwUiKwuDiscSduReq(pst, spId, discSdu)
958 KwuDiscSduInfo *discSdu;
961 KW_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, discSdu, sizeof(KwuDiscSduInfo));
965 /********************************************************************30**
967 **********************************************************************/