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 "common_def.h"
47 /* kw005.201 added support for L2 Measurement */
52 #include "ckw.h" /* CKW defines */
53 #include "kwu.h" /* KWU defines */
54 #include "lkw.h" /* LKW defines */
55 #include "rgu.h" /* RGU defines */
57 #include "kw_env.h" /* RLC environment options */
58 #include "kw.h" /* RLC defines */
59 #include "kw_err.h" /* Error defines */
60 #include "kw_ul.h" /* RLC Uplink defines */
62 /* extern (.x) include files */
63 #include "ckw.x" /* CKW includes */
64 #include "kwu.x" /* KWU includes */
65 #include "lkw.x" /* LKW includes */
66 #include "rgu.x" /* RGU includes */
68 #include "kw.x" /* RLC inlcudes */
69 #include "kw_ul.x" /* RLC uplink includes */
73 PUBLIC S16 SMrkUlPkt(Buffer *mbuf);
75 PUBLIC KwAmRecBuf* kwUtlGetRecBuf(CmLListCp *recBufLst, KwSn sn);
76 #define KW_MODULE (KW_DBGMASK_DUT | KW_DBGMASK_UL) /* for debugging purpose */
82 * Handler for receiving data for multiple logical channels from MAC.
85 * This function receives the data sent by MAC for one or more
86 * logical channels.It calls the UMM or AMM functions to process
87 * the PDUs and send them to the uppper layer.
89 * @param[in] gCb - RLC instance control block
90 * @param[in] datIndInfo - Data Indication Information containing the PDU(s)
91 * for one or more logical channels
99 PUBLIC S16 kwUtlRcvFrmLi
102 KwDatIndInfo *datIndInfo
105 PUBLIC S16 kwUtlRcvFrmLi(gCb,datIndInfo)
107 KwDatIndInfo *datIndInfo;
110 U32 count; /* Loop Counter */
111 KwPduInfo *pduInfo; /* PDU Information */
112 RlcUlRbCb *rbCb; /* RB Control Block */
113 RlcUlUeCb *ueCb; /* UE Control Block */
114 /* kw005.201 added support for L2 Measurement */
122 if( ROK != kwDbmFetchUlUeCb(gCb,datIndInfo->rnti,datIndInfo->cellId,&(ueCb)))
124 /* Fetch UeCb failed */
125 RLOG_ARG1(L_ERROR,DBG_CELLID,datIndInfo->cellId,
126 "UEID:%d UeCb not found",
128 /* free the buffers inside the datIndInfo */
130 for(i = 0; i< datIndInfo->numLch; i++)
132 for(j = 0; j < datIndInfo->lchData[i].pdu.numPdu; j++)
134 if(datIndInfo->lchData[i].pdu.mBuf[j])
136 RLC_FREE_BUF_WC(datIndInfo->lchData[i].pdu.mBuf[j]);
146 if (RGU_L2M_UL_BURST_START == datIndInfo->burstInd)
148 ueCb->isUlBurstActive = TRUE;
152 ueCb->firstPacketTTI = 0;
153 ueCb->isUlBurstActive = FALSE;
156 for ( count = 0;count < datIndInfo->numLch; count++ )
158 rbCb = ueCb->lCh[datIndInfo->lchData[count].lcId - 1].ulRbCb;
159 /* kw002.201 Removed allocation of pduInfo */
160 pduInfo = &(datIndInfo->lchData[count].pdu);
161 /* Fix for CR ccpu00138374,sometimes rbCb is NULL in UL path,
162 * So inorder to avoid the crash, added this preventive check
167 for(j = 0; j < pduInfo->numPdu; j++)
171 RLC_FREE_BUF_WC(pduInfo->mBuf[j]);
178 SMrkUlPkt(pduInfo->mBuf[0]);
180 if ( rbCb->mode == CM_LTE_MODE_UM )
182 /* kw005.201 added support for L2 Measurement */
184 kwUmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
186 kwUmmProcessPdus(gCb,rbCb,pduInfo);
189 else if (rbCb->mode == CM_LTE_MODE_AM )
191 /* kw005.201 added support for L2 Measurement */
193 kwAmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
195 kwAmmProcessPdus(gCb,rbCb,pduInfo);
205 * Handler for sending Data Indication to the upper layer.
208 * This function is used to send re-assembled SDU to the upper layer.
210 * @param[in] gCb - RLC instance Control Block
211 * @param[in] rbCb - RB Control Block
212 * @param[in] sdu - SDU to be sent to upper layer
218 PUBLIC S16 kwUtlSndDatInd
225 PUBLIC S16 kwUtlSndDatInd(gCb,rbCb,sdu)
232 KwuDatIndInfo *datIndInfo; /* Data Indication Information */
233 KwuDatIndInfo datIndInfoTmp;
240 /* Creating static memory for KwuDatIndInfo. #else will be
241 * removed once the testing is done on all platforms */
242 datIndInfo = &datIndInfoTmp;
244 #if (ERRCLASS & ERRCLS_ADD_RES )
245 if ( datIndInfo == NULLP )
247 RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
248 "Memory allocation failed UEID:%d CELLID:%d",
254 #endif /* ERRCLASS & ERRCLS_ADD_RES */
256 KW_MEM_CPY(&(datIndInfo->rlcId),&(rbCb->rlcId),sizeof(CmLteRlcId));
257 /* Set the "isOutofSeq" flag for each packet
258 * If packets are in-sequence set flag as TRUE else FALSE */
259 datIndInfo->isOutOfSeq = rbCb->m.amUl.isOutOfSeq;
262 /* If trace flag is enabled send the trace indication */
263 if(gCb->init.trc == TRUE)
265 /* Populate the trace params */
266 kwLmmSendTrc(gCb,KWU_EVT_DAT_IND, sdu);
270 KwUiKwuDatInd(&gCb->genCfg.lmPst, datIndInfo, sdu);
273 } /* kwUtlSndDatInd */
276 PRIVATE Void dumpRLCUlRbInformation(RlcUlRbCb* ulRbCb)
278 if(ulRbCb->mode == CM_LTE_MODE_UM)
281 U32 pdusInReceptionBuffer = 0;
282 U32 windSz = ulRbCb->m.umUl.umWinSz << 1;
284 for(i = 0; i< windSz; i++)
286 if(ulRbCb->m.umUl.recBuf[i] != NULLP)
288 pdusInReceptionBuffer++;
292 RLOG_ARG3(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
293 "UM UL UEID:%d CELLID:%d Reception Buffer size = %d",
294 (int)ulRbCb->rlcId.ueId,
295 (int)ulRbCb->rlcId.cellId,
296 (int)pdusInReceptionBuffer);
298 else if(ulRbCb->mode == CM_LTE_MODE_AM)
301 U32 pdusInReceptionBuffer = 0;
303 U32 windSz = KW_AM_GET_WIN_SZ(ulRbCb->m.amUl.snLen) << 1;
305 for(i = 0; i< windSz; i++)
307 KwAmRecBuf *recBuf = kwUtlGetRecBuf(ulRbCb->m.amUl.recBufLst, i);
310 pdusInReceptionBuffer++;
311 totalSegs += (recBuf->segLst.count);
315 RLOG_ARG4(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
316 "AM UL UEID:%d CELLID:%d Reception Buf size = %d"
318 (int)ulRbCb->rlcId.ueId,
319 (int)ulRbCb->rlcId.cellId,
320 (int)pdusInReceptionBuffer,
325 Void DumpRLCUlDebugInformation(Void)
327 RlcCb* ulInst = rlcCb[0]; /* TODO : Check whether UL is 0 or 1 */
328 RlcUlCb* ulCb = ulInst->u.ulCb;
329 RlcUlUeCb *ueCb = NULLP;
331 /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
332 while (ROK == cmHashListGetNext(&ulCb->ueLstCp,
337 for(i = 0; i< KW_MAX_SRB_PER_UE; i++)
339 RlcUlRbCb* ulRbCb = ueCb->srbCb[i];
342 dumpRLCUlRbInformation(ulRbCb);
345 for(i = 0; i< KW_MAX_DRB_PER_UE; i++)
347 RlcUlRbCb* ulRbCb = ueCb->drbCb[i];
350 dumpRLCUlRbInformation(ulRbCb);
358 * kwUtlFreeUlRbCb() function is split into two functions
359 * - kwAmmFreeUlRbCb() ---> gp_amm_ul.c
360 * - kwUmmFreeUlRbCb() ---> gp_umm_ul.c
361 * and placed in respective files mentioned above
366 /* kw005.201 added support for L2 Measurement */
372 * Handler for initialisation of measurement
374 * @param[in] gCb - RLC instance Control Block
379 S16 kwUtlL2MeasUlInit(RlcCb *gCb)
383 gCb->u.ulCb->kwL2Cb.kwNumMeas=0;
384 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
386 cmMemset((U8 *)&(gCb->u.ulCb->kwL2Cb.kwL2EvtCb[cntr]), 0, sizeof(KwL2MeasEvtCb));
388 gCb->u.ulCb->kwL2Cb.kwL2EvtCb[KW_L2MEAS_UL_IP].measCb.measType = LKW_L2MEAS_UL_IP;
395 * Handler to calculate the Ul Ip throughput for a LCH
400 * @param[in] rbCb RB control block
401 * @param[in] pdu Pdu of LCH
407 PUBLIC Void kwUtlCalUlIpThrPutIncTTI
414 PUBLIC Void kwUtlCalUlIpThrPutIncTTI(gCb, rbCb, ttiCnt)
420 VOLATILE U32 startTime = 0;
421 TRC2(kwUtlCalUlIpThrPutIncTTI)
424 SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
426 RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:"
427 "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d",
428 rbCb->rbL2Cb.measOn,ttiCnt,
432 RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:"
433 "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d",
434 rbCb->rbL2Cb.measOn,ttiCnt,
439 /*Check if UL IP throughput measurement is ON for this RB or not*/
440 if(KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))
442 if (TRUE == rbCb->ueCb->isUlBurstActive)
444 if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
446 /*Removed Error Print*/
448 if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
450 rbCb->rbL2Cb.l2Sts[KW_L2MEAS_UL_IP]->ulIpThruput.timeSummation +=
451 (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
455 rbCb->ueCb->firstPacketTTI = ttiCnt;
457 rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
461 rbCb->l2MeasIpThruput.prevTtiCnt = 0;
466 SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
467 } /* kwUtlCalUlIpThrPutIncTTI */
474 * Handler to calculate the Ul Ip throughput for a LCH
479 * @param[in] rbCb RB control block
480 * @param[in] pdu Pdu of LCH
486 PUBLIC Void kwUtlCalUlIpThrPut
494 PUBLIC Void kwUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt)
501 MsgLen rlcSduSz = 0; /*Holds length of Rlc Sdu*/
502 VOLATILE U32 startTime = 0;
503 TRC2(kwUtlCalUlIpThrPut)
507 SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
509 /*Check if UL IP throughput measurement is ON for this RB or not*/
510 if(KW_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&
511 (TRUE == rbCb->ueCb->isUlBurstActive) &&
512 (rbCb->ueCb->firstPacketTTI) &&
513 (ttiCnt != rbCb->ueCb->firstPacketTTI))
515 SFndLenMsg(pdu, &rlcSduSz);
517 rbCb->rbL2Cb.l2Sts[KW_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
521 SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
522 } /* kwUtlCalUlIpThrPut */
527 * @brief Handler for L2 Measurement timer expiry.
531 * This function is called when the l2 measurement timer expires.
532 * This function sends a consolidates the mesaurements taken during
533 * this time and sends the confirm .
535 * @param[in] measEvtCb Measurement Event Control Block.
543 PUBLIC S16 kwUtlHdlL2TmrExp
546 KwL2MeasEvtCb *measEvtCb
549 PUBLIC S16 kwUtlHdlL2TmrExp(measEvtCb)
551 KwL2MeasEvtCb *measEvtCb;
554 TRC3(kwUtlHdlL2TmrExp)
556 #ifdef LTE_L2_MEAS_RLC
560 /* Clean up the RB data structures */
561 if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
562 (measEvtCb->measCb.val.nonIpThMeas.numSamples))
564 measCb = &measEvtCb->measCb;
566 for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
568 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe +=
569 rlcCb.kwL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
570 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
572 measEvtCb->val.nonIpThMeas.measCb.numSamples--;
573 kwStartTmr(gCb, (PTR)measEvtCb, KW_EVT_L2_TMR);
578 kwUtlSndUlL2MeasCfm(gCb, measEvtCb);
581 } /* kwUtlHdlL2TmrExp */
584 * @brief Handler for Sending L2 Measurement confirm.
588 * This function sends a consolidates the mesaurements taken during
589 * this time and sends the confirm .
591 * @param[in] measEvtCb Measurement Event Control Block.
599 PUBLIC S16 kwUtlSndUlL2MeasCfm
602 KwL2MeasEvtCb *measEvtCb
605 PUBLIC S16 kwUtlSndUlL2MeasCfm(gCb, measEvtCb)
607 KwL2MeasEvtCb *measEvtCb;
612 KwL2MeasCfmEvt measCfmEvt;
617 /* Discard new changes starts */
620 /* Discard new changes ends */
622 TRC3(kwUtlSndUlL2MeasCfm)
624 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
626 RLOG1(L_DEBUG,"kwUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
628 RLOG1(L_DEBUG,"kwUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
631 /* Clean up the RB data structures */
632 measCb = &measEvtCb->measCb;
634 cmMemset((U8*)&measCfmEvt, 0, sizeof(KwL2MeasCfmEvt));
635 measCfmEvt.transId = measEvtCb->transId;
637 measCfmEvt.measType = measCb->measType;
638 measCfmEvt.status.status = LCM_PRIM_OK;
639 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
641 if( measCb->measType & LKW_L2MEAS_UL_IP)
643 KwL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
644 KwL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
645 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
647 pUeInfoLstCfm[cfmIdx].numCfm = 0;
648 if (pUeInfoLstCb[cntr].isValid == TRUE)
650 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
651 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
653 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
655 qci = pUeInfoLstCb[cntr].qci[qciIdx];
656 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
658 if(measCb->measType & LKW_L2MEAS_UL_IP)
660 ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
661 ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
664 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
668 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
670 /* Converting it to kbps */
671 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
674 /* Reset the values after reporting to Application */
675 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
676 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
678 pUeInfoLstCfm[cfmIdx].numCfm++;
683 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
685 KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
687 } /* kwUtlSndUlL2MeasCfm */
690 * @brief Handler for Sending Negative confirm .
694 * This function is called when the l2 measurement cannot be started
695 * This function sends negative confirm for all the requests
697 * @param[in] gCb - RLC instance control block
698 * @param[in] measReqEvt Measurement Req Structure
699 * @param[in] measCfmEvt Confirmation to be sent to layer manager
707 PUBLIC S16 kwUtlSndUlL2MeasNCfm
710 KwL2MeasReqEvt *measReqEvt,
711 KwL2MeasCfmEvt *measCfmEvt
714 PUBLIC S16 kwUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt)
716 KwL2MeasReqEvt *measReqEvt;
717 KwL2MeasCfmEvt *measCfmEvt;
720 TRC3(kwUtlSndUlL2MeasNCfm)
722 KwMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
724 } /* kwUtlSndL2MeasNCfm */
726 #ifdef LTE_L2_MEAS_RLC
728 * @brief Validates the measurement request parameters.
732 * Function :kwUtlValidateL2Meas
734 * @param[in] measReqEvt L2 measurement request received from layer manager.
735 * @param[out] measCfmEvt L2 measurement confirm to be prepared.
736 * @param[out] lChId List of LCh for the given Ue corresponding to QCIs
737 given in measurement request.
738 * @param[out] numLCh Number of LCh in array lChId.
742 PUBLIC S16 kwUtlValidateL2Meas
744 KwL2MeasReqEvt *measReqEvt,
745 KwL2MeasCfmEvt *measCfmEvt,
750 PUBLIC S16 kwUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh)
751 KwL2MeasReqEvt *measReqEvt;
752 KwL2MeasCfmEvt *measCfmEvt;
774 TRC3(kwUtlValidateL2Meas)
779 measType = measReqEvt->measReq.measType;
780 /* Check for the range of measType */
781 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
782 if((measType == 0x00) ||
785 measCfmEvt->transId = measReqEvt->transId;
786 measCfmEvt->measType = measType;
787 measCfmEvt->status.status = LCM_PRIM_NOK;
788 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
791 /*User can either request for Active UE,*
792 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
793 lsbNibble = measType & 0x0F;
794 msbNibble = measType & 0xF0;
796 if( (lsbNibble != 0) && (msbNibble != 0) )
798 measCfmEvt->transId = measReqEvt->transId;
799 measCfmEvt->measType = measType;
800 measCfmEvt->status.status = LCM_PRIM_NOK;
801 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
805 /* Check for total maximum number of Measurement Control Block */
806 if(rlcCb.kwL2Cb.kwNumMeas >= LKW_MAX_L2MEAS )
808 measCfmEvt->transId = measReqEvt->transId;
809 measCfmEvt->measType = measType;
810 measCfmEvt->status.status = LCM_PRIM_NOK;
811 measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
815 /* Check that number of samples should be a non-zero value */
816 if(((measType & LKW_L2MEAS_ACT_UE) &&
817 (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
819 measCfmEvt->transId = measReqEvt->transId;
820 measCfmEvt->measType = measType;
821 measCfmEvt->status.status = LCM_PRIM_NOK;
822 measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
825 /* Check that measurement period should be completely divisible *
826 * number of sample. */
827 if(((measType & LKW_L2MEAS_ACT_UE) &&
828 ((measReqEvt->measPeriod %
829 measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
831 measCfmEvt->transId = measReqEvt->transId;
832 measCfmEvt->measType = measType;
833 measCfmEvt->status.status = LCM_PRIM_NOK;
834 measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
838 numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
839 qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
841 /* Check whether qci is configured or not */
842 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
844 qci = qciVal[qciIdx];
845 ret = cmHashListFind(&(rlcCb.kwL2Cb.qciHlCp),
846 (U8 *)&qci, (U16)sizeof(qci), 0, (PTR *)&rbCb);
849 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
850 measCfmEvt->val.nonIpThMeas.numCfm++;
854 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
856 measCfmEvt->status.status = LCM_PRIM_NOK;
857 measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
858 measCfmEvt->measType = measType;
859 measCfmEvt->transId = measReqEvt->transId;
863 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
865 if(rlcCb.kwL2Cb.measOn[qci] & measReqEvt->measReq.measType)
867 /* measurement is already ongoing */
868 measCfmEvt->status.status = LCM_PRIM_NOK;
869 measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
870 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
871 measCfmEvt->measType = measType;
872 measCfmEvt->val.nonIpThMeas.numCfm++;
876 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
878 measCfmEvt->transId = measReqEvt->transId;
883 }/* kwUtlValidateL2Meas */
887 PUBLIC S16 kwUtlValidateIpThL2Meas
889 KwL2MeasReqEvt *measReqEvt,
890 KwL2MeasCfmEvt *measCfmEvt
893 PUBLIC S16 kwUtlValidateIpThL2Meas(measReqEvt, measCfmEvt)
894 KwL2MeasReqEvt *measReqEvt;
895 KwL2MeasCfmEvt *measCfmEvt;
902 TRC3(kwUtlValidateIpThL2Meas)
904 measType = measReqEvt->measReq.measType;
905 /* Check for the range of measType */
906 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
907 if((measType == 0x00) ||
910 measCfmEvt->transId = measReqEvt->transId;
911 measCfmEvt->measType = measType;
912 measCfmEvt->status.status = LCM_PRIM_NOK;
913 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
916 /*User can either request for Active UE,*
917 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
918 lsbNibble = measType & 0x0F;
919 msbNibble = measType & 0xF0;
921 if( (lsbNibble != 0) && (msbNibble != 0) )
923 measCfmEvt->transId = measReqEvt->transId;
924 measCfmEvt->measType = measType;
925 measCfmEvt->status.status = LCM_PRIM_NOK;
926 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
930 }/* kwUtlValidateL2Meas */
934 * @brief Handler for resetting the RB data structures
938 * This function resets the RB data structure after the expiry of
941 * @param[in] measCb Measurement Control Block.
948 PUBLIC Void kwUtlResetUlL2MeasInKwRb
955 PUBLIC Void kwUtlResetUlL2MeasInKwRb(measCb, measType)
964 RlcUlUeCb *ueCb = NULL;
968 if (measCb->measType & LKW_L2MEAS_UL_IP)
970 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
972 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
974 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
976 if (measType & LKW_L2MEAS_UL_IP)
978 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
979 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
983 if(ROK != kwDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
984 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
989 for (rbIdx = 0; rbIdx < KW_MAX_DRB_PER_UE; rbIdx++)
991 if (ueCb->drbCb[rbIdx])
993 ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
999 } /* kwUtlResetUlL2MeasInKwRb */
1003 * @brief Handler for storing address of MeasData in rbCb at right index
1007 * This function is called when LM sends measReq message to RLC.
1018 PUBLIC Void kwUtlPlcMeasDatInL2Sts
1021 KwL2MeasRbCb *rbL2Cb,
1025 PUBLIC Void kwUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType)
1027 KwL2MeasRbCb *rbL2Cb;
1031 TRC3(kwUtlPlcMeasDatInL2Sts)
1033 /* We should check the number of measType in the request. This can be done
1034 * by looking at each bit in the measType. Also store the measData in the
1035 * correct index of l2Sts in RbCb.
1038 if(measType & LKW_L2MEAS_ACT_UE)
1040 rbL2Cb->l2Sts[KW_L2MEAS_ACT_UE] = measData;
1042 if(measType & LKW_L2MEAS_UU_LOSS)
1044 rbL2Cb->l2Sts[KW_L2MEAS_UU_LOSS] = measData;
1046 if(measType & LKW_L2MEAS_DL_IP )
1048 rbL2Cb->l2Sts[KW_L2MEAS_DL_IP] = measData;
1050 if(measType & LKW_L2MEAS_UL_IP)
1052 rbL2Cb->l2Sts[KW_L2MEAS_UL_IP] = measData;
1054 if(measType & LKW_L2MEAS_DL_DISC)
1056 rbL2Cb->l2Sts[KW_L2MEAS_DL_DISC] = measData;
1058 if(measType & LKW_L2MEAS_DL_DELAY)
1060 rbL2Cb->l2Sts[KW_L2MEAS_DL_DELAY] = measData;
1062 }/* End of kwUtlPlcMeasDatInL2Sts */
1063 #endif /* LTE_L2_MEAS */
1067 * @brief Store the UL buffer in hashList
1072 * Use the SN % binSize as key and store the received UL buffer
1073 * @param[in] recBufLst List CP array
1074 * @param[in] recBuf received buffer
1075 * @param[in] sn sn of the received buffer
1081 PUBLIC Void kwUtlStoreRecBuf
1083 CmLListCp *recBufLst,
1088 PUBLIC Void kwUtlStoreRecBuf(recBufLst, recBuf, sn)
1089 CmLListCp *recBufLst;
1096 TRC3(kwUtlStoreRecBuf)
1098 hashKey = (sn % KW_RCV_BUF_BIN_SIZE );
1099 recBuf->lnk.node = (PTR)recBuf;
1100 cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1103 } /* kwUtlStoreRecBuf */
1107 * @brief Retrieve the UL buffer from the list
1112 * Use the SN % binSize as key and retrieve the UL buffer
1113 * @param[in] recBufLst List CP array
1114 * @param[in] sn sn of the received buffer
1120 PUBLIC KwAmRecBuf* kwUtlGetRecBuf
1122 CmLListCp *recBufLst,
1126 PUBLIC KwAmRecBuf* kwUtlGetRecBuf(recBufLst, sn)
1127 CmLListCp *recBufLst;
1132 CmLListCp *recBufLstCp;
1134 CmLList *node = NULLP;
1136 TRC3(kwUtlGetRecBuf)
1138 hashKey = (sn % KW_RCV_BUF_BIN_SIZE );
1140 recBufLstCp = &recBufLst[hashKey];
1141 CM_LLIST_FIRST_NODE(recBufLstCp, node);
1144 recBuf = (KwAmRecBuf *) node->node;
1145 if(recBuf->amHdr.sn == sn)
1149 CM_LLIST_NEXT_NODE(recBufLstCp, node);
1152 } /* kwUtlStoreRecBuf */
1155 * @brief Delete the UL buffer from the list
1160 * Use the SN % binSize as key and retrieve the UL buffer
1161 * @param[in] recBufLst List CP array
1162 * @param[in] sn sn of the received buffer
1168 PUBLIC Void kwUtlDelRecBuf
1170 CmLListCp *recBufLst,
1175 PUBLIC Void kwUtlDelRecBuf(recBufLst, recBufi, gCb)
1176 CmLListCp *recBufLst;
1182 CmLListCp *recBufLstCp;
1184 TRC3(kwUtlDelRecBuf)
1186 hashKey = (recBuf->amHdr.sn % KW_RCV_BUF_BIN_SIZE );
1188 recBufLstCp = &recBufLst[hashKey];
1189 cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1190 RLC_FREE_WC(gCb, recBuf, sizeof(KwAmRecBuf));
1193 } /* kwUtlDelRecBuf */
1198 /********************************************************************30**
1200 **********************************************************************/