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;
290 #if (ERRCLASS & ERRCLS_INT_PAR)
291 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
297 tKwCb = KW_GET_KWCB(pst->dstInst);
299 pstUdxCfm = &(tKwCb->u.dlCb->udxDlSap[spId].pst);
300 KWDBGP_BRIEF(tKwCb,"spId(%d)\n", spId);
302 /* Validate SAP ID under ERRORCLS */
303 KW_VALDATE_SAP(tKwCb,spId,
304 (&tKwCb->u.dlCb->udxDlSap[spId]),
308 /* kw002.201 Freeing from proper region */
309 /* only RLC UL will free it KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */
313 /* Allocate memory and memset to 0 for cfmInfo */
314 KW_ALLOC_SHRABL_BUF_WC(pstUdxCfm->region,
317 sizeof(CkwCfgCfmInfo));
319 #if (ERRCLASS & ERRCLS_ADD_RES)
322 RLOG0(L_FATAL,"Memory Allocation Failed.");
323 /* kw002.201 Freeing from proper region */
324 /* KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */
327 #endif /* ERRCLASS & ERRCLS_ADD_RES */
329 /* For every entity configuration process by cfgType */
330 for (idx = 0; idx < cfg->numEnt; idx++)
332 CkwEntCfgCfmInfo *entCfgCfm;
333 CkwEntCfgInfo *entCfg;
335 entCfg = (CkwEntCfgInfo *)&(cfg->entCfg[idx]);
336 entCfgCfm = (CkwEntCfgCfmInfo *)&(cfgCfm->entCfgCfm[idx]);
338 switch (entCfg->cfgType)
342 if (entCfg->dir & KW_DIR_DL)
344 /* Add a new RB entity configuration */
345 if (kwCfgAddDlRb(tKwCb,cfg->ueId, cfg->cellId,\
346 entCfg, entCfgCfm) != ROK)
348 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Addition Failed due to[%d]",
349 entCfgCfm->status.reason);
356 if (entCfg->dir & KW_DIR_DL)
358 /* Re-configure the existing RB entity configuration */
359 if (kwCfgReCfgDlRb(tKwCb,cfg->ueId, cfg->cellId,\
360 entCfg, entCfgCfm) != ROK)
362 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"ReCfg Failed due to[%d]",
363 entCfgCfm->status.reason);
371 if (entCfg->dir & KW_DIR_DL)
373 /* Delete the existing RB entity configuration */
374 if (kwCfgDelDlRb(tKwCb,cfg->ueId, cfg->cellId,\
375 entCfg, entCfgCfm) != ROK)
377 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Deletion Failed due to[%d]",
378 entCfgCfm->status.reason);
384 case CKW_CFG_REESTABLISH:
386 if (entCfg->dir & KW_DIR_DL)
388 /*if direction is both then, re-establishment end indication
389 * should be sent only from the UL instance, only if DIR is
390 * DL only then DL instance will send indication.*/
391 Bool sndReEst = TRUE;
392 if (entCfg->dir & KW_DIR_UL)
396 /* Re-establish the existing RB entity configuration */
397 if (kwCfgReEstDlRb(tKwCb,cfg->ueId, cfg->cellId,
398 sndReEst,entCfg, entCfgCfm) != ROK)
400 RLOG_ARG1(L_ERROR,DBG_RBID,cfg->entCfg[idx].rbId,"Reest Failed due to[%d]",
401 entCfgCfm->status.reason);
407 case CKW_CFG_DELETE_UE:
409 /* Delete all RB entity configuration under UE */
410 if (kwCfgDelDlUe(tKwCb,cfg->ueId, cfg->cellId,
411 entCfg, entCfgCfm) != ROK)
413 RLOG_ARG1(L_ERROR,DBG_UEID,cfg->ueId,"deletion Failed due to[%d]",
414 entCfgCfm->status.reason);
418 case CKW_CFG_DELETE_CELL:
420 if (kwCfgDelDlCell(tKwCb,cfg->cellId,entCfg,entCfgCfm)
423 RLOG_ARG1(L_ERROR,DBG_CELLID,cfg->cellId,"deletion Failed due to[%d]",
424 entCfgCfm->status.reason);
431 KW_CFG_FILL_CFG_CFM(entCfgCfm, entCfg->rbId, entCfg->rbType,\
432 CKW_CFG_CFM_NOK, CKW_CFG_REAS_INVALID_CFG);
433 RLOG0(L_ERROR, "Invalid CfgType");
438 /* Assign number of entity configuraitons and suId */
439 cfgCfm->transId = cfg->transId;
440 cfgCfm->ueId = cfg->ueId;
441 cfgCfm->cellId = cfg->cellId;
442 cfgCfm->numEnt = cfg->numEnt;
444 /* kw002.201 Freeing from proper region */
445 /* KW_PST_FREE(pst->region, pst->pool, cfg, sizeof(CkwCfgInfo)); */
446 /* Send Configuration confirm primitive */
447 KwDlUdxCfgCfm(&(tKwCb->u.dlCb->udxDlSap[spId].pst),
448 tKwCb->u.dlCb->udxDlSap[spId].suId,
456 * This primitive is used by RRC to change the UeId for the existing UE
459 * @param pst - Pointer to the pst structure
460 * @param spId - The ID of the service provider SAP in the RLC layer
461 * @param transId - Transaction ID. This field uniquily identifies
462 * transaction between RRC and RLC
463 * @param ueInfo - Old UE Id Info for which the change request has come
464 * @param newUeInfo - New UE Id Info for existing UE context
471 PUBLIC S16 KwDlUdxUeIdChgReq
480 PUBLIC S16 KwDlUdxUeIdChgReq(pst,spId,transId,ueInfo,newUeInfo)
485 CkwUeInfo *newUeInfo;
491 TRC3(KwDlUdxUeIdChgReq)
493 #if (ERRCLASS & ERRCLS_INT_PAR)
494 if (pst->dstInst >= KW_MAX_RLC_INSTANCES)
500 tKwCb = KW_GET_KWCB(pst->dstInst);
502 KWDBGP_BRIEF(tKwCb, "(spId(%d), transId(%ld))\n",
505 KWDBGP_BRIEF(tKwCb, "(spId(%d), transId(%d))\n",
509 status.reason = CKW_CFG_REAS_NONE;
510 status.status = CKW_CFG_CFM_OK;
512 if (kwCfgDlUeIdChng(tKwCb, ueInfo, newUeInfo, &status) != ROK)
514 RLOG_ARG1(L_ERROR,DBG_CELLID,newUeInfo->cellId,"Failure due to[%d]",
517 KwDlUdxUeIdChgCfm(&(tKwCb->u.dlCb->udxDlSap[spId].pst),
518 tKwCb->u.dlCb->udxDlSap[spId].suId,
527 * Request for status PDU from ULM to DLM.
529 * @param[in] pst - Post Structure
530 * @param[in] spId - Service Provider Id
531 * @param[in] rlcId - Rlc Information Id
532 * @param[in] pStaPdu - Status PDU
539 PUBLIC S16 KwDlUdxStaPduReq
544 KwUdxDlStaPdu *pStaPdu
547 PUBLIC S16 KwDlUdxStaPduReq(pst, spId, rlcId, pStaPdu)
551 KwUdxDlStaPdu *pStaPdu;
557 tKwCb = KW_GET_KWCB (pst->dstInst);
559 kwDbmFetchDlRbCbByRbId(tKwCb, rlcId, &rbCb); /* Fetch DBM RbCb */
562 RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found",
563 rlcId->cellId,rlcId->rbId);
564 KW_FREE_SHRABL_BUF(pst->region,
567 sizeof(KwUdxDlStaPdu));
571 AMDL.cntrlBo = pStaPdu->controlBo;
572 /* If there already exists a STAUS PDU, free it and take the new one
576 KW_FREE_SHRABL_BUF(pst->region,
579 sizeof(KwUdxDlStaPdu));
582 AMDL.pStaPdu = pStaPdu;
583 kwAmmSendDStaRsp(tKwCb, rbCb, &AMDL);
590 * It handles the status update recieved from ULM.
592 * @param[in] pst - Post Structure
593 * @param[in] spId - Service Provider Id
594 * @param[in] rlcId - Rlc Information Id
595 * @param[in] pStaPdu - Status PDU
602 PUBLIC S16 KwDlUdxStaUpdReq
610 PUBLIC S16 KwDlUdxStaUpdReq(pst, spId, rlcId,pStaPdu)
614 KwUdxStaPdu *pStaPdu;
620 tKwCb = KW_GET_KWCB(pst->dstInst);
622 kwDbmFetchDlRbCbByRbId(tKwCb, rlcId, &rbCb);
625 RLOG_ARG2(L_ERROR, DBG_UEID,rlcId->ueId, "CellId [%u]:RbId[%d] not found",
626 rlcId->cellId,rlcId->rbId);
630 kwAmmDlHndlStatusPdu(tKwCb, rbCb, pStaPdu);
632 KW_FREE_SHRABL_BUF(pst->region,
635 sizeof(KwUdxStaPdu));
644 PUBLIC S16 KwDlUdxL2MeasReq
647 KwL2MeasReqEvt *measReqEvt
650 PUBLIC S16 KwDlUdxL2MeasReq (pst, measReqEvt)
652 KwL2MeasReqEvt *measReqEvt;
657 VOLATILE U32 startTime = 0;
660 TRC3(KwDlUdxL2MeasReq);
663 SStartTask(&startTime, PID_RLC_MEAS_START);
665 tKwCb = KW_GET_KWCB(pst->dstInst);
667 /* Initialize measCfmEvt */
669 /* validate the received measReqEvt */
670 /*LTE_L2_MEAS_PHASE2*/
672 measType = measReqEvt->measReq.measType;
674 if(measType & LKW_L2MEAS_DL_IP)
676 /* if measurement is for DL IP enable for all QCI */
677 for(cntr = 0; cntr < LKW_MAX_QCI; cntr++)
679 tKwCb->u.dlCb->kwL2Cb.measOn[cntr] |= LKW_L2MEAS_DL_IP;
684 /* for nonIpThroughput meas, enable only for the sent QCIs */
686 for(i = 0; i < LKW_MAX_QCI; i++)
688 tKwCb->u.dlCb->kwL2Cb.measOn[i] |= measType;
692 /* We need to copy the transId for sending back confirms later */
693 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
695 KwL2MeasEvtCb* measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]);
696 if(measEvtCb->measCb.measType & measType)
698 measEvtCb->transId= measReqEvt->transId;
703 SStopTask(startTime, PID_RLC_MEAS_START);
705 } /* KwDlUdxMeasReq */
709 This function processes L2 Measurement stop request received from the layer manager.
710 After receving this request, RLC stops L2 Measurement
711 * @param[in] pst post structure
712 * @param[in] measType meas Type
715 * -# Failure : RFAILED
719 PUBLIC S16 KwDlUdxL2MeasStopReq
725 PUBLIC S16 KwDlUdxL2MeasStopReq (pst, measType)
731 KwL2MeasEvtCb *measEvtCb = NULLP;
734 /* KwL2MeasCfmEvt measCfmEvt; */
735 VOLATILE U32 startTime = 0;
737 TRC3(KwDlUdxMeasStopReq);
740 SStartTask(&startTime, PID_RLC_MEAS_STOP);
742 tKwCb = KW_GET_KWCB(pst->dstInst);
743 /* cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt)); */
744 /* reset the counters for the measurement type passed */
745 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
747 measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]);
748 if(measEvtCb->measCb.measType & measType)
750 kwUtlResetDlL2MeasInKwRb(tKwCb, &measEvtCb->measCb, measType);
755 /* switch off the measurements for the type passed */
756 for(cntr = 0; cntr < LKW_MAX_QCI; cntr++)
758 tKwCb->u.dlCb->kwL2Cb.measOn[cntr] &= ~measType;
761 status = LCM_PRIM_OK;
762 /* Stop confirm is removed as UL thread is already sending it */
765 SStopTask(startTime, PID_RLC_MEAS_STOP);
771 This function processes L2 Measurement Send request received from the layer manager.
772 After receving this request, RLC sends L2 Measurement
773 * @param[in] pst post structure
774 * @param[in] measType meas Type
777 * -# Failure : RFAILED
781 PUBLIC S16 KwDlUdxL2MeasSendReq
787 PUBLIC S16 KwDlUdxL2MeasSendReq (pst, measType)
792 KwL2MeasEvtCb *measEvtCb;
795 VOLATILE U32 startTime = 0;
797 TRC3(KwDlUdxMeasSendReq);
799 tKwCb = KW_GET_KWCB(pst->dstInst);
800 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
802 measEvtCb = &(tKwCb->u.dlCb->kwL2Cb.kwL2EvtCb[cntr]);
803 if(measEvtCb->measCb.measType & measType)
806 SStartTask(&startTime, PID_RLC_MEAS_REPORT);
808 kwUtlSndDlL2MeasCfm(tKwCb, measEvtCb);
811 SStopTask(startTime, PID_RLC_MEAS_REPORT);
817 #endif /* LTE_L2_MEAS */
821 #endif /* __cplusplus */
824 /**********************************************************************
826 **********************************************************************/