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
404 Void rlcUtlCalUlIpThrPutIncTTI
411 Void rlcUtlCalUlIpThrPutIncTTI(gCb, rbCb, ttiCnt)
417 volatile uint32_t startTime = 0;
420 SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
422 RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:"
423 "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d",
424 rbCb->rbL2Cb.measOn,ttiCnt,
428 RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:"
429 "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d",
430 rbCb->rbL2Cb.measOn,ttiCnt,
435 /*Check if UL IP throughput measurement is ON for this RB or not*/
436 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))
438 if (TRUE == rbCb->ueCb->isUlBurstActive)
440 if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
442 /*Removed Error Print*/
444 if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
446 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.timeSummation +=
447 (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
451 rbCb->ueCb->firstPacketTTI = ttiCnt;
453 rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
457 rbCb->l2MeasIpThruput.prevTtiCnt = 0;
462 SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
463 } /* rlcUtlCalUlIpThrPutIncTTI */
470 * Handler to calculate the Ul Ip throughput for a LCH
475 * @param[in] rbCb RB control block
476 * @param[in] pdu Pdu of LCH
482 Void rlcUtlCalUlIpThrPut
490 Void rlcUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt)
497 MsgLen rlcSduSz = 0; /*Holds length of Rlc Sdu*/
498 volatile uint32_t startTime = 0;
501 SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
503 /*Check if UL IP throughput measurement is ON for this RB or not*/
504 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&
505 (TRUE == rbCb->ueCb->isUlBurstActive) &&
506 (rbCb->ueCb->firstPacketTTI) &&
507 (ttiCnt != rbCb->ueCb->firstPacketTTI))
509 SFndLenMsg(pdu, &rlcSduSz);
511 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
515 SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
516 } /* rlcUtlCalUlIpThrPut */
521 * @brief Handler for L2 Measurement timer expiry.
525 * This function is called when the l2 measurement timer expires.
526 * This function sends a consolidates the mesaurements taken during
527 * this time and sends the confirm .
529 * @param[in] measEvtCb Measurement Event Control Block.
537 S16 rlcUtlHdlL2TmrExp
540 RlcL2MeasEvtCb *measEvtCb
543 S16 rlcUtlHdlL2TmrExp(measEvtCb)
545 RlcL2MeasEvtCb *measEvtCb;
549 #ifdef LTE_L2_MEAS_RLC
553 /* Clean up the RB data structures */
554 if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
555 (measEvtCb->measCb.val.nonIpThMeas.numSamples))
557 measCb = &measEvtCb->measCb;
559 for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
561 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe +=
562 rlcCb.rlcL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
563 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
565 measEvtCb->val.nonIpThMeas.measCb.numSamples--;
566 rlcStartTmr(gCb, (PTR)measEvtCb, RLC_EVT_L2_TMR);
571 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb);
574 } /* rlcUtlHdlL2TmrExp */
577 * @brief Handler for Sending L2 Measurement confirm.
581 * This function sends a consolidates the mesaurements taken during
582 * this time and sends the confirm .
584 * @param[in] measEvtCb Measurement Event Control Block.
592 S16 rlcUtlSndUlL2MeasCfm
595 RlcL2MeasEvtCb *measEvtCb
598 S16 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb)
600 RlcL2MeasEvtCb *measEvtCb;
605 RlcL2MeasCfmEvt measCfmEvt;
609 /* Discard new changes starts */
612 /* Discard new changes ends */
614 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
616 RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
618 RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
621 /* Clean up the RB data structures */
622 measCb = &measEvtCb->measCb;
624 memset(&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
625 measCfmEvt.transId = measEvtCb->transId;
627 measCfmEvt.measType = measCb->measType;
628 measCfmEvt.status.status = LCM_PRIM_OK;
629 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
631 if( measCb->measType & LKW_L2MEAS_UL_IP)
633 RlcL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
634 RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
635 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
637 pUeInfoLstCfm[cfmIdx].numCfm = 0;
638 if (pUeInfoLstCb[cntr].isValid == TRUE)
640 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
641 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
643 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
645 qci = pUeInfoLstCb[cntr].qci[qciIdx];
646 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
648 if(measCb->measType & LKW_L2MEAS_UL_IP)
650 ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
651 ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
654 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
658 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
660 /* Converting it to kbps */
661 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
664 /* Reset the values after reporting to Application */
665 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
666 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
668 pUeInfoLstCfm[cfmIdx].numCfm++;
673 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
675 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
677 } /* rlcUtlSndUlL2MeasCfm */
680 * @brief Handler for Sending Negative confirm .
684 * This function is called when the l2 measurement cannot be started
685 * This function sends negative confirm for all the requests
687 * @param[in] gCb - RLC instance control block
688 * @param[in] measReqEvt Measurement Req Structure
689 * @param[in] measCfmEvt Confirmation to be sent to layer manager
697 S16 rlcUtlSndUlL2MeasNCfm
700 RlcL2MeasReqEvt *measReqEvt,
701 RlcL2MeasCfmEvt *measCfmEvt
704 S16 rlcUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt)
706 RlcL2MeasReqEvt *measReqEvt;
707 RlcL2MeasCfmEvt *measCfmEvt;
711 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
713 } /* kwUtlSndL2MeasNCfm */
715 #ifdef LTE_L2_MEAS_RLC
717 * @brief Validates the measurement request parameters.
721 * Function :rlcUtlValidateL2Meas
723 * @param[in] measReqEvt L2 measurement request received from layer manager.
724 * @param[out] measCfmEvt L2 measurement confirm to be prepared.
725 * @param[out] lChId List of LCh for the given Ue corresponding to QCIs
726 given in measurement request.
727 * @param[out] numLCh Number of LCh in array lChId.
731 S16 rlcUtlValidateL2Meas
733 RlcL2MeasReqEvt *measReqEvt,
734 RlcL2MeasCfmEvt *measCfmEvt,
739 S16 rlcUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh)
740 RlcL2MeasReqEvt *measReqEvt;
741 RlcL2MeasCfmEvt *measCfmEvt;
757 uint8_t lsbNibble = 0;
758 uint8_t msbNibble = 0;
759 uint8_t numFaild = 0;
764 measType = measReqEvt->measReq.measType;
765 /* Check for the range of measType */
766 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
767 if((measType == 0x00) ||
770 measCfmEvt->transId = measReqEvt->transId;
771 measCfmEvt->measType = measType;
772 measCfmEvt->status.status = LCM_PRIM_NOK;
773 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
776 /*User can either request for Active UE,*
777 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
778 lsbNibble = measType & 0x0F;
779 msbNibble = measType & 0xF0;
781 if( (lsbNibble != 0) && (msbNibble != 0) )
783 measCfmEvt->transId = measReqEvt->transId;
784 measCfmEvt->measType = measType;
785 measCfmEvt->status.status = LCM_PRIM_NOK;
786 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
790 /* Check for total maximum number of Measurement Control Block */
791 if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
793 measCfmEvt->transId = measReqEvt->transId;
794 measCfmEvt->measType = measType;
795 measCfmEvt->status.status = LCM_PRIM_NOK;
796 measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
800 /* Check that number of samples should be a non-zero value */
801 if(((measType & LKW_L2MEAS_ACT_UE) &&
802 (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
804 measCfmEvt->transId = measReqEvt->transId;
805 measCfmEvt->measType = measType;
806 measCfmEvt->status.status = LCM_PRIM_NOK;
807 measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
810 /* Check that measurement period should be completely divisible *
811 * number of sample. */
812 if(((measType & LKW_L2MEAS_ACT_UE) &&
813 ((measReqEvt->measPeriod %
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_INVALID_NUMSAM;
823 numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
824 qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
826 /* Check whether qci is configured or not */
827 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
829 qci = qciVal[qciIdx];
830 ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp),
831 (uint8_t *)&qci, (uint16_t)sizeof(qci), 0, (PTR *)&rbCb);
834 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
835 measCfmEvt->val.nonIpThMeas.numCfm++;
839 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
841 measCfmEvt->status.status = LCM_PRIM_NOK;
842 measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
843 measCfmEvt->measType = measType;
844 measCfmEvt->transId = measReqEvt->transId;
848 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
850 if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
852 /* measurement is already ongoing */
853 measCfmEvt->status.status = LCM_PRIM_NOK;
854 measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
855 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
856 measCfmEvt->measType = measType;
857 measCfmEvt->val.nonIpThMeas.numCfm++;
861 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
863 measCfmEvt->transId = measReqEvt->transId;
868 }/* rlcUtlValidateL2Meas */
872 S16 rlcUtlValidateIpThL2Meas
874 RlcL2MeasReqEvt *measReqEvt,
875 RlcL2MeasCfmEvt *measCfmEvt
878 S16 rlcUtlValidateIpThL2Meas(measReqEvt, measCfmEvt)
879 RlcL2MeasReqEvt *measReqEvt;
880 RlcL2MeasCfmEvt *measCfmEvt;
884 uint8_t lsbNibble = 0;
885 uint8_t msbNibble = 0;
887 measType = measReqEvt->measReq.measType;
888 /* Check for the range of measType */
889 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
890 if((measType == 0x00) ||
893 measCfmEvt->transId = measReqEvt->transId;
894 measCfmEvt->measType = measType;
895 measCfmEvt->status.status = LCM_PRIM_NOK;
896 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
899 /*User can either request for Active UE,*
900 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
901 lsbNibble = measType & 0x0F;
902 msbNibble = measType & 0xF0;
904 if( (lsbNibble != 0) && (msbNibble != 0) )
906 measCfmEvt->transId = measReqEvt->transId;
907 measCfmEvt->measType = measType;
908 measCfmEvt->status.status = LCM_PRIM_NOK;
909 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
913 }/* rlcUtlValidateL2Meas */
917 * @brief Handler for resetting the RB data structures
921 * This function resets the RB data structure after the expiry of
924 * @param[in] measCb Measurement Control Block.
931 Void rlcUtlResetUlL2MeasInRlcRb
938 Void rlcUtlResetUlL2MeasInRlcRb(measCb, measType)
947 RlcUlUeCb *ueCb = NULL;
951 if (measCb->measType & LKW_L2MEAS_UL_IP)
953 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
955 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
957 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
959 if (measType & LKW_L2MEAS_UL_IP)
961 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
962 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
966 if(ROK != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
967 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
972 for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
974 if (ueCb->drbCb[rbIdx])
976 ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
982 } /* rlcUtlResetUlL2MeasInRlcRb */
986 * @brief Handler for storing address of MeasData in rbCb at right index
990 * This function is called when LM sends measReq message to RLC.
1001 Void rlcUtlPlcMeasDatInL2Sts
1003 RlcL2Cntr *measData,
1004 RlcL2MeasRbCb *rbL2Cb,
1008 Void rlcUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType)
1009 RlcL2Cntr *measData;
1010 RlcL2MeasRbCb *rbL2Cb;
1014 /* We should check the number of measType in the request. This can be done
1015 * by looking at each bit in the measType. Also store the measData in the
1016 * correct index of l2Sts in RbCb.
1019 if(measType & LKW_L2MEAS_ACT_UE)
1021 rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
1023 if(measType & LKW_L2MEAS_UU_LOSS)
1025 rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
1027 if(measType & LKW_L2MEAS_DL_IP )
1029 rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
1031 if(measType & LKW_L2MEAS_UL_IP)
1033 rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
1035 if(measType & LKW_L2MEAS_DL_DISC)
1037 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
1039 if(measType & LKW_L2MEAS_DL_DELAY)
1041 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
1043 }/* End of rlcUtlPlcMeasDatInL2Sts */
1044 #endif /* LTE_L2_MEAS */
1048 * @brief Store the UL buffer in hashList
1053 * Use the SN % binSize as key and store the received UL buffer
1054 * @param[in] recBufLst List CP array
1055 * @param[in] recBuf received buffer
1056 * @param[in] sn sn of the received buffer
1061 void rlcUtlStoreRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcSn sn)
1065 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1066 recBuf->lnk.node = (PTR)recBuf;
1067 cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1070 } /* rlcUtlStoreRecBuf */
1074 * @brief Retrieve the UL buffer from the list
1079 * Use the SN % binSize as key and retrieve the UL buffer
1080 * @param[in] recBufLst List CP array
1081 * @param[in] sn sn of the received buffer
1086 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn)
1089 CmLListCp *recBufLstCp;
1090 RlcAmRecBuf *recBuf;
1091 CmLList *node = NULLP;
1093 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1095 recBufLstCp = &recBufLst[hashKey];
1096 CM_LLIST_FIRST_NODE(recBufLstCp, node);
1099 recBuf = (RlcAmRecBuf *) node->node;
1100 if(recBuf->amHdr.sn == sn)
1104 CM_LLIST_NEXT_NODE(recBufLstCp, node);
1107 } /* rlcUtlStoreRecBuf */
1110 * @brief Delete the UL buffer from the list
1115 * Use the SN % binSize as key and retrieve the UL buffer
1116 * @param[in] recBufLst List CP array
1117 * @param[in] sn sn of the received buffer
1122 void rlcUtlDelRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcCb *gCb)
1125 CmLListCp *recBufLstCp;
1127 hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE );
1129 recBufLstCp = &recBufLst[hashKey];
1130 cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1131 RLC_FREE_WC(gCb, recBuf, sizeof(RlcAmRecBuf));
1134 } /* rlcUtlDelRecBuf */
1139 /********************************************************************30**
1141 **********************************************************************/