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 /**********************************************************************
25 Desc: Defines required by LTE MAC
29 **********************************************************************/
30 static const char* RLOG_MODULE_NAME="UDX";
31 static int RLOG_MODULE_ID=262144;
32 static int RLOG_FILE_ID=203;
34 /* header include files (.h) */
35 #include "envopt.h" /* environment options */
36 #include "envdep.h" /* environment dependent */
37 #include "envind.h" /* environment independent */
39 #include "gen.h" /* general */
40 #include "ssi.h" /* system services */
41 #include "cm5.h" /* common timer defines */
42 #include "cm_tkns.h" /* common tokens defines */
43 #include "cm_mblk.h" /* common memory allocation library defines */
44 #include "cm_llist.h" /* common link list defines */
45 #include "cm_hash.h" /* common hash list defines */
46 #include "cm_lte.h" /* common LTE defines */
47 #include "lkw.h" /* LKW defines */
48 #include "ckw.h" /* CKW defines */
49 #include "kwu.h" /* KWU defines */
50 #include "rgu.h" /* RGU defines */
51 #include "kw_err.h" /* Err defines */
52 #include "kw_env.h" /* RLC environment options */
54 #include "kw.h" /* RLC defines */
58 /* extern (.x) include files */
59 #include "gen.x" /* general */
60 #include "ssi.x" /* system services */
62 #include "cm5.x" /* common timer library */
63 #include "cm_tkns.x" /* common tokens */
64 #include "cm_mblk.x" /* common memory allocation */
65 #include "cm_llist.x" /* common link list */
66 #include "cm_hash.x" /* common hash list */
67 #include "cm_lte.x" /* common LTE includes */
68 #include "cm_lib.x" /* common memory allocation library */
69 #include "lkw.x" /* LKW */
70 #include "ckw.x" /* CKW */
71 #include "kwu.x" /* KWU */
72 #include "rgu.x" /* RGU */
79 #define KW_MODULE KW_DBGMASK_UDX
82 EXTERN S16 kwDlmHndlStaRsp ARGS (( KwCb *gCb,KwDlRbCb *rbCb,
83 KwUdxStaPdu *pStaPdu, KwUdxBufLst *rlsPduLst));
96 * Handler to bind the DL with UL.
98 * @param[in] pst Post structure
99 * @param[in] suId Service user SAP ID
100 * @param[in] spId Service provider ID
107 PUBLIC S16 KwDlUdxBndReq
114 PUBLIC S16 KwDlUdxBndReq (pst, suId, spId)
120 KwUdxDlSapCb *udxSap; /* pointer to session SAP */
125 #if (ERRCLASS & ERRCLS_INT_PAR)
126 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
131 tKwCb = KW_GET_KWCB(pst->dstInst);
133 KWDBGP_BRIEF(tKwCb, "KwDlUdxBndReq(spId(%d), suId(%d))\n",
136 udxSap = (tKwCb->u.dlCb->udxDlSap + spId);
138 /* Verify CKW SAP State */
139 switch(udxSap->state)
141 /* SAP is configured but not bound */
145 /* copy bind configuration parameters in SSAP sap */
147 udxSap->pst.dstProcId = pst->srcProcId;
148 udxSap->pst.dstEnt = pst->srcEnt;
149 udxSap->pst.dstInst = pst->srcInst;
151 /* Update the State */
152 udxSap->state = KW_SAP_BND;
154 RLOG1(L_INFO, "UDX SAP state [%d]", udxSap->state);
157 /* SAP is already bound */
161 * Sap is already bound check source, destination Entity and
164 if (udxSap->pst.dstProcId != pst->srcProcId
165 || udxSap->pst.dstEnt != pst->srcEnt
166 || udxSap->pst.dstInst != pst->srcInst
167 || udxSap->suId != suId)
169 KW_SEND_SAPID_ALARM(tKwCb, spId,
170 LKW_EVENT_UDX_BND_REQ, LCM_CAUSE_INV_PAR_VAL);
172 RLOG0(L_ERROR, "UDX SAP already Bound");
173 KwDlUdxBndCfm(&(udxSap->pst), udxSap->suId, CM_BND_NOK);
180 #if (ERRCLASS & ERRCLS_INT_PAR)
181 KW_SEND_SAPID_ALARM(tKwCb,spId,
182 LKW_EVENT_CKW_BND_REQ, LCM_CAUSE_INV_STATE);
183 #endif /* ERRCLASS & ERRCLS_INT_PAR */
184 RLOG0(L_ERROR, "Invalid UDX SAP State in Bind Req");
185 KwDlUdxBndCfm(&(udxSap->pst), udxSap->suId, CM_BND_NOK);
189 KwDlUdxBndCfm(&(udxSap->pst), udxSap->suId, CM_BND_OK);
196 * Handler for unbinding the DL from UL.
198 * @param[in] pst Post structure
199 * @param[in] spId Service provider SAP ID
200 * @param[in] reason Reason for Unbinding
206 PUBLIC S16 KwDlUdxUbndReq
213 PUBLIC S16 KwDlUdxUbndReq(pst, spId, reason)
219 KwUdxDlSapCb *udxSap;
224 #if (ERRCLASS & ERRCLS_INT_PAR)
225 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
231 tKwCb = KW_GET_KWCB(pst->dstInst);
233 RLOG2(L_DEBUG,"Unbind Req for spId[%d], reason[%d]",
236 /* disable upper sap (CKW) */
237 udxSap = (tKwCb->u.dlCb->udxDlSap + spId);
239 #if (ERRCLASS & ERRCLS_INT_PAR)
240 KW_GET_AND_VALIDATE_UDXSAP(tKwCb,udxSap, EKW208, "KwUiDlUdxndReq");
241 #endif /* ERRCLASS & ERRCLS_INT_PAR */
242 udxSap->state = KW_SAP_CFG;
249 * Handler for configuring RLC entities.
252 * This function is used by RRC to configure(add/delete/modify)
253 * one or more RLC entities.
254 * - CKW_CFG_ADD => kwCfgAddRb
255 * - CKW_CFG_MODIFY => kwCfgReCfgRb
256 * - CKW_CFG_DELETE => kwCfgDelRb
257 * - CKW_CFG_REESTABLISH => kwCfgReEstRb
258 * - CKW_CFG_DELETE_UE => kwCfgDelUe
260 * @param[in] pst - Post structure
261 * @param[in] spId - Serive Provider ID
262 * @param[in] cfg - Configuration information for one or more RLC entities.
269 PUBLIC S16 KwDlUdxCfgReq
276 PUBLIC S16 KwDlUdxCfgReq(pst, spId, cfg)
282 CkwCfgCfmInfo *cfgCfm;
289 #if (ERRCLASS & ERRCLS_INT_PAR)
290 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
296 tKwCb = KW_GET_KWCB(pst->dstInst);
298 pstUdxCfm = &(tKwCb->u.dlCb->udxDlSap[spId].pst);
299 KWDBGP_BRIEF(tKwCb,"spId(%d)\n", spId);
300 /* Allocate memory and memset to 0 for cfmInfo */
301 KW_ALLOC_SHRABL_BUF_WC(pstUdxCfm->region,
304 sizeof(CkwCfgCfmInfo));
306 #if (ERRCLASS & ERRCLS_ADD_RES)
309 RLOG0(L_FATAL,"Memory Allocation Failed.");
310 /* kw002.201 Freeing from proper region */
311 /* KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */
314 #endif /* ERRCLASS & ERRCLS_ADD_RES */
316 /* For every entity configuration process by cfgType */
317 for (idx = 0; idx < cfg->numEnt; idx++)
319 CkwEntCfgCfmInfo *entCfgCfm;
320 CkwEntCfgInfo *entCfg;
322 entCfg = (CkwEntCfgInfo *)&(cfg->entCfg[idx]);
323 entCfgCfm = (CkwEntCfgCfmInfo *)&(cfgCfm->entCfgCfm[idx]);
325 switch (entCfg->cfgType)
329 if (entCfg->dir & KW_DIR_DL)
331 /* Add a new RB entity configuration */
332 if (kwCfgAddDlRb(tKwCb,cfg->ueId, cfg->cellId,\
333 entCfg, entCfgCfm) != ROK)
335 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Addition Failed due to[%d]",
336 entCfgCfm->status.reason);
343 if (entCfg->dir & KW_DIR_DL)
345 /* Re-configure the existing RB entity configuration */
346 if (kwCfgReCfgDlRb(tKwCb,cfg->ueId, cfg->cellId,\
347 entCfg, entCfgCfm) != ROK)
349 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"ReCfg Failed due to[%d]",
350 entCfgCfm->status.reason);
358 if (entCfg->dir & KW_DIR_DL)
360 /* Delete the existing RB entity configuration */
361 if (kwCfgDelDlRb(tKwCb,cfg->ueId, cfg->cellId,\
362 entCfg, entCfgCfm) != ROK)
364 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Deletion Failed due to[%d]",
365 entCfgCfm->status.reason);
371 case CKW_CFG_REESTABLISH:
373 if (entCfg->dir & KW_DIR_DL)
375 /*if direction is both then, re-establishment end indication
376 * should be sent only from the UL instance, only if DIR is
377 * DL only then DL instance will send indication.*/
378 Bool sndReEst = TRUE;
379 if (entCfg->dir & KW_DIR_UL)
383 /* Re-establish the existing RB entity configuration */
384 if (kwCfgReEstDlRb(tKwCb,cfg->ueId, cfg->cellId,
385 sndReEst,entCfg, entCfgCfm) != ROK)
387 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Reest Failed due to[%d]",
388 entCfgCfm->status.reason);
394 case CKW_CFG_DELETE_UE:
396 /* Delete all RB entity configuration under UE */
397 if (kwCfgDelDlUe(tKwCb,cfg->ueId, cfg->cellId,
398 entCfg, entCfgCfm) != ROK)
400 RLOG_ARG1(L_ERROR,DBG_UEID,cfg->ueId,"deletion Failed due to[%d]",
401 entCfgCfm->status.reason);
405 case CKW_CFG_DELETE_CELL:
407 if (kwCfgDelDlCell(tKwCb,cfg->cellId,entCfg,entCfgCfm)
410 RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->cellId,"deletion Failed due to[%d]",
411 entCfgCfm->status.reason);
418 KW_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,\
419 CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_CFG);
420 RLOG0(L_ERROR, "Invalid CfgType");
425 /* Assign number of entity configuraitons and suId */
426 cfgCfm->transId = cfg->transId;
427 cfgCfm->ueId = cfg->ueId;
428 cfgCfm->cellId = cfg->cellId;
429 cfgCfm->numEnt = cfg->numEnt;
431 /* kw002.201 Freeing from proper region */
432 /* KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */
433 /* Send Configuration confirm primitive */
434 KwDlUdxCfgCfm(&(tKwCb->u.dlCb->udxDlSap[spId].pst),
435 tKwCb->u.dlCb->udxDlSap[spId].suId,
443 * This primitive is used by RRC to change the UeId for the existing UE
446 * @param pst - Pointer to the pst structure
447 * @param spId - The ID of the service provider SAP in the RLC layer
448 * @param transId - Transaction ID. This field uniquily identifies
449 * transaction between RRC and RLC
450 * @param ueInfo - Old UE Id Info for which the change request has come
451 * @param newUeInfo - New UE Id Info for existing UE context
458 PUBLIC S16 KwDlUdxUeIdChgReq
467 PUBLIC S16 KwDlUdxUeIdChgReq(pst,spId,transId,ueInfo,newUeInfo)
472 CkwUeInfo *newUeInfo;
478 TRC3(KwDlUdxUeIdChgReq)
480 #if (ERRCLASS & ERRCLS_INT_PAR)
481 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
487 tKwCb = KW_GET_KWCB(pst->dstInst);
489 KWDBGP_BRIEF(tKwCb, "(spId(%d), transId(%ld))\n",
492 KWDBGP_BRIEF(tKwCb, "(spId(%d), transId(%d))\n",
496 status.reason = CKW_CFG_REAS_NONE;
497 status.status = CKW_CFG_CFM_OK;
499 if (kwCfgDlUeIdChng(tKwCb, ueInfo, newUeInfo, &status) != ROK)
501 RLOG_ARG1(L_ERROR,DBG_CELLID,newUeInfo->cellId,"Failure due to[%d]",
504 KwDlUdxUeIdChgCfm(&(tKwCb->u.dlCb->udxDlSap[spId].pst),
505 tKwCb->u.dlCb->udxDlSap[spId].suId,
514 * Request for status PDU from ULM to DLM.
516 * @param[in] pst - Post Structure
517 * @param[in] spId - Service Provider Id
518 * @param[in] rlcId - Rlc Information Id
519 * @param[in] pStaPdu - Status PDU
526 PUBLIC S16 KwDlUdxStaPduReq
531 KwUdxDlStaPdu *pStaPdu
534 PUBLIC S16 KwDlUdxStaPduReq(pst, spId, rlcId, pStaPdu)
538 KwUdxDlStaPdu *pStaPdu;
544 tKwCb = KW_GET_KWCB (pst->dstInst);
546 kwDbmFetchDlRbCbByRbId(tKwCb, rlcId, &rbCb); /* Fetch DBM RbCb */
549 RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found",
550 rlcId->cellId,rlcId->rbId);
551 KW_FREE_SHRABL_BUF(pst->region,
554 sizeof(KwUdxDlStaPdu));
558 AMDL.cntrlBo = pStaPdu->controlBo;
559 /* If there already exists a STAUS PDU, free it and take the new one
563 KW_FREE_SHRABL_BUF(pst->region,
566 sizeof(KwUdxDlStaPdu));
569 AMDL.pStaPdu = pStaPdu;
570 kwAmmSendDStaRsp(tKwCb, rbCb, &AMDL);
577 * It handles the status update recieved from ULM.
579 * @param[in] pst - Post Structure
580 * @param[in] spId - Service Provider Id
581 * @param[in] rlcId - Rlc Information Id
582 * @param[in] pStaPdu - Status PDU
589 PUBLIC S16 KwDlUdxStaUpdReq
597 PUBLIC S16 KwDlUdxStaUpdReq(pst, spId, rlcId,pStaPdu)
601 KwUdxStaPdu *pStaPdu;
607 tKwCb = KW_GET_KWCB(pst->dstInst);
609 kwDbmFetchDlRbCbByRbId(tKwCb, rlcId, &rbCb);
612 RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found",
613 rlcId->cellId,rlcId->rbId);
617 kwAmmDlHndlStatusPdu(tKwCb, rbCb, pStaPdu);
619 KW_FREE_SHRABL_BUF(pst->region,
622 sizeof(KwUdxStaPdu));
631 PUBLIC S16 KwDlUdxL2MeasReq
634 KwL2MeasReqEvt *measReqEvt
637 PUBLIC S16 KwDlUdxL2MeasReq (pst, measReqEvt)
639 KwL2MeasReqEvt *measReqEvt;
644 VOLATILE U32 startTime = 0;
647 TRC3(KwDlUdxL2MeasReq);
650 SStartTask(&startTime, PID_RLC_MEAS_START);
652 tKwCb = KW_GET_KWCB(pst->dstInst);
654 /* Initialize measCfmEvt */
656 /* validate the received measReqEvt */
657 /*LTE_L2_MEAS_PHASE2*/
659 measType = measReqEvt->measReq.measType;
661 if(measType & LKW_L2MEAS_DL_IP)
663 /* if measurement is for DL IP enable for all QCI */
664 for(cntr = 0; cntr < LKW_MAX_QCI; cntr++)
666 tKwCb->u.dlCb->kwL2Cb.measOn[cntr] |= LKW_L2MEAS_DL_IP;
671 /* for nonIpThroughput meas, enable only for the sent QCIs */
673 for(i = 0; i < LKW_MAX_QCI; i++)
675 tKwCb->u.dlCb->kwL2Cb.measOn[i] |= measType;
679 /* We need to copy the transId for sending back confirms later */
680 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
682 KwL2MeasEvtCb* measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]);
683 if(measEvtCb->measCb.measType & measType)
685 measEvtCb->transId= measReqEvt->transId;
690 SStopTask(startTime, PID_RLC_MEAS_START);
692 } /* KwDlUdxMeasReq */
696 This function processes L2 Measurement stop request received from the layer manager.
697 After receving this request, RLC stops L2 Measurement
698 * @param[in] pst post structure
699 * @param[in] measType meas Type
702 * -# Failure : RFAILED
706 PUBLIC S16 KwDlUdxL2MeasStopReq
712 PUBLIC S16 KwDlUdxL2MeasStopReq (pst, measType)
718 KwL2MeasEvtCb *measEvtCb = NULLP;
721 /* KwL2MeasCfmEvt measCfmEvt; */
722 VOLATILE U32 startTime = 0;
724 TRC3(KwDlUdxMeasStopReq);
727 SStartTask(&startTime, PID_RLC_MEAS_STOP);
729 tKwCb = KW_GET_KWCB(pst->dstInst);
730 /* cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt)); */
731 /* reset the counters for the measurement type passed */
732 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
734 measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]);
735 if(measEvtCb->measCb.measType & measType)
737 kwUtlResetDlL2MeasInKwRb(tKwCb, &measEvtCb->measCb, measType);
742 /* switch off the measurements for the type passed */
743 for(cntr = 0; cntr < LKW_MAX_QCI; cntr++)
745 tKwCb->u.dlCb->kwL2Cb.measOn[cntr] &= ~measType;
748 status = LCM_PRIM_OK;
749 /* Stop confirm is removed as UL thread is already sending it */
752 SStopTask(startTime, PID_RLC_MEAS_STOP);
758 This function processes L2 Measurement Send request received from the layer manager.
759 After receving this request, RLC sends L2 Measurement
760 * @param[in] pst post structure
761 * @param[in] measType meas Type
764 * -# Failure : RFAILED
768 PUBLIC S16 KwDlUdxL2MeasSendReq
774 PUBLIC S16 KwDlUdxL2MeasSendReq (pst, measType)
779 KwL2MeasEvtCb *measEvtCb;
782 VOLATILE U32 startTime = 0;
784 TRC3(KwDlUdxMeasSendReq);
786 tKwCb = KW_GET_KWCB(pst->dstInst);
787 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
789 measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]);
790 if(measEvtCb->measCb.measType & measType)
793 SStartTask(&startTime, PID_RLC_MEAS_REPORT);
795 kwUtlSndDlL2MeasCfm(tKwCb, measEvtCb);
798 SStopTask(startTime, PID_RLC_MEAS_REPORT);
804 #endif /* LTE_L2_MEAS */
808 #endif /* __cplusplus */
811 /**********************************************************************
813 **********************************************************************/