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 static Void dumpRLCUlRbInformation(RlcUlRbCb* ulRbCb)
275 if(ulRbCb->mode == CM_LTE_MODE_UM)
278 uint32_t pdusInReceptionBuffer = 0;
279 uint32_t 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 uint32_t pdusInReceptionBuffer = 0;
299 uint32_t totalSegs = 0;
300 uint32_t 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 memset(&(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
403 Void rlcUtlCalUlIpThrPutIncTTI(RlcCb *gCb,RlcUlRbCb *rbCb,uint32_t ttiCnt)
405 volatile uint32_t startTime = 0;
408 SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
410 RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:"
411 "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d",
412 rbCb->rbL2Cb.measOn,ttiCnt,
416 RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:"
417 "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d",
418 rbCb->rbL2Cb.measOn,ttiCnt,
423 /*Check if UL IP throughput measurement is ON for this RB or not*/
424 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))
426 if (TRUE == rbCb->ueCb->isUlBurstActive)
428 if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
430 /*Removed Error Print*/
432 if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
434 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.timeSummation +=
435 (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
439 rbCb->ueCb->firstPacketTTI = ttiCnt;
441 rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
445 rbCb->l2MeasIpThruput.prevTtiCnt = 0;
450 SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
451 } /* rlcUtlCalUlIpThrPutIncTTI */
458 * Handler to calculate the Ul Ip throughput for a LCH
463 * @param[in] rbCb RB control block
464 * @param[in] pdu Pdu of LCH
469 Void rlcUtlCalUlIpThrPut
477 MsgLen rlcSduSz = 0; /*Holds length of Rlc Sdu*/
478 volatile uint32_t startTime = 0;
481 SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
483 /*Check if UL IP throughput measurement is ON for this RB or not*/
484 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&
485 (TRUE == rbCb->ueCb->isUlBurstActive) &&
486 (rbCb->ueCb->firstPacketTTI) &&
487 (ttiCnt != rbCb->ueCb->firstPacketTTI))
489 SFndLenMsg(pdu, &rlcSduSz);
491 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
495 SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
496 } /* rlcUtlCalUlIpThrPut */
501 * @brief Handler for L2 Measurement timer expiry.
505 * This function is called when the l2 measurement timer expires.
506 * This function sends a consolidates the mesaurements taken during
507 * this time and sends the confirm .
509 * @param[in] measEvtCb Measurement Event Control Block.
516 S16 rlcUtlHdlL2TmrExp(RlcCb *gCb,RlcL2MeasEvtCb *measEvtCb)
519 #ifdef LTE_L2_MEAS_RLC
523 /* Clean up the RB data structures */
524 if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
525 (measEvtCb->measCb.val.nonIpThMeas.numSamples))
527 measCb = &measEvtCb->measCb;
529 for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
531 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe +=
532 rlcCb.rlcL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
533 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
535 measEvtCb->val.nonIpThMeas.measCb.numSamples--;
536 rlcStartTmr(gCb, (PTR)measEvtCb, RLC_EVT_L2_TMR);
541 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb);
544 } /* rlcUtlHdlL2TmrExp */
547 * @brief Handler for Sending L2 Measurement confirm.
551 * This function sends a consolidates the mesaurements taken during
552 * this time and sends the confirm .
554 * @param[in] measEvtCb Measurement Event Control Block.
561 S16 rlcUtlSndUlL2MeasCfm(RlcCb *gCb,RlcL2MeasEvtCb *measEvtCb)
565 RlcL2MeasCfmEvt measCfmEvt;
569 /* Discard new changes starts */
572 /* Discard new changes ends */
574 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
576 RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
578 RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
581 /* Clean up the RB data structures */
582 measCb = &measEvtCb->measCb;
584 memset(&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
585 measCfmEvt.transId = measEvtCb->transId;
587 measCfmEvt.measType = measCb->measType;
588 measCfmEvt.status.status = LCM_PRIM_OK;
589 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
591 if( measCb->measType & LKW_L2MEAS_UL_IP)
593 RlcL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
594 RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
595 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
597 pUeInfoLstCfm[cfmIdx].numCfm = 0;
598 if (pUeInfoLstCb[cntr].isValid == TRUE)
600 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
601 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
603 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
605 qci = pUeInfoLstCb[cntr].qci[qciIdx];
606 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
608 if(measCb->measType & LKW_L2MEAS_UL_IP)
610 ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
611 ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
614 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
618 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
620 /* Converting it to kbps */
621 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
624 /* Reset the values after reporting to Application */
625 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
626 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
628 pUeInfoLstCfm[cfmIdx].numCfm++;
633 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
635 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
637 } /* rlcUtlSndUlL2MeasCfm */
640 * @brief Handler for Sending Negative confirm .
644 * This function is called when the l2 measurement cannot be started
645 * This function sends negative confirm for all the requests
647 * @param[in] gCb - RLC instance control block
648 * @param[in] measReqEvt Measurement Req Structure
649 * @param[in] measCfmEvt Confirmation to be sent to layer manager
656 S16 rlcUtlSndUlL2MeasNCfm(RlcCb *gCb,RlcL2MeasReqEvt *measReqEvt,RlcL2MeasCfmEvt *measCfmEvt)
659 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
661 } /* kwUtlSndL2MeasNCfm */
663 #ifdef LTE_L2_MEAS_RLC
665 * @brief Validates the measurement request parameters.
669 * Function :rlcUtlValidateL2Meas
671 * @param[in] measReqEvt L2 measurement request received from layer manager.
672 * @param[out] measCfmEvt L2 measurement confirm to be prepared.
673 * @param[out] lChId List of LCh for the given Ue corresponding to QCIs
674 given in measurement request.
675 * @param[out] numLCh Number of LCh in array lChId.
678 S16 rlcUtlValidateL2Meas
680 RlcL2MeasReqEvt *measReqEvt,
681 RlcL2MeasCfmEvt *measCfmEvt,
697 uint8_t lsbNibble = 0;
698 uint8_t msbNibble = 0;
699 uint8_t numFaild = 0;
704 measType = measReqEvt->measReq.measType;
705 /* Check for the range of measType */
706 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
707 if((measType == 0x00) ||
710 measCfmEvt->transId = measReqEvt->transId;
711 measCfmEvt->measType = measType;
712 measCfmEvt->status.status = LCM_PRIM_NOK;
713 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
716 /*User can either request for Active UE,*
717 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
718 lsbNibble = measType & 0x0F;
719 msbNibble = measType & 0xF0;
721 if( (lsbNibble != 0) && (msbNibble != 0) )
723 measCfmEvt->transId = measReqEvt->transId;
724 measCfmEvt->measType = measType;
725 measCfmEvt->status.status = LCM_PRIM_NOK;
726 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
730 /* Check for total maximum number of Measurement Control Block */
731 if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
733 measCfmEvt->transId = measReqEvt->transId;
734 measCfmEvt->measType = measType;
735 measCfmEvt->status.status = LCM_PRIM_NOK;
736 measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
740 /* Check that number of samples should be a non-zero value */
741 if(((measType & LKW_L2MEAS_ACT_UE) &&
742 (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
744 measCfmEvt->transId = measReqEvt->transId;
745 measCfmEvt->measType = measType;
746 measCfmEvt->status.status = LCM_PRIM_NOK;
747 measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
750 /* Check that measurement period should be completely divisible *
751 * number of sample. */
752 if(((measType & LKW_L2MEAS_ACT_UE) &&
753 ((measReqEvt->measPeriod %
754 measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
756 measCfmEvt->transId = measReqEvt->transId;
757 measCfmEvt->measType = measType;
758 measCfmEvt->status.status = LCM_PRIM_NOK;
759 measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
763 numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
764 qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
766 /* Check whether qci is configured or not */
767 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
769 qci = qciVal[qciIdx];
770 ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp),
771 (uint8_t *)&qci, (uint16_t)sizeof(qci), 0, (PTR *)&rbCb);
774 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
775 measCfmEvt->val.nonIpThMeas.numCfm++;
779 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
781 measCfmEvt->status.status = LCM_PRIM_NOK;
782 measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
783 measCfmEvt->measType = measType;
784 measCfmEvt->transId = measReqEvt->transId;
788 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
790 if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
792 /* measurement is already ongoing */
793 measCfmEvt->status.status = LCM_PRIM_NOK;
794 measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
795 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
796 measCfmEvt->measType = measType;
797 measCfmEvt->val.nonIpThMeas.numCfm++;
801 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
803 measCfmEvt->transId = measReqEvt->transId;
808 }/* rlcUtlValidateL2Meas */
811 S16 rlcUtlValidateIpThL2Meas(RlcL2MeasReqEvt *measReqEvt,RlcL2MeasCfmEvt *measCfmEvt)
814 uint8_t lsbNibble = 0;
815 uint8_t msbNibble = 0;
817 measType = measReqEvt->measReq.measType;
818 /* Check for the range of measType */
819 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
820 if((measType == 0x00) ||
823 measCfmEvt->transId = measReqEvt->transId;
824 measCfmEvt->measType = measType;
825 measCfmEvt->status.status = LCM_PRIM_NOK;
826 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
829 /*User can either request for Active UE,*
830 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
831 lsbNibble = measType & 0x0F;
832 msbNibble = measType & 0xF0;
834 if( (lsbNibble != 0) && (msbNibble != 0) )
836 measCfmEvt->transId = measReqEvt->transId;
837 measCfmEvt->measType = measType;
838 measCfmEvt->status.status = LCM_PRIM_NOK;
839 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
843 }/* rlcUtlValidateL2Meas */
847 * @brief Handler for resetting the RB data structures
851 * This function resets the RB data structure after the expiry of
854 * @param[in] measCb Measurement Control Block.
860 Void rlcUtlResetUlL2MeasInRlcRb(RlcCb *gCb,RlcL2MeasCb *measCb,uint8_t measType)
865 RlcUlUeCb *ueCb = NULL;
869 if (measCb->measType & LKW_L2MEAS_UL_IP)
871 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
873 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
875 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
877 if (measType & LKW_L2MEAS_UL_IP)
879 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
880 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
884 if(ROK != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
885 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
890 for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
892 if (ueCb->drbCb[rbIdx])
894 ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
900 } /* rlcUtlResetUlL2MeasInRlcRb */
904 * @brief Handler for storing address of MeasData in rbCb at right index
908 * This function is called when LM sends measReq message to RLC.
918 Void rlcUtlPlcMeasDatInL2Sts(RlcL2Cntr *measData,RlcL2MeasRbCb *rbL2Cb,uint8_t measType)
920 /* We should check the number of measType in the request. This can be done
921 * by looking at each bit in the measType. Also store the measData in the
922 * correct index of l2Sts in RbCb.
925 if(measType & LKW_L2MEAS_ACT_UE)
927 rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
929 if(measType & LKW_L2MEAS_UU_LOSS)
931 rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
933 if(measType & LKW_L2MEAS_DL_IP )
935 rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
937 if(measType & LKW_L2MEAS_UL_IP)
939 rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
941 if(measType & LKW_L2MEAS_DL_DISC)
943 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
945 if(measType & LKW_L2MEAS_DL_DELAY)
947 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
949 }/* End of rlcUtlPlcMeasDatInL2Sts */
950 #endif /* LTE_L2_MEAS */
954 * @brief Store the UL buffer in hashList
959 * Use the SN % binSize as key and store the received UL buffer
960 * @param[in] recBufLst List CP array
961 * @param[in] recBuf received buffer
962 * @param[in] sn sn of the received buffer
967 void rlcUtlStoreRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcSn sn)
971 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
972 recBuf->lnk.node = (PTR)recBuf;
973 cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
976 } /* rlcUtlStoreRecBuf */
980 * @brief Retrieve the UL buffer from the list
985 * Use the SN % binSize as key and retrieve the UL buffer
986 * @param[in] recBufLst List CP array
987 * @param[in] sn sn of the received buffer
992 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn)
995 CmLListCp *recBufLstCp;
997 CmLList *node = NULLP;
999 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1001 recBufLstCp = &recBufLst[hashKey];
1002 CM_LLIST_FIRST_NODE(recBufLstCp, node);
1005 recBuf = (RlcAmRecBuf *) node->node;
1006 if(recBuf->amHdr.sn == sn)
1010 CM_LLIST_NEXT_NODE(recBufLstCp, node);
1013 } /* rlcUtlStoreRecBuf */
1016 * @brief Delete the UL buffer from the list
1021 * Use the SN % binSize as key and retrieve the UL buffer
1022 * @param[in] recBufLst List CP array
1023 * @param[in] sn sn of the received buffer
1028 void rlcUtlDelRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcCb *gCb)
1031 CmLListCp *recBufLstCp;
1033 hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE );
1035 recBufLstCp = &recBufLst[hashKey];
1036 cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1037 RLC_FREE_WC(gCb, recBuf, sizeof(RlcAmRecBuf));
1040 } /* rlcUtlDelRecBuf */
1045 /********************************************************************30**
1047 **********************************************************************/