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 **********************************************************************/
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 "kw_env.h" /* RLC environment options */
55 #include "kw.h" /* RLC defines */
60 /* extern (.x) include files */
61 #include "lkw.x" /* LKW */
62 #include "ckw.x" /* CKW */
63 #include "kwu.x" /* KWU */
64 #include "rgu.x" /* RGU */
72 /*****************************************************************************
74 ****************************************************************************/
78 * Handler for binding the RLC upper layer service user with
82 * This function is used by RLC user to request for binding to
83 * RLC. This function is called by the CKW interface to bind
84 * RLC's SAP (identified by spId) with the service user's
85 * SAP (identified by suId).
87 * @param[in] pst Post structure
88 * @param[in] suId Service User ID
89 * @param[in] spId Service provider ID
106 #if (ERRCLASS & ERRCLS_INT_PAR)
107 if (pst->dstInst >= MAX_RLC_INSTANCES)
113 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
115 DU_LOG("\nDEBUG --> RLC_UL : spId(%d), suId(%d)", spId, suId);
116 ckwSap = &(tRlcCb->u.ulCb->ckwSap);
117 /* Take action based on the current state of the SAP */
118 switch(ckwSap->state)
120 /* SAP is configured but not bound */
124 /* copy bind configuration parameters in SSAP sap */
126 ckwSap->pst.dstProcId = pst->srcProcId;
127 ckwSap->pst.dstEnt = pst->srcEnt;
128 ckwSap->pst.dstInst = pst->srcInst;
130 /* Update the State */
131 ckwSap->state = RLC_SAP_BND;
133 DU_LOG("\nDEBUG --> RLC_UL : RlcUiCkwBndReq: state (%d)", ckwSap->state);
138 /* Sap is already bound check source, destination Entity and
140 if (ckwSap->pst.dstProcId != pst->srcProcId ||
141 ckwSap->pst.dstEnt != pst->srcEnt ||
142 ckwSap->pst.dstInst != pst->srcInst ||
143 ckwSap->suId != suId)
145 RLC_SEND_SAPID_ALARM(tRlcCb,
147 LKW_EVENT_CKW_BND_REQ,
148 LCM_CAUSE_INV_PAR_VAL);
150 DU_LOG("\nERROR --> RLC_UL : CKW SAP already Bound");
151 RlcUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
158 #if (ERRCLASS & ERRCLS_INT_PAR)
159 DU_LOG("\nERROR --> RLC_UL : Invalid CKW SAP State in Bind Req");
160 RLC_SEND_SAPID_ALARM(tRlcCb,
162 LKW_EVENT_CKW_BND_REQ,
163 LCM_CAUSE_INV_STATE);
164 #endif /* ERRCLASS & ERRCLS_INT_PAR */
165 RlcUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_NOK);
171 RlcUiCkwBndCfm(&(ckwSap->pst), ckwSap->suId, CM_BND_OK);
178 * Handler for unbinding the RLC upper layer service user CKW with
182 * This function is used by RLC user to request for unbinding
183 * with RLC.This function is called by the CKW interface to
186 * @param[in] pst Post structure
187 * @param[in] spId Service provider SAP ID
188 * @param[in] reason Reason for Unbinding
203 #if (ERRCLASS & ERRCLS_INT_PAR)
204 if (pst->dstInst >= MAX_RLC_INSTANCES)
208 #endif /* ERRCLASS & ERRCLS_INT_PAR */
209 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
211 DU_LOG("\nDEBUG --> RLC_UL : spId(%d), reason(%d)",
217 #if (ERRCLASS & ERRCLS_INT_PAR)
218 RLC_GET_AND_VALIDATE_CKWSAP(tRlcCb,
219 (&(tRlcCb->u.ulCb->ckwSap)),
222 #endif /* ERRCLASS & ERRCLS_INT_PAR */
224 /* disable upper sap (CKW) */
225 tRlcCb->u.ulCb->ckwSap.state = RLC_SAP_CFG;
231 * Handler for configuring RLC entities.
234 * This function is used by RRC to configure(add/delete/modify)
235 * one or more RLC entities.
237 * @param[in] pst - Post structure
238 * @param[in] spId - Serive Provider ID
239 * @param[in] cfg - Configuration information for one or more RLC entities.
252 RlcUlCfgTmpData *cfgTmpData;
254 static uint32_t transCount;
256 #if (ERRCLASS & ERRCLS_INT_PAR)
257 if (pst->dstInst >= MAX_RLC_INSTANCES)
259 RLC_PST_FREE(pst->region, pst->pool, cfg, sizeof(RlcCfgInfo));
263 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
265 RLC_ALLOC(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
267 if (cfgTmpData == NULLP)
269 RLC_PST_FREE(pst->region, pst->pool, cfg, sizeof(RlcCfgInfo));
273 cfgTmpData->uprLyrTransId = cfg->transId; /*Save User TransId*/
274 cfgTmpData->transId = ++transCount; /*Generate new TransId*/
275 cfg->transId = cfgTmpData->transId;
276 cfgTmpData->cfgInfo = cfg;
279 tRlcCb->u.ulCb->rlcUlUdxEventType = pst->event;
280 if (rlcDbmAddUlTransaction(tRlcCb, cfgTmpData) != ROK)
282 DU_LOG("\nERROR --> RLC_UL : Addition to UL transId Lst Failed");
283 RLC_PST_FREE(pst->region, pst->pool, cfg, sizeof(RlcCfgInfo));
288 rlcUlHdlCfgReq(tRlcCb, cfgTmpData, cfg);
289 rlcUlUdxCfgReq(&(RLC_GET_UDX_SAP(tRlcCb)->pst),RLC_GET_UDX_SAP(tRlcCb)->spId,cfg);
296 * Handler to change the UeId
299 * This primitive is used by RRC to change the UeId for the existing UE
302 * @param[in] pst - Point to the pst structure
303 * @param[in] spId - The ID of the service provider SAP in the RLC layer
304 * @param[in] transId - Transaction ID. This field uniquily identifies
305 * transaction between RRC and RLC
306 * @param[in] ueInfo - Old UE Id Info for which the change request has come
307 * @param[in] newUeInfo - New UE Id Info for existing UE context
313 S16 RlcUiCkwUeIdChgReq
324 RlcUlCfgTmpData *cfgTmpData = NULLP;
328 #if (ERRCLASS & ERRCLS_INT_PAR)
329 if (pst->dstInst >= MAX_RLC_INSTANCES)
336 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
338 DU_LOG("\nDEBUG --> RLC_UL : RlcUiCkwUeIdChgReq(pst, spId(%d), transId(%ld))",
342 DU_LOG("\nDEBUG --> RLC_UL : RlcUiCkwUeIdChgReq(pst, spId(%d), transId(%d))\n",
346 RLC_ALLOC(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
353 cfgTmpData->transId = transId;
354 cfgTmpData->ueInfo = ueInfo;
355 cfgTmpData->newUeInfo = newUeInfo;
357 if (rlcDbmAddUlTransaction(tRlcCb, cfgTmpData))
359 DU_LOG("\nERROR --> RLC_UL : Addition to UL transId Lst Failed");
367 /* there was an error in the processing, free up all the memory
368 * that was passed and could have been allocated in this function
370 /* Freeing from proper region */
371 RLC_PST_FREE(pst->region, pst->pool, newUeInfo, sizeof(CkwUeInfo));
372 RLC_PST_FREE(pst->region, pst->pool, ueInfo, sizeof(CkwUeInfo));
376 RLC_FREE(tRlcCb, cfgTmpData, sizeof (RlcUlCfgTmpData));
381 if(ROK != rlcCfgValidateUeIdChng(tRlcCb,ueInfo,newUeInfo,cfgTmpData))
383 DU_LOG("\nERROR --> RLC_UL : Validation Failure for UeId change");
386 rlcUlUdxUeIdChgReq(&(RLC_GET_UDX_SAP(tRlcCb)->pst),
387 RLC_GET_UDX_SAP(tRlcCb)->spId,
398 * Handler for Configuration Request
400 * @param[in] gCb RLC Instance Control Block
401 * @param[in] cfgTmpData Configuration stored in Transaction Block
402 * @param[in] cfg Configuration block
411 RlcUlCfgTmpData *cfgTmpData,
417 cfgTmpData->ueId = cfg->ueId;
418 cfgTmpData->cellId = cfg->cellId;
419 for (idx = 0; idx < cfg->numEnt; idx++)
421 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_OK;
422 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbId = cfg->entCfg[idx].rbId;
423 cfgTmpData->cfgEntData[idx].entUlCfgCfm.rbType = cfg->entCfg[idx].rbType;
424 switch(cfg->entCfg[idx].cfgType)
431 if(cfg->entCfg[idx].dir & RLC_DIR_UL)
433 /* Configuration is for UL , thus validating */
434 if(ROK != rlcCfgValidateUlRb(gCb,
436 &cfgTmpData->cfgEntData[idx],
439 DU_LOG("\nERROR --> RLC_UL : CELLID [%u]:Validation Failure for UL RB [%d]",
440 cfg->cellId,cfg->entCfg[idx].rbId);
441 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
442 /*Validation is getting failed so no need to do configuration at DL.
443 *Set dir as UL, so that no configuration is done at DL */
444 cfg->entCfg[idx].dir = RLC_DIR_UL;
447 if(cfg->entCfg[idx].dir == RLC_DIR_UL)
449 /*If the configuration is for UL only then apply it */
450 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
454 &cfgTmpData->cfgEntData[idx],
460 case CKW_CFG_REESTABLISH:
462 if(cfg->entCfg[idx].dir & RLC_DIR_UL)
464 if(ROK != rlcCfgValidateReEstRb(gCb,
468 &cfgTmpData->cfgEntData[idx]))
470 DU_LOG("\nERROR --> RLC_UL : CellID [%u]:Validation Failure for Reest UL RB [%d]",
471 cfg->cellId,cfg->entCfg[idx].rbId);
472 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
473 /* Setting dir as UL, so that no configuration is done at DL */
474 cfg->entCfg[idx].dir = RLC_DIR_UL;
478 if(cfg->entCfg[idx].dir == RLC_DIR_UL)
480 /*If the configuration is for UL only then apply it */
481 if (cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status == CKW_CFG_CFM_OK)
483 rlcCfgApplyReEstUlRb(gCb,
487 &cfgTmpData->cfgEntData[idx]);
492 case CKW_CFG_DELETE_UE :
494 if(ROK != rlcCfgValidateDelUlUe(gCb,
496 &cfgTmpData->cfgEntData[idx],
499 DU_LOG("\nERROR --> RLC_UL : UL UEID [%d]:Validation Failure",
501 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
502 /* Setting dir as UL, so that no configuration is done at DL */
503 cfg->entCfg[idx].dir = RLC_DIR_UL;
507 case CKW_CFG_DELETE_CELL :
509 if(ROK != rlcCfgValidateDelUlCell(gCb,
512 &cfgTmpData->cfgEntData[idx],
515 DU_LOG("\nERROR --> RLC_UL : Del UL Cell Validation Failure");
516 cfgTmpData->cfgEntData[idx].entUlCfgCfm.status.status = CKW_CFG_CFM_NOK;
517 /* Setting dir as UL, so that no configuration is done at DL */
518 cfg->entCfg[idx].dir = RLC_DIR_UL;
528 /*****************************************************************************
530 ****************************************************************************/
533 * Handler for binding the RLC upper layer service user with
537 * This function is used by RLC user to request for binding to
538 * RLC.This function is called by the KWU interface to bind
539 * RLC's SAP (identified by spId) with the service user's
540 * SAP (identified by suId).
542 * @param[in] pst Post structure
543 * @param[in] suId Service user SAP ID
544 * @param[in] spId Service provider ID
558 RlcKwuSapCb *rlckwuSap; /* SAP Config Block */
561 #if (ERRCLASS & ERRCLS_INT_PAR)
562 if (pst->dstInst >= MAX_RLC_INSTANCES)
567 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
568 DU_LOG("\nDEBUG --> RLC_UL : RlcUiKwuBndReq(pst, spId(%d), suId(%d))", spId, suId);
570 /* Validation of input parameters */
571 #if (ERRCLASS & ERRCLS_INT_PAR)
572 if(!((spId < (S16) tRlcCb->genCfg.maxKwuSaps) && (spId >=0)))
574 DU_LOG("\nERROR --> RLC_UL : Invalid spId");
575 RLC_SEND_SAPID_ALARM(tRlcCb,spId, LKW_EVENT_KWU_BND_REQ, LCM_CAUSE_INV_SAP);
580 /* Get Sap control block */
581 rlckwuSap = (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
582 (tRlcCb->u.dlCb->rlcKwuDlSap + spId):
583 (tRlcCb->u.ulCb->rlcKwuUlSap + spId);
585 /* Take action based on the current state of the SAP */
586 switch(rlckwuSap->state)
588 /* SAP is configured but not bound */
592 /* copy bind configuration parameters in sap */
593 rlckwuSap->suId = suId;
594 rlckwuSap->pst.dstProcId = pst->srcProcId;
595 rlckwuSap->pst.dstEnt = pst->srcEnt;
596 rlckwuSap->pst.dstInst = pst->srcInst;
598 /* Update the State */
599 rlckwuSap->state = RLC_SAP_BND;
601 DU_LOG("\nDEBUG --> RLC_UL : RlcUiKwuBndReq: state (%d)", rlckwuSap->state);
606 /* Sap is already bound check source, destination Entity and Proc Id */
607 if (rlckwuSap->pst.dstProcId != pst->srcProcId ||
608 rlckwuSap->pst.dstEnt != pst->srcEnt ||
609 rlckwuSap->pst.dstInst != pst->srcInst ||
610 rlckwuSap->suId != suId)
612 RLC_SEND_SAPID_ALARM(tRlcCb,
614 LKW_EVENT_KWU_BND_REQ,
615 LCM_CAUSE_INV_PAR_VAL);
616 DU_LOG("\nERROR --> RLC_UL : RLC Mode [%d] : KWU SAP already Bound",
617 tRlcCb->genCfg.rlcMode);
618 RlcUiKwuBndCfm(&(rlckwuSap->pst), rlckwuSap->suId, CM_BND_NOK);
626 #if (ERRCLASS & ERRCLS_INT_PAR)
627 DU_LOG("\nERROR --> RLC_UL : RLC Mode [%d]:Invalid KWU SAP State in Bind Req",
628 tRlcCb->genCfg.rlcMode);
629 RLC_SEND_SAPID_ALARM(tRlcCb,
631 LKW_EVENT_KWU_BND_REQ,
632 LCM_CAUSE_INV_STATE);
633 #endif /* ERRCLASS & ERRCLS_INT_PAR */
634 RlcUiKwuBndCfm(&(rlckwuSap->pst), rlckwuSap->suId, CM_BND_NOK);
638 RlcUiKwuBndCfm(&(rlckwuSap->pst), rlckwuSap->suId, CM_BND_OK);
645 * Handler for unbinding the RLC upper layer service user with
649 * This function is used by RLC user to request for unbinding
650 * with RLC.This function is called by the KWU interface to
653 * @param[in] pst Post structure
654 * @param[in] spId Service provider SAP ID
655 * @param[in] reason Reason for Unbinding
668 RlcKwuSapCb *rlckwuSap; /* KWU SAP control block */
671 #if (ERRCLASS & ERRCLS_INT_PAR)
672 if ((pst->dstInst >= MAX_RLC_INSTANCES) ||
673 (spId >= (S16) rlcCb[pst->dstInst]->genCfg.maxKwuSaps) ||
680 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
682 DU_LOG("\nDEBUG --> RLC_UL : spId(%d), reason(%d)",
686 /* Get Sap control block */
687 rlckwuSap = (tRlcCb->genCfg.rlcMode == LKW_RLC_MODE_DL) ?
688 (tRlcCb->u.dlCb->rlcKwuDlSap + spId):
689 (tRlcCb->u.ulCb->rlcKwuUlSap + spId);
691 rlckwuSap->state = RLC_SAP_CFG;
697 * @brief Handler for receiving the data(SDU) from upper layer.
700 * This function is used by RLC service user (PDCP) to
701 * transfer data (SDU) to RLC.
703 * @param[in] pst Post structure
704 * @param[in] spId Service Provider SAP ID
705 * @param[in] datreq Data Request Information
706 * @param[in] mBuf Data Buffer (SDU)
712 uint8_t rlcProcDlData(Pst *pst, KwuDatReqInfo *datReq, Buffer *mBuf)
714 uint8_t ret = ROK; /* Return Value */
715 RlcDlRbCb *rbCb; /* RB Control Block */
718 DU_LOG("\nDEBUG --> RLC_UL : Received DL Data");
720 #if (ERRCLASS & ERRCLS_INT_PAR)
721 if(pst->dstInst >= MAX_RLC_INSTANCES)
723 ODU_PUT_MSG_BUF(mBuf);
728 tRlcCb = RLC_GET_RLCCB(pst->dstInst);
731 rlcDbmFetchDlRbCbByRbId(tRlcCb, &datReq->rlcId, &rbCb);
734 DU_LOG("\nERROR --> RLC_UL : CellId[%u]:DL RbId [%d] not found",
735 datReq->rlcId.cellId,datReq->rlcId.rbId);
736 ODU_PUT_MSG_BUF(mBuf);
741 /* Dispatch according to mode of the rbCb */
746 /* Verify the user */
747 if (pst->srcEnt != ENTNH)
749 /* kw002.201 Freeing from proper region */
750 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, datReq,
751 sizeof(KwuDatReqInfo));
752 ODU_PUT_MSG_BUF(mBuf);
757 rlcTmmQSdu(tRlcCb,rbCb, datReq, mBuf);
762 rlcUmmQSdu(tRlcCb,rbCb, datReq, mBuf);
768 rlcAmmQSdu(tRlcCb,rbCb, mBuf, datReq);
773 DU_LOG("\nERROR --> RLC_UL : Invalid RB Mode");
783 * Handler for discarding a SDU.
786 * This function is used by RLC AM and RLC UM entities.
787 * This function is called by the service user to discard a particular
788 * RLC SDU if it is present in the SDU queue of the RB control block
789 * and if it is not mapped to any PDU.
791 * @param[in] pst Post structure
792 * @param[in] spId Service Provider SAP ID
793 * @param[in] discSdu SDU discard Information
799 S16 RlcUiKwuDiscSduReq
803 KwuDiscSduInfo *discSdu
806 RLC_SHRABL_STATIC_BUF_FREE(pst->region, pst->pool, discSdu, sizeof(KwuDiscSduInfo));
810 /********************************************************************30**
812 **********************************************************************/