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
31 --rlcUtlSendUlDataToDu
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 */
70 #include "rlc_utils.h"
71 #include "du_app_rlc_inf.h"
72 #include "rlc_upr_inf_api.h"
75 S16 SMrkUlPkt(Buffer *mbuf);
77 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn);
78 #define RLC_MODULE (RLC_DBGMASK_DUT | RLC_DBGMASK_UL) /* for debugging purpose */
84 * Handler for receiving data for multiple logical channels from MAC.
87 * This function receives the data sent by MAC for one or more
88 * logical channels.It calls the UMM or AMM functions to process
89 * the PDUs and send them to the uppper layer.
91 * @param[in] gCb - RLC instance control block
92 * @param[in] datIndInfo - Data Indication Information containing the PDU(s)
93 * for one or more logical channels
100 uint8_t rlcUtlRcvFrmMac(RlcCb *gCb, KwDatIndInfo *datIndInfo)
102 uint32_t count; /* Loop Counter */
103 KwPduInfo *pduInfo; /* PDU Information */
104 RlcUlRbCb *rbCb; /* RB Control Block */
105 RlcUlUeCb *ueCb; /* UE Control Block */
110 if( ROK != rlcDbmFetchUlUeCb(gCb,datIndInfo->rnti,datIndInfo->cellId,&(ueCb)))
112 /* Fetch UeCb failed */
113 DU_LOG("\nRLC : rlcUtlRcvFrmMac : UEID:%d UeCb not found",
115 /* free the buffers inside the datIndInfo */
117 for(i = 0; i< datIndInfo->numLch; i++)
119 for(j = 0; j < datIndInfo->lchData[i].pdu.numPdu; j++)
121 if(datIndInfo->lchData[i].pdu.mBuf[j])
123 RLC_FREE_BUF_WC(datIndInfo->lchData[i].pdu.mBuf[j]);
133 if (RGU_L2M_UL_BURST_START == datIndInfo->burstInd)
135 ueCb->isUlBurstActive = TRUE;
139 ueCb->firstPacketTTI = 0;
140 ueCb->isUlBurstActive = FALSE;
143 for ( count = 0;count < datIndInfo->numLch; count++ )
145 rbCb = ueCb->lCh[datIndInfo->lchData[count].lcId - 1].ulRbCb;
146 /* kw002.201 Removed allocation of pduInfo */
147 pduInfo = &(datIndInfo->lchData[count].pdu);
148 /* Fix for CR ccpu00138374,sometimes rbCb is NULL in UL path,
149 * So inorder to avoid the crash, added this preventive check
154 for(j = 0; j < pduInfo->numPdu; j++)
158 RLC_FREE_BUF_WC(pduInfo->mBuf[j]);
165 SMrkUlPkt(pduInfo->mBuf[0]);
167 if ( rbCb->mode == CM_LTE_MODE_UM )
169 /* kw005.201 added support for L2 Measurement */
171 rlcUmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
173 rlcUmmProcessPdus(gCb,rbCb,pduInfo);
176 else if (rbCb->mode == CM_LTE_MODE_AM )
178 /* kw005.201 added support for L2 Measurement */
180 rlcAmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
182 rlcAmmProcessPdus(gCb,rbCb,pduInfo);
192 * Handler for sending Data Indication to the upper layer.
195 * This function is used to send re-assembled SDU to the upper layer.
197 * @param[in] gCb - RLC instance Control Block
198 * @param[in] rbCb - RB Control Block
199 * @param[in] sdu - SDU to be sent to upper layer
204 uint8_t rlcUtlSendUlDataToDu(RlcCb *gCb, RlcUlRbCb *rbCb, Buffer *sdu)
207 KwuDatIndInfo *datIndInfo; /* Data Indication Information */
208 KwuDatIndInfo datIndInfoTmp;
210 RlcUlRrcMsgInfo *ulRrcMsgInfo;
211 uint16_t msgLen, copyLen;
215 /* Creating static memory for KwuDatIndInfo. #else will be
216 * removed once the testing is done on all platforms */
217 datIndInfo = &datIndInfoTmp;
219 #if (ERRCLASS & ERRCLS_ADD_RES )
220 if ( datIndInfo == NULLP )
222 DU_LOG("\nRLC : rlcUtlSendUlDataToDu: Memory allocation failed UEID:%d \
223 CELLID:%d", rbCb->rlcId.ueId, rbCb->rlcId.cellId);
227 #endif /* ERRCLASS & ERRCLS_ADD_RES */
229 RLC_MEM_CPY(&(datIndInfo->rlcId),&(rbCb->rlcId),sizeof(CmLteRlcId));
230 /* Set the "isOutofSeq" flag for each packet
231 * If packets are in-sequence set flag as TRUE else FALSE */
232 datIndInfo->isOutOfSeq = rbCb->m.amUl.isOutOfSeq;
235 /* Filling UL RRC Message Info */
236 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL,
237 ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
240 ulRrcMsgInfo->cellId = rbCb->rlcId.cellId;
241 ulRrcMsgInfo->ueIdx = rbCb->rlcId.ueId;
242 ulRrcMsgInfo->lcId = rbCb->lch.lChId;
243 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL,
244 ulRrcMsgInfo->rrcMsg, msgLen);
245 if (ulRrcMsgInfo->rrcMsg)
247 ODU_GET_MSG_LEN(sdu, (MsgLen *)&msgLen);
248 ODU_COPY_MSG_TO_FIX_BUF(sdu, 0, msgLen, ulRrcMsgInfo->rrcMsg, (MsgLen *)©Len);
249 ulRrcMsgInfo->msgLen = msgLen;
251 /* Sending UL RRC Message transfeer to DU APP */
252 memset(&pst, 0, sizeof(Pst));
253 FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_UL_RRC_MSG_TRANS_TO_DU);
254 rlcSendUlRrcMsgToDu(&pst, ulRrcMsgInfo);
258 DU_LOG("\nRLC : rlcUtlSendUlDataToDu: Memory allocation failed for rrcMsg");
259 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
265 DU_LOG("\nRLC : rlcUtlSendUlDataToDu: Memory allocation failed for ulRrcMsgInfo");
270 } /* rlcUtlSendUlDataToDu */
273 PRIVATE Void dumpRLCUlRbInformation(RlcUlRbCb* ulRbCb)
275 if(ulRbCb->mode == CM_LTE_MODE_UM)
278 U32 pdusInReceptionBuffer = 0;
279 U32 windSz = ulRbCb->m.umUl.umWinSz << 1;
281 for(i = 0; i< windSz; i++)
283 if(ulRbCb->m.umUl.recBuf[i] != NULLP)
285 pdusInReceptionBuffer++;
289 RLOG_ARG3(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
290 "UM UL UEID:%d CELLID:%d Reception Buffer size = %d",
291 (int)ulRbCb->rlcId.ueId,
292 (int)ulRbCb->rlcId.cellId,
293 (int)pdusInReceptionBuffer);
295 else if(ulRbCb->mode == CM_LTE_MODE_AM)
298 U32 pdusInReceptionBuffer = 0;
300 U32 windSz = RLC_AM_GET_WIN_SZ(ulRbCb->m.amUl.snLen) << 1;
302 for(i = 0; i< windSz; i++)
304 RlcAmRecBuf *recBuf = rlcUtlGetRecBuf(ulRbCb->m.amUl.recBufLst, i);
307 pdusInReceptionBuffer++;
308 totalSegs += (recBuf->segLst.count);
312 RLOG_ARG4(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
313 "AM UL UEID:%d CELLID:%d Reception Buf size = %d"
315 (int)ulRbCb->rlcId.ueId,
316 (int)ulRbCb->rlcId.cellId,
317 (int)pdusInReceptionBuffer,
322 Void DumpRLCUlDebugInformation(Void)
324 RlcCb* ulInst = rlcCb[0]; /* TODO : Check whether UL is 0 or 1 */
325 RlcUlCb* ulCb = ulInst->u.ulCb;
326 RlcUlUeCb *ueCb = NULLP;
328 /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
329 while (ROK == cmHashListGetNext(&ulCb->ueLstCp,
334 for(i = 0; i< RLC_MAX_SRB_PER_UE; i++)
336 RlcUlRbCb* ulRbCb = ueCb->srbCb[i];
339 dumpRLCUlRbInformation(ulRbCb);
342 for(i = 0; i< RLC_MAX_DRB_PER_UE; i++)
344 RlcUlRbCb* ulRbCb = ueCb->drbCb[i];
347 dumpRLCUlRbInformation(ulRbCb);
355 * kwUtlFreeUlRbCb() function is split into two functions
356 * - rlcAmmFreeUlRbCb() ---> gp_amm_ul.c
357 * - rlcUmmFreeUlRbCb() ---> gp_umm_ul.c
358 * and placed in respective files mentioned above
363 /* kw005.201 added support for L2 Measurement */
369 * Handler for initialisation of measurement
371 * @param[in] gCb - RLC instance Control Block
376 S16 rlcUtlL2MeasUlInit(RlcCb *gCb)
380 gCb->u.ulCb->rlcL2Cb.rlcNumMeas=0;
381 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
383 cmMemset((U8 *)&(gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[cntr]), 0, sizeof(RlcL2MeasEvtCb));
385 gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_UL_IP].measCb.measType = LKW_L2MEAS_UL_IP;
392 * Handler to calculate the Ul Ip throughput for a LCH
397 * @param[in] rbCb RB control block
398 * @param[in] pdu Pdu of LCH
404 Void rlcUtlCalUlIpThrPutIncTTI
411 Void rlcUtlCalUlIpThrPutIncTTI(gCb, rbCb, ttiCnt)
417 VOLATILE U32 startTime = 0;
418 TRC2(rlcUtlCalUlIpThrPutIncTTI)
421 SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
423 RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:"
424 "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d",
425 rbCb->rbL2Cb.measOn,ttiCnt,
429 RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:"
430 "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d",
431 rbCb->rbL2Cb.measOn,ttiCnt,
436 /*Check if UL IP throughput measurement is ON for this RB or not*/
437 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))
439 if (TRUE == rbCb->ueCb->isUlBurstActive)
441 if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
443 /*Removed Error Print*/
445 if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
447 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.timeSummation +=
448 (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
452 rbCb->ueCb->firstPacketTTI = ttiCnt;
454 rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
458 rbCb->l2MeasIpThruput.prevTtiCnt = 0;
463 SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
464 } /* rlcUtlCalUlIpThrPutIncTTI */
471 * Handler to calculate the Ul Ip throughput for a LCH
476 * @param[in] rbCb RB control block
477 * @param[in] pdu Pdu of LCH
483 Void rlcUtlCalUlIpThrPut
491 Void rlcUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt)
498 MsgLen rlcSduSz = 0; /*Holds length of Rlc Sdu*/
499 VOLATILE U32 startTime = 0;
500 TRC2(rlcUtlCalUlIpThrPut)
504 SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
506 /*Check if UL IP throughput measurement is ON for this RB or not*/
507 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&
508 (TRUE == rbCb->ueCb->isUlBurstActive) &&
509 (rbCb->ueCb->firstPacketTTI) &&
510 (ttiCnt != rbCb->ueCb->firstPacketTTI))
512 SFndLenMsg(pdu, &rlcSduSz);
514 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
518 SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
519 } /* rlcUtlCalUlIpThrPut */
524 * @brief Handler for L2 Measurement timer expiry.
528 * This function is called when the l2 measurement timer expires.
529 * This function sends a consolidates the mesaurements taken during
530 * this time and sends the confirm .
532 * @param[in] measEvtCb Measurement Event Control Block.
540 S16 rlcUtlHdlL2TmrExp
543 RlcL2MeasEvtCb *measEvtCb
546 S16 rlcUtlHdlL2TmrExp(measEvtCb)
548 RlcL2MeasEvtCb *measEvtCb;
551 TRC3(rlcUtlHdlL2TmrExp)
553 #ifdef LTE_L2_MEAS_RLC
557 /* Clean up the RB data structures */
558 if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
559 (measEvtCb->measCb.val.nonIpThMeas.numSamples))
561 measCb = &measEvtCb->measCb;
563 for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
565 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe +=
566 rlcCb.rlcL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
567 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
569 measEvtCb->val.nonIpThMeas.measCb.numSamples--;
570 rlcStartTmr(gCb, (PTR)measEvtCb, RLC_EVT_L2_TMR);
575 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb);
578 } /* rlcUtlHdlL2TmrExp */
581 * @brief Handler for Sending L2 Measurement confirm.
585 * This function sends a consolidates the mesaurements taken during
586 * this time and sends the confirm .
588 * @param[in] measEvtCb Measurement Event Control Block.
596 S16 rlcUtlSndUlL2MeasCfm
599 RlcL2MeasEvtCb *measEvtCb
602 S16 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb)
604 RlcL2MeasEvtCb *measEvtCb;
609 RlcL2MeasCfmEvt measCfmEvt;
614 /* Discard new changes starts */
617 /* Discard new changes ends */
619 TRC3(rlcUtlSndUlL2MeasCfm)
621 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
623 RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
625 RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
628 /* Clean up the RB data structures */
629 measCb = &measEvtCb->measCb;
631 cmMemset((U8*)&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
632 measCfmEvt.transId = measEvtCb->transId;
634 measCfmEvt.measType = measCb->measType;
635 measCfmEvt.status.status = LCM_PRIM_OK;
636 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
638 if( measCb->measType & LKW_L2MEAS_UL_IP)
640 RlcL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
641 RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
642 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
644 pUeInfoLstCfm[cfmIdx].numCfm = 0;
645 if (pUeInfoLstCb[cntr].isValid == TRUE)
647 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
648 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
650 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
652 qci = pUeInfoLstCb[cntr].qci[qciIdx];
653 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
655 if(measCb->measType & LKW_L2MEAS_UL_IP)
657 ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
658 ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
661 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
665 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
667 /* Converting it to kbps */
668 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
671 /* Reset the values after reporting to Application */
672 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
673 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
675 pUeInfoLstCfm[cfmIdx].numCfm++;
680 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
682 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
684 } /* rlcUtlSndUlL2MeasCfm */
687 * @brief Handler for Sending Negative confirm .
691 * This function is called when the l2 measurement cannot be started
692 * This function sends negative confirm for all the requests
694 * @param[in] gCb - RLC instance control block
695 * @param[in] measReqEvt Measurement Req Structure
696 * @param[in] measCfmEvt Confirmation to be sent to layer manager
704 S16 rlcUtlSndUlL2MeasNCfm
707 RlcL2MeasReqEvt *measReqEvt,
708 RlcL2MeasCfmEvt *measCfmEvt
711 S16 rlcUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt)
713 RlcL2MeasReqEvt *measReqEvt;
714 RlcL2MeasCfmEvt *measCfmEvt;
717 TRC3(rlcUtlSndUlL2MeasNCfm)
719 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
721 } /* kwUtlSndL2MeasNCfm */
723 #ifdef LTE_L2_MEAS_RLC
725 * @brief Validates the measurement request parameters.
729 * Function :rlcUtlValidateL2Meas
731 * @param[in] measReqEvt L2 measurement request received from layer manager.
732 * @param[out] measCfmEvt L2 measurement confirm to be prepared.
733 * @param[out] lChId List of LCh for the given Ue corresponding to QCIs
734 given in measurement request.
735 * @param[out] numLCh Number of LCh in array lChId.
739 S16 rlcUtlValidateL2Meas
741 RlcL2MeasReqEvt *measReqEvt,
742 RlcL2MeasCfmEvt *measCfmEvt,
747 S16 rlcUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh)
748 RlcL2MeasReqEvt *measReqEvt;
749 RlcL2MeasCfmEvt *measCfmEvt;
771 TRC3(rlcUtlValidateL2Meas)
776 measType = measReqEvt->measReq.measType;
777 /* Check for the range of measType */
778 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
779 if((measType == 0x00) ||
782 measCfmEvt->transId = measReqEvt->transId;
783 measCfmEvt->measType = measType;
784 measCfmEvt->status.status = LCM_PRIM_NOK;
785 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
788 /*User can either request for Active UE,*
789 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
790 lsbNibble = measType & 0x0F;
791 msbNibble = measType & 0xF0;
793 if( (lsbNibble != 0) && (msbNibble != 0) )
795 measCfmEvt->transId = measReqEvt->transId;
796 measCfmEvt->measType = measType;
797 measCfmEvt->status.status = LCM_PRIM_NOK;
798 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
802 /* Check for total maximum number of Measurement Control Block */
803 if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
805 measCfmEvt->transId = measReqEvt->transId;
806 measCfmEvt->measType = measType;
807 measCfmEvt->status.status = LCM_PRIM_NOK;
808 measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
812 /* Check that number of samples should be a non-zero value */
813 if(((measType & LKW_L2MEAS_ACT_UE) &&
814 (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
816 measCfmEvt->transId = measReqEvt->transId;
817 measCfmEvt->measType = measType;
818 measCfmEvt->status.status = LCM_PRIM_NOK;
819 measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
822 /* Check that measurement period should be completely divisible *
823 * number of sample. */
824 if(((measType & LKW_L2MEAS_ACT_UE) &&
825 ((measReqEvt->measPeriod %
826 measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
828 measCfmEvt->transId = measReqEvt->transId;
829 measCfmEvt->measType = measType;
830 measCfmEvt->status.status = LCM_PRIM_NOK;
831 measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
835 numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
836 qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
838 /* Check whether qci is configured or not */
839 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
841 qci = qciVal[qciIdx];
842 ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp),
843 (U8 *)&qci, (U16)sizeof(qci), 0, (PTR *)&rbCb);
846 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
847 measCfmEvt->val.nonIpThMeas.numCfm++;
851 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
853 measCfmEvt->status.status = LCM_PRIM_NOK;
854 measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
855 measCfmEvt->measType = measType;
856 measCfmEvt->transId = measReqEvt->transId;
860 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
862 if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
864 /* measurement is already ongoing */
865 measCfmEvt->status.status = LCM_PRIM_NOK;
866 measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
867 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
868 measCfmEvt->measType = measType;
869 measCfmEvt->val.nonIpThMeas.numCfm++;
873 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
875 measCfmEvt->transId = measReqEvt->transId;
880 }/* rlcUtlValidateL2Meas */
884 S16 rlcUtlValidateIpThL2Meas
886 RlcL2MeasReqEvt *measReqEvt,
887 RlcL2MeasCfmEvt *measCfmEvt
890 S16 rlcUtlValidateIpThL2Meas(measReqEvt, measCfmEvt)
891 RlcL2MeasReqEvt *measReqEvt;
892 RlcL2MeasCfmEvt *measCfmEvt;
899 TRC3(rlcUtlValidateIpThL2Meas)
901 measType = measReqEvt->measReq.measType;
902 /* Check for the range of measType */
903 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
904 if((measType == 0x00) ||
907 measCfmEvt->transId = measReqEvt->transId;
908 measCfmEvt->measType = measType;
909 measCfmEvt->status.status = LCM_PRIM_NOK;
910 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
913 /*User can either request for Active UE,*
914 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
915 lsbNibble = measType & 0x0F;
916 msbNibble = measType & 0xF0;
918 if( (lsbNibble != 0) && (msbNibble != 0) )
920 measCfmEvt->transId = measReqEvt->transId;
921 measCfmEvt->measType = measType;
922 measCfmEvt->status.status = LCM_PRIM_NOK;
923 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
927 }/* rlcUtlValidateL2Meas */
931 * @brief Handler for resetting the RB data structures
935 * This function resets the RB data structure after the expiry of
938 * @param[in] measCb Measurement Control Block.
945 Void rlcUtlResetUlL2MeasInRlcRb
952 Void rlcUtlResetUlL2MeasInRlcRb(measCb, measType)
961 RlcUlUeCb *ueCb = NULL;
965 if (measCb->measType & LKW_L2MEAS_UL_IP)
967 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
969 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
971 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
973 if (measType & LKW_L2MEAS_UL_IP)
975 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
976 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
980 if(ROK != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
981 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
986 for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
988 if (ueCb->drbCb[rbIdx])
990 ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
996 } /* rlcUtlResetUlL2MeasInRlcRb */
1000 * @brief Handler for storing address of MeasData in rbCb at right index
1004 * This function is called when LM sends measReq message to RLC.
1015 Void rlcUtlPlcMeasDatInL2Sts
1017 RlcL2Cntr *measData,
1018 RlcL2MeasRbCb *rbL2Cb,
1022 Void rlcUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType)
1023 RlcL2Cntr *measData;
1024 RlcL2MeasRbCb *rbL2Cb;
1028 TRC3(rlcUtlPlcMeasDatInL2Sts)
1030 /* We should check the number of measType in the request. This can be done
1031 * by looking at each bit in the measType. Also store the measData in the
1032 * correct index of l2Sts in RbCb.
1035 if(measType & LKW_L2MEAS_ACT_UE)
1037 rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
1039 if(measType & LKW_L2MEAS_UU_LOSS)
1041 rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
1043 if(measType & LKW_L2MEAS_DL_IP )
1045 rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
1047 if(measType & LKW_L2MEAS_UL_IP)
1049 rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
1051 if(measType & LKW_L2MEAS_DL_DISC)
1053 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
1055 if(measType & LKW_L2MEAS_DL_DELAY)
1057 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
1059 }/* End of rlcUtlPlcMeasDatInL2Sts */
1060 #endif /* LTE_L2_MEAS */
1064 * @brief Store the UL buffer in hashList
1069 * Use the SN % binSize as key and store the received UL buffer
1070 * @param[in] recBufLst List CP array
1071 * @param[in] recBuf received buffer
1072 * @param[in] sn sn of the received buffer
1077 void rlcUtlStoreRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcSn sn)
1081 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1082 recBuf->lnk.node = (PTR)recBuf;
1083 cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1086 } /* rlcUtlStoreRecBuf */
1090 * @brief Retrieve the UL buffer from the list
1095 * Use the SN % binSize as key and retrieve the UL buffer
1096 * @param[in] recBufLst List CP array
1097 * @param[in] sn sn of the received buffer
1102 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn)
1105 CmLListCp *recBufLstCp;
1106 RlcAmRecBuf *recBuf;
1107 CmLList *node = NULLP;
1109 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1111 recBufLstCp = &recBufLst[hashKey];
1112 CM_LLIST_FIRST_NODE(recBufLstCp, node);
1115 recBuf = (RlcAmRecBuf *) node->node;
1116 if(recBuf->amHdr.sn == sn)
1120 CM_LLIST_NEXT_NODE(recBufLstCp, node);
1123 } /* rlcUtlStoreRecBuf */
1126 * @brief Delete the UL buffer from the list
1131 * Use the SN % binSize as key and retrieve the UL buffer
1132 * @param[in] recBufLst List CP array
1133 * @param[in] sn sn of the received buffer
1138 void rlcUtlDelRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcCb *gCb)
1141 CmLListCp *recBufLstCp;
1143 hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE );
1145 recBufLstCp = &recBufLst[hashKey];
1146 cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1147 RLC_FREE_WC(gCb, recBuf, sizeof(RlcAmRecBuf));
1150 } /* rlcUtlDelRecBuf */
1155 /********************************************************************30**
1157 **********************************************************************/