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: Source code for RLC Utility Module
26 This file contains following functions
36 **********************************************************************/
37 static const char* RLOG_MODULE_NAME="UTL";
38 static int RLOG_MODULE_ID=2048;
39 static int RLOG_FILE_ID=210;
42 @brief RLC Utility Module
45 /* header (.h) include files */
46 #include "envopt.h" /* environment options */
47 #include "envdep.h" /* environment dependent */
48 #include "envind.h" /* environment independent */
49 /* kw005.201 added support for L2 Measurement */
54 #include "gen.h" /* general */
55 #include "ssi.h" /* system services */
56 #include "cm5.h" /* common timer defines */
57 #include "cm_tkns.h" /* common tokens defines */
58 #include "cm_mblk.h" /* common memory allocation library defines */
59 #include "cm_llist.h" /* common link list defines */
60 #include "cm_hash.h" /* common hash list defines */
61 #include "cm_lte.h" /* common LTE defines */
62 #include "ckw.h" /* CKW defines */
63 #include "kwu.h" /* KWU defines */
64 #include "lkw.h" /* LKW defines */
65 #include "rgu.h" /* RGU defines */
67 #include "kw_env.h" /* RLC environment options */
68 #include "kw.h" /* RLC defines */
69 #include "kw_err.h" /* Error defines */
70 #include "kw_ul.h" /* RLC Uplink defines */
72 /* extern (.x) include files */
73 #include "gen.x" /* general */
74 #include "ssi.x" /* system services */
76 #include "cm5.x" /* common timer library */
77 #include "cm_tkns.x" /* common tokens */
78 #include "cm_mblk.x" /* common memory allocation */
79 #include "cm_llist.x" /* common link list */
80 #include "cm_hash.x" /* common hash list */
81 #include "cm_lte.x" /* common LTE includes */
82 #include "cm_lib.x" /* common memory allocation library */
83 #include "ckw.x" /* CKW includes */
84 #include "kwu.x" /* KWU includes */
85 #include "lkw.x" /* LKW includes */
86 #include "rgu.x" /* RGU includes */
88 #include "kw.x" /* RLC inlcudes */
89 #include "kw_ul.x" /* RLC uplink includes */
93 PUBLIC S16 SMrkUlPkt(Buffer *mbuf);
95 PUBLIC KwAmRecBuf* kwUtlGetRecBuf(CmLListCp *recBufLst, KwSn sn);
96 #define KW_MODULE (KW_DBGMASK_DUT | KW_DBGMASK_UL) /* for debugging purpose */
102 * Handler for receiving data for multiple logical channels from MAC.
105 * This function receives the data sent by MAC for one or more
106 * logical channels.It calls the UMM or AMM functions to process
107 * the PDUs and send them to the uppper layer.
109 * @param[in] gCb - RLC instance control block
110 * @param[in] datIndInfo - Data Indication Information containing the PDU(s)
111 * for one or more logical channels
119 PUBLIC S16 kwUtlRcvFrmLi
122 KwDatIndInfo *datIndInfo
125 PUBLIC S16 kwUtlRcvFrmLi(gCb,datIndInfo)
127 KwDatIndInfo *datIndInfo;
130 U32 count; /* Loop Counter */
131 KwPduInfo *pduInfo; /* PDU Information */
132 KwUlRbCb *rbCb; /* RB Control Block */
133 KwUlUeCb *ueCb; /* UE Control Block */
134 /* kw005.201 added support for L2 Measurement */
142 if( ROK != kwDbmFetchUlUeCb(gCb,datIndInfo->rnti,datIndInfo->cellId,&(ueCb)))
144 /* Fetch UeCb failed */
145 RLOG_ARG1(L_ERROR,DBG_CELLID,datIndInfo->cellId,
146 "UEID:%d UeCb not found",
148 /* free the buffers inside the datIndInfo */
150 for(i = 0; i< datIndInfo->numLch; i++)
152 for(j = 0; j < datIndInfo->lchData[i].pdu.numPdu; j++)
154 if(datIndInfo->lchData[i].pdu.mBuf[j])
156 KW_FREE_BUF_WC(datIndInfo->lchData[i].pdu.mBuf[j]);
166 if (RGU_L2M_UL_BURST_START == datIndInfo->burstInd)
168 ueCb->isUlBurstActive = TRUE;
172 ueCb->firstPacketTTI = 0;
173 ueCb->isUlBurstActive = FALSE;
176 for ( count = 0;count < datIndInfo->numLch; count++ )
178 rbCb = ueCb->lCh[datIndInfo->lchData[count].lcId - 1].ulRbCb;
179 /* kw002.201 Removed allocation of pduInfo */
180 pduInfo = &(datIndInfo->lchData[count].pdu);
181 /* Fix for CR ccpu00138374,sometimes rbCb is NULL in UL path,
182 * So inorder to avoid the crash, added this preventive check
187 for(j = 0; j < pduInfo->numPdu; j++)
191 KW_FREE_BUF_WC(pduInfo->mBuf[j]);
198 SMrkUlPkt(pduInfo->mBuf[0]);
200 if ( rbCb->mode == CM_LTE_MODE_UM )
202 /* kw005.201 added support for L2 Measurement */
204 kwUmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
206 kwUmmProcessPdus(gCb,rbCb,pduInfo);
209 else if (rbCb->mode == CM_LTE_MODE_AM )
211 /* kw005.201 added support for L2 Measurement */
213 kwAmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
215 kwAmmProcessPdus(gCb,rbCb,pduInfo);
225 * Handler for sending Data Indication to the upper layer.
228 * This function is used to send re-assembled SDU to the upper layer.
230 * @param[in] gCb - RLC instance Control Block
231 * @param[in] rbCb - RB Control Block
232 * @param[in] sdu - SDU to be sent to upper layer
238 PUBLIC S16 kwUtlSndDatInd
245 PUBLIC S16 kwUtlSndDatInd(gCb,rbCb,sdu)
252 KwuDatIndInfo *datIndInfo; /* Data Indication Information */
253 KwuDatIndInfo datIndInfoTmp;
260 /* Creating static memory for KwuDatIndInfo. #else will be
261 * removed once the testing is done on all platforms */
262 datIndInfo = &datIndInfoTmp;
264 #if (ERRCLASS & ERRCLS_ADD_RES )
265 if ( datIndInfo == NULLP )
267 RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
268 "Memory allocation failed UEID:%d CELLID:%d",
274 #endif /* ERRCLASS & ERRCLS_ADD_RES */
276 KW_MEM_CPY(&(datIndInfo->rlcId),&(rbCb->rlcId),sizeof(CmLteRlcId));
277 /* Set the "isOutofSeq" flag for each packet
278 * If packets are in-sequence set flag as TRUE else FALSE */
279 datIndInfo->isOutOfSeq = rbCb->m.amUl.isOutOfSeq;
282 /* If trace flag is enabled send the trace indication */
283 if(gCb->init.trc == TRUE)
285 /* Populate the trace params */
286 kwLmmSendTrc(gCb,KWU_EVT_DAT_IND, sdu);
290 KwUiKwuDatInd(&gCb->genCfg.lmPst, datIndInfo, sdu);
293 } /* kwUtlSndDatInd */
296 PRIVATE Void dumpRLCUlRbInformation(KwUlRbCb* ulRbCb)
298 if(ulRbCb->mode == CM_LTE_MODE_UM)
301 U32 pdusInReceptionBuffer = 0;
302 U32 windSz = ulRbCb->m.umUl.umWinSz << 1;
304 for(i = 0; i< windSz; i++)
306 if(ulRbCb->m.umUl.recBuf[i] != NULLP)
308 pdusInReceptionBuffer++;
312 RLOG_ARG3(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
313 "UM UL UEID:%d CELLID:%d Reception Buffer size = %d",
314 (int)ulRbCb->rlcId.ueId,
315 (int)ulRbCb->rlcId.cellId,
316 (int)pdusInReceptionBuffer);
318 else if(ulRbCb->mode == CM_LTE_MODE_AM)
321 U32 pdusInReceptionBuffer = 0;
323 U32 windSz = KW_AM_GET_WIN_SZ(ulRbCb->m.amUl.snLen) << 1;
325 for(i = 0; i< windSz; i++)
327 KwAmRecBuf *recBuf = kwUtlGetRecBuf(ulRbCb->m.amUl.recBufLst, i);
330 pdusInReceptionBuffer++;
331 totalSegs += (recBuf->segLst.count);
335 RLOG_ARG4(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
336 "AM UL UEID:%d CELLID:%d Reception Buf size = %d"
338 (int)ulRbCb->rlcId.ueId,
339 (int)ulRbCb->rlcId.cellId,
340 (int)pdusInReceptionBuffer,
345 Void DumpRLCUlDebugInformation(Void)
347 KwCb* ulInst = kwCb[0]; /* TODO : Check whether UL is 0 or 1 */
348 KwUlCb* ulCb = ulInst->u.ulCb;
349 KwUlUeCb *ueCb = NULLP;
351 /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
352 while (ROK == cmHashListGetNext(&ulCb->ueLstCp,
357 for(i = 0; i< KW_MAX_SRB_PER_UE; i++)
359 KwUlRbCb* ulRbCb = ueCb->srbCb[i];
362 dumpRLCUlRbInformation(ulRbCb);
365 for(i = 0; i< KW_MAX_DRB_PER_UE; i++)
367 KwUlRbCb* ulRbCb = ueCb->drbCb[i];
370 dumpRLCUlRbInformation(ulRbCb);
378 * kwUtlFreeUlRbCb() function is split into two functions
379 * - kwAmmFreeUlRbCb() ---> gp_amm_ul.c
380 * - kwUmmFreeUlRbCb() ---> gp_umm_ul.c
381 * and placed in respective files mentioned above
386 /* kw005.201 added support for L2 Measurement */
392 * Handler for initialisation of measurement
394 * @param[in] gCb - RLC instance Control Block
399 S16 kwUtlL2MeasUlInit(KwCb *gCb)
403 gCb->u.ulCb->kwL2Cb.kwNumMeas=0;
404 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
406 cmMemset((U8 *)&(gCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr]), 0, sizeof(KwL2MeasEvtCb));
408 gCb->u.ulCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_UL_IP].measCb.measType = LKW_L2MEAS_UL_IP;
415 * Handler to calculate the Ul Ip throughput for a LCH
420 * @param[in] rbCb RB control block
421 * @param[in] pdu Pdu of LCH
427 PUBLIC Void kwUtlCalUlIpThrPutIncTTI
434 PUBLIC Void kwUtlCalUlIpThrPutIncTTI(gCb, rbCb, ttiCnt)
440 VOLATILE U32 startTime = 0;
441 TRC2(kwUtlCalUlIpThrPutIncTTI)
444 SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
446 RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:"
447 "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d",
448 rbCb->rbL2Cb.measOn,ttiCnt,
452 RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:"
453 "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d",
454 rbCb->rbL2Cb.measOn,ttiCnt,
459 /*Check if UL IP throughput measurement is ON for this RB or not*/
460 if(KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))
462 if (TRUE == rbCb->ueCb->isUlBurstActive)
464 if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
466 /*Removed Error Print*/
468 if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
470 rbCb->rbL2Cb.l2Sts[KW_L2MEAS_UL_IP]->ulIpThruput.timeSummation +=
471 (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
475 rbCb->ueCb->firstPacketTTI = ttiCnt;
477 rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
481 rbCb->l2MeasIpThruput.prevTtiCnt = 0;
486 SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
487 } /* kwUtlCalUlIpThrPutIncTTI */
494 * Handler to calculate the Ul Ip throughput for a LCH
499 * @param[in] rbCb RB control block
500 * @param[in] pdu Pdu of LCH
506 PUBLIC Void kwUtlCalUlIpThrPut
514 PUBLIC Void kwUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt)
521 MsgLen rlcSduSz = 0; /*Holds length of Rlc Sdu*/
522 VOLATILE U32 startTime = 0;
523 TRC2(kwUtlCalUlIpThrPut)
527 SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
529 /*Check if UL IP throughput measurement is ON for this RB or not*/
530 if(KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&
531 (TRUE == rbCb->ueCb->isUlBurstActive) &&
532 (rbCb->ueCb->firstPacketTTI) &&
533 (ttiCnt != rbCb->ueCb->firstPacketTTI))
535 SFndLenMsg(pdu, &rlcSduSz);
537 rbCb->rbL2Cb.l2Sts[KW_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
541 SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
542 } /* kwUtlCalUlIpThrPut */
547 * @brief Handler for L2 Measurement timer expiry.
551 * This function is called when the l2 measurement timer expires.
552 * This function sends a consolidates the mesaurements taken during
553 * this time and sends the confirm .
555 * @param[in] measEvtCb Measurement Event Control Block.
563 PUBLIC S16 kwUtlHdlL2TmrExp
566 KwL2MeasEvtCb *measEvtCb
569 PUBLIC S16 kwUtlHdlL2TmrExp(measEvtCb)
571 KwL2MeasEvtCb *measEvtCb;
574 TRC3(kwUtlHdlL2TmrExp)
576 #ifdef LTE_L2_MEAS_RLC
580 /* Clean up the RB data structures */
581 if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
582 (measEvtCb->measCb.val.nonIpThMeas.numSamples))
584 measCb = &measEvtCb->measCb;
586 for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
588 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe +=
589 kwCb.kwL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
590 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
592 measEvtCb->val.nonIpThMeas.measCb.numSamples--;
593 kwStartTmr(gCb, (PTR)measEvtCb, KW_EVT_L2_TMR);
598 kwUtlSndUlL2MeasCfm(gCb, measEvtCb);
601 } /* kwUtlHdlL2TmrExp */
604 * @brief Handler for Sending L2 Measurement confirm.
608 * This function sends a consolidates the mesaurements taken during
609 * this time and sends the confirm .
611 * @param[in] measEvtCb Measurement Event Control Block.
619 PUBLIC S16 kwUtlSndUlL2MeasCfm
622 KwL2MeasEvtCb *measEvtCb
625 PUBLIC S16 kwUtlSndUlL2MeasCfm(gCb, measEvtCb)
627 KwL2MeasEvtCb *measEvtCb;
632 KwL2MeasCfmEvt measCfmEvt;
637 /* Discard new changes starts */
640 /* Discard new changes ends */
642 TRC3(kwUtlSndUlL2MeasCfm)
644 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
646 RLOG1(L_DEBUG,"kwUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
648 RLOG1(L_DEBUG,"kwUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
651 /* Clean up the RB data structures */
652 measCb = &measEvtCb->measCb;
654 cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt));
655 measCfmEvt.transId = measEvtCb->transId;
657 measCfmEvt.measType = measCb->measType;
658 measCfmEvt.status.status = LCM_PRIM_OK;
659 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
661 if( measCb->measType & LKW_L2MEAS_UL_IP)
663 KwL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
664 KwL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
665 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
667 pUeInfoLstCfm[cfmIdx].numCfm = 0;
668 if (pUeInfoLstCb[cntr].isValid == TRUE)
670 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
671 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
673 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
675 qci = pUeInfoLstCb[cntr].qci[qciIdx];
676 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
678 if(measCb->measType & LKW_L2MEAS_UL_IP)
680 ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
681 ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
684 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
688 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
690 /* Converting it to kbps */
691 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
694 /* Reset the values after reporting to Application */
695 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
696 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
698 pUeInfoLstCfm[cfmIdx].numCfm++;
703 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
705 KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
707 } /* kwUtlSndUlL2MeasCfm */
710 * @brief Handler for Sending Negative confirm .
714 * This function is called when the l2 measurement cannot be started
715 * This function sends negative confirm for all the requests
717 * @param[in] gCb - RLC instance control block
718 * @param[in] measReqEvt Measurement Req Structure
719 * @param[in] measCfmEvt Confirmation to be sent to layer manager
727 PUBLIC S16 kwUtlSndUlL2MeasNCfm
730 KwL2MeasReqEvt *measReqEvt,
731 KwL2MeasCfmEvt *measCfmEvt
734 PUBLIC S16 kwUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt)
736 KwL2MeasReqEvt *measReqEvt;
737 KwL2MeasCfmEvt *measCfmEvt;
740 TRC3(kwUtlSndUlL2MeasNCfm)
742 KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
744 } /* kwUtlSndL2MeasNCfm */
746 #ifdef LTE_L2_MEAS_RLC
748 * @brief Validates the measurement request parameters.
752 * Function :kwUtlValidateL2Meas
754 * @param[in] measReqEvt L2 measurement request received from layer manager.
755 * @param[out] measCfmEvt L2 measurement confirm to be prepared.
756 * @param[out] lChId List of LCh for the given Ue corresponding to QCIs
757 given in measurement request.
758 * @param[out] numLCh Number of LCh in array lChId.
762 PUBLIC S16 kwUtlValidateL2Meas
764 KwL2MeasReqEvt *measReqEvt,
765 KwL2MeasCfmEvt *measCfmEvt,
770 PUBLIC S16 kwUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh)
771 KwL2MeasReqEvt *measReqEvt;
772 KwL2MeasCfmEvt *measCfmEvt;
794 TRC3(kwUtlValidateL2Meas)
799 measType = measReqEvt->measReq.measType;
800 /* Check for the range of measType */
801 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
802 if((measType == 0x00) ||
805 measCfmEvt->transId = measReqEvt->transId;
806 measCfmEvt->measType = measType;
807 measCfmEvt->status.status = LCM_PRIM_NOK;
808 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
811 /*User can either request for Active UE,*
812 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
813 lsbNibble = measType & 0x0F;
814 msbNibble = measType & 0xF0;
816 if( (lsbNibble != 0) && (msbNibble != 0) )
818 measCfmEvt->transId = measReqEvt->transId;
819 measCfmEvt->measType = measType;
820 measCfmEvt->status.status = LCM_PRIM_NOK;
821 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
825 /* Check for total maximum number of Measurement Control Block */
826 if(kwCb.kwL2Cb.kwNumMeas >= LKW_MAX_L2MEAS )
828 measCfmEvt->transId = measReqEvt->transId;
829 measCfmEvt->measType = measType;
830 measCfmEvt->status.status = LCM_PRIM_NOK;
831 measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
835 /* Check that number of samples should be a non-zero value */
836 if(((measType & LKW_L2MEAS_ACT_UE) &&
837 (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
839 measCfmEvt->transId = measReqEvt->transId;
840 measCfmEvt->measType = measType;
841 measCfmEvt->status.status = LCM_PRIM_NOK;
842 measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
845 /* Check that measurement period should be completely divisible *
846 * number of sample. */
847 if(((measType & LKW_L2MEAS_ACT_UE) &&
848 ((measReqEvt->measPeriod %
849 measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
851 measCfmEvt->transId = measReqEvt->transId;
852 measCfmEvt->measType = measType;
853 measCfmEvt->status.status = LCM_PRIM_NOK;
854 measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
858 numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
859 qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
861 /* Check whether qci is configured or not */
862 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
864 qci = qciVal[qciIdx];
865 ret = cmHashListFind(&(kwCb.kwL2Cb.qciHlCp),
866 (U8 *)&qci, (U16)sizeof(qci), 0, (PTR *)&rbCb);
869 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
870 measCfmEvt->val.nonIpThMeas.numCfm++;
874 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
876 measCfmEvt->status.status = LCM_PRIM_NOK;
877 measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
878 measCfmEvt->measType = measType;
879 measCfmEvt->transId = measReqEvt->transId;
883 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
885 if(kwCb.kwL2Cb.measOn[qci] & measReqEvt->measReq.measType)
887 /* measurement is already ongoing */
888 measCfmEvt->status.status = LCM_PRIM_NOK;
889 measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
890 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
891 measCfmEvt->measType = measType;
892 measCfmEvt->val.nonIpThMeas.numCfm++;
896 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
898 measCfmEvt->transId = measReqEvt->transId;
903 }/* kwUtlValidateL2Meas */
907 PUBLIC S16 kwUtlValidateIpThL2Meas
909 KwL2MeasReqEvt *measReqEvt,
910 KwL2MeasCfmEvt *measCfmEvt
913 PUBLIC S16 kwUtlValidateIpThL2Meas(measReqEvt, measCfmEvt)
914 KwL2MeasReqEvt *measReqEvt;
915 KwL2MeasCfmEvt *measCfmEvt;
922 TRC3(kwUtlValidateIpThL2Meas)
924 measType = measReqEvt->measReq.measType;
925 /* Check for the range of measType */
926 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
927 if((measType == 0x00) ||
930 measCfmEvt->transId = measReqEvt->transId;
931 measCfmEvt->measType = measType;
932 measCfmEvt->status.status = LCM_PRIM_NOK;
933 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
936 /*User can either request for Active UE,*
937 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
938 lsbNibble = measType & 0x0F;
939 msbNibble = measType & 0xF0;
941 if( (lsbNibble != 0) && (msbNibble != 0) )
943 measCfmEvt->transId = measReqEvt->transId;
944 measCfmEvt->measType = measType;
945 measCfmEvt->status.status = LCM_PRIM_NOK;
946 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
950 }/* kwUtlValidateL2Meas */
954 * @brief Handler for resetting the RB data structures
958 * This function resets the RB data structure after the expiry of
961 * @param[in] measCb Measurement Control Block.
968 PUBLIC Void kwUtlResetUlL2MeasInKwRb
975 PUBLIC Void kwUtlResetUlL2MeasInKwRb(measCb, measType)
984 KwUlUeCb *ueCb = NULL;
988 if (measCb->measType & LKW_L2MEAS_UL_IP)
990 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
992 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
994 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
996 if (measType & LKW_L2MEAS_UL_IP)
998 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
999 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
1003 if(ROK != kwDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
1004 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
1009 for (rbIdx = 0; rbIdx < KW_MAX_DRB_PER_UE; rbIdx++)
1011 if (ueCb->drbCb[rbIdx])
1013 ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
1019 } /* kwUtlResetUlL2MeasInKwRb */
1023 * @brief Handler for storing address of MeasData in rbCb at right index
1027 * This function is called when LM sends measReq message to RLC.
1038 PUBLIC Void kwUtlPlcMeasDatInL2Sts
1041 KwL2MeasRbCb *rbL2Cb,
1045 PUBLIC Void kwUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType)
1047 KwL2MeasRbCb *rbL2Cb;
1051 TRC3(kwUtlPlcMeasDatInL2Sts)
1053 /* We should check the number of measType in the request. This can be done
1054 * by looking at each bit in the measType. Also store the measData in the
1055 * correct index of l2Sts in RbCb.
1058 if(measType & LKW_L2MEAS_ACT_UE)
1060 rbL2Cb->l2Sts[KW_L2MEAS_ACT_UE] = measData;
1062 if(measType & LKW_L2MEAS_UU_LOSS)
1064 rbL2Cb->l2Sts[KW_L2MEAS_UU_LOSS] = measData;
1066 if(measType & LKW_L2MEAS_DL_IP )
1068 rbL2Cb->l2Sts[KW_L2MEAS_DL_IP] = measData;
1070 if(measType & LKW_L2MEAS_UL_IP)
1072 rbL2Cb->l2Sts[KW_L2MEAS_UL_IP] = measData;
1074 if(measType & LKW_L2MEAS_DL_DISC)
1076 rbL2Cb->l2Sts[KW_L2MEAS_DL_DISC] = measData;
1078 if(measType & LKW_L2MEAS_DL_DELAY)
1080 rbL2Cb->l2Sts[KW_L2MEAS_DL_DELAY] = measData;
1082 }/* End of kwUtlPlcMeasDatInL2Sts */
1083 #endif /* LTE_L2_MEAS */
1087 * @brief Store the UL buffer in hashList
1092 * Use the SN % binSize as key and store the received UL buffer
1093 * @param[in] recBufLst List CP array
1094 * @param[in] recBuf received buffer
1095 * @param[in] sn sn of the received buffer
1101 PUBLIC Void kwUtlStoreRecBuf
1103 CmLListCp *recBufLst,
1108 PUBLIC Void kwUtlStoreRecBuf(recBufLst, recBuf, sn)
1109 CmLListCp *recBufLst;
1116 TRC3(kwUtlStoreRecBuf)
1118 hashKey = (sn % KW_RCV_BUF_BIN_SIZE );
1119 recBuf->lnk.node = (PTR)recBuf;
1120 cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1123 } /* kwUtlStoreRecBuf */
1127 * @brief Retrieve the UL buffer from the list
1132 * Use the SN % binSize as key and retrieve the UL buffer
1133 * @param[in] recBufLst List CP array
1134 * @param[in] sn sn of the received buffer
1140 PUBLIC KwAmRecBuf* kwUtlGetRecBuf
1142 CmLListCp *recBufLst,
1146 PUBLIC KwAmRecBuf* kwUtlGetRecBuf(recBufLst, sn)
1147 CmLListCp *recBufLst;
1152 CmLListCp *recBufLstCp;
1154 CmLList *node = NULLP;
1156 TRC3(kwUtlGetRecBuf)
1158 hashKey = (sn % KW_RCV_BUF_BIN_SIZE );
1160 recBufLstCp = &recBufLst[hashKey];
1161 CM_LLIST_FIRST_NODE(recBufLstCp, node);
1164 recBuf = (KwAmRecBuf *) node->node;
1165 if(recBuf->amHdr.sn == sn)
1169 CM_LLIST_NEXT_NODE(recBufLstCp, node);
1172 } /* kwUtlStoreRecBuf */
1175 * @brief Delete the UL buffer from the list
1180 * Use the SN % binSize as key and retrieve the UL buffer
1181 * @param[in] recBufLst List CP array
1182 * @param[in] sn sn of the received buffer
1188 PUBLIC Void kwUtlDelRecBuf
1190 CmLListCp *recBufLst,
1195 PUBLIC Void kwUtlDelRecBuf(recBufLst, recBufi, gCb)
1196 CmLListCp *recBufLst;
1202 CmLListCp *recBufLstCp;
1204 TRC3(kwUtlDelRecBuf)
1206 hashKey = (recBuf->amHdr.sn % KW_RCV_BUF_BIN_SIZE );
1208 recBufLstCp = &recBufLst[hashKey];
1209 cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1210 KW_FREE_WC(gCb, recBuf, sizeof(KwAmRecBuf));
1213 } /* kwUtlDelRecBuf */
1218 /********************************************************************30**
1220 **********************************************************************/