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 **********************************************************************/
38 /** @file rlc_utl_ul.c
39 @brief RLC Utility Module
42 /* header (.h) include files */
43 #include "common_def.h"
44 /* kw005.201 added support for L2 Measurement */
49 #include "ckw.h" /* CKW defines */
50 #include "kwu.h" /* KWU defines */
51 #include "lkw.h" /* LKW defines */
52 #include "rgu.h" /* RGU defines */
53 #include "rlc_env.h" /* RLC environment options */
54 #include "rlc_err.h" /* Error defines */
57 /* extern (.x) include files */
58 #include "ckw.x" /* CKW includes */
59 #include "kwu.x" /* KWU includes */
60 #include "lkw.x" /* LKW includes */
61 #include "rgu.x" /* RGU includes */
63 #include "rlc_utils.h" /* RLC defines */
64 #include "rlc_ul.h" /* RLC Uplink defines */
65 #include "du_app_rlc_inf.h"
66 #include "rlc_upr_inf_api.h"
69 S16 SMrkUlPkt(Buffer *mbuf);
71 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn);
72 #define RLC_MODULE (RLC_DBGMASK_DUT | RLC_DBGMASK_UL) /* for debugging purpose */
78 * Handler for receiving data for multiple logical channels from MAC.
81 * This function receives the data sent by MAC for one or more
82 * logical channels.It calls the UMM or AMM functions to process
83 * the PDUs and send them to the uppper layer.
85 * @param[in] gCb - RLC instance control block
86 * @param[in] datIndInfo - Data Indication Information containing the PDU(s)
87 * for one or more logical channels
94 uint8_t rlcUtlRcvFrmMac(RlcCb *gCb, KwDatIndInfo *datIndInfo)
96 uint32_t count; /* Loop Counter */
97 KwPduInfo *pduInfo; /* PDU Information */
98 RlcUlRbCb *rbCb; /* RB Control Block */
99 RlcUlUeCb *ueCb; /* UE Control Block */
104 if( ROK != rlcDbmFetchUlUeCb(gCb,datIndInfo->rnti,datIndInfo->cellId,&(ueCb)))
106 /* Fetch UeCb failed */
107 DU_LOG("\nERROR --> RLC_UL : rlcUtlRcvFrmMac : UEID:%d UeCb not found",
109 /* free the buffers inside the datIndInfo */
111 for(i = 0; i< datIndInfo->numLch; i++)
113 for(j = 0; j < datIndInfo->lchData[i].pdu.numPdu; j++)
115 if(datIndInfo->lchData[i].pdu.mBuf[j])
117 ODU_PUT_MSG_BUF(datIndInfo->lchData[i].pdu.mBuf[j]);
127 if (RGU_L2M_UL_BURST_START == datIndInfo->burstInd)
129 ueCb->isUlBurstActive = TRUE;
133 ueCb->firstPacketTTI = 0;
134 ueCb->isUlBurstActive = FALSE;
137 for ( count = 0;count < datIndInfo->numLch; count++ )
139 rbCb = ueCb->lCh[datIndInfo->lchData[count].lcId - 1].ulRbCb;
140 /* kw002.201 Removed allocation of pduInfo */
141 pduInfo = &(datIndInfo->lchData[count].pdu);
142 /* Fix for CR ccpu00138374,sometimes rbCb is NULL in UL path,
143 * So inorder to avoid the crash, added this preventive check
148 for(j = 0; j < pduInfo->numPdu; j++)
152 ODU_PUT_MSG_BUF(pduInfo->mBuf[j]);
159 SMrkUlPkt(pduInfo->mBuf[0]);
161 if ( rbCb->mode == RLC_MODE_UM )
163 /* kw005.201 added support for L2 Measurement */
165 rlcUmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
167 rlcUmmProcessPdus(gCb,rbCb,pduInfo);
170 else if (rbCb->mode == RLC_MODE_AM )
172 /* kw005.201 added support for L2 Measurement */
174 rlcAmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
176 rlcAmmProcessPdus(gCb,rbCb,pduInfo);
186 * Handler for sending Data Indication to the upper layer.
189 * This function is used to send re-assembled SDU to the upper layer.
191 * @param[in] gCb - RLC instance Control Block
192 * @param[in] rbCb - RB Control Block
193 * @param[in] sdu - SDU to be sent to upper layer
198 uint8_t rlcUtlSendUlDataToDu(RlcCb *gCb, RlcUlRbCb *rbCb, Buffer *sdu)
201 KwuDatIndInfo *datIndInfo; /* Data Indication Information */
202 KwuDatIndInfo datIndInfoTmp;
204 RlcUlRrcMsgInfo *ulRrcMsgInfo;
205 RlcUlUserDatInfo *ulUserDatInfo;
206 uint16_t msgLen, copyLen;
210 /* Creating static memory for KwuDatIndInfo. #else will be
211 * removed once the testing is done on all platforms */
212 datIndInfo = &datIndInfoTmp;
213 if (datIndInfo == NULLP)
215 DU_LOG("\nERROR --> RLC_UL: rlcUtlSendUlDataToDu: Memory allocation failed UEID:%d \
216 CELLID:%d", rbCb->rlcId.ueId, rbCb->rlcId.cellId);
217 ODU_PUT_MSG_BUF(sdu);
221 RLC_MEM_CPY(&(datIndInfo->rlcId),&(rbCb->rlcId),sizeof(CmLteRlcId));
222 /* Set the "isOutofSeq" flag for each packet
223 * If packets are in-sequence set flag as TRUE else FALSE */
224 datIndInfo->isOutOfSeq = rbCb->m.amUl.isOutOfSeq;
227 if(rbCb->rlcId.rbType == RB_TYPE_SRB)
229 /* Filling UL RRC Message Info if UL msg is not received on SRBs*/
230 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL,
231 ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
234 ulRrcMsgInfo->cellId = rbCb->rlcId.cellId;
235 ulRrcMsgInfo->ueIdx = rbCb->rlcId.ueId;
236 ulRrcMsgInfo->lcId = rbCb->lch.lChId;
237 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL,
238 ulRrcMsgInfo->rrcMsg, msgLen);
239 if (ulRrcMsgInfo->rrcMsg)
241 ODU_GET_MSG_LEN(sdu, (MsgLen *)&msgLen);
242 ODU_COPY_MSG_TO_FIX_BUF(sdu, 0, msgLen, ulRrcMsgInfo->rrcMsg, (MsgLen *)©Len);
243 ulRrcMsgInfo->msgLen = msgLen;
245 /* Sending UL RRC Message transfeer to DU APP */
246 memset(&pst, 0, sizeof(Pst));
247 FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_UL_RRC_MSG_TRANS_TO_DU);
248 rlcSendUlRrcMsgToDu(&pst, ulRrcMsgInfo);
252 DU_LOG("\nERROR --> RLC_UL: rlcUtlSendUlDataToDu: Memory allocation failed for rrcMsg");
253 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
259 DU_LOG("\nERROR --> RLC_UL: rlcUtlSendUlDataToDu: Memory allocation failed for ulRrcMsgInfo");
263 else if(rbCb->rlcId.rbType == RB_TYPE_DRB)
265 /* Filling UL User Data Info if UL msg is received on a DRB */
266 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, ulUserDatInfo, sizeof(RlcUlUserDatInfo));
269 ulUserDatInfo->cellId = rbCb->rlcId.cellId;
270 ulUserDatInfo->ueIdx = rbCb->rlcId.ueId;
271 ulUserDatInfo->rbId = rbCb->rlcId.rbId;
272 RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, ulUserDatInfo->userData, msgLen);
273 if (ulUserDatInfo->userData)
275 ODU_GET_MSG_LEN(sdu, (MsgLen *)&msgLen);
276 ODU_COPY_MSG_TO_FIX_BUF(sdu, 0, msgLen, ulUserDatInfo->userData, (MsgLen *)©Len);
277 ulUserDatInfo->msgLen = msgLen;
279 /* Sending UL RRC Message transfeer to DU APP */
280 memset(&pst, 0, sizeof(Pst));
281 FILL_PST_RLC_TO_DUAPP(pst, RLC_UL_INST, EVENT_UL_USER_DATA_TRANS_TO_DU);
282 rlcSendUlUserDataToDu(&pst, ulUserDatInfo);
286 DU_LOG("\nERROR --> RLC_UL: rlcUtlSendUlDataToDu: Memory allocation failed for user data");
287 RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, ulUserDatInfo, sizeof(RlcUlUserDatInfo));
293 DU_LOG("\nERROR --> RLC_UL: rlcUtlSendUlDataToDu: Memory allocation failed for ulUserDatInfo");
298 } /* rlcUtlSendUlDataToDu */
301 static Void dumpRLCUlRbInformation(RlcUlRbCb* ulRbCb)
303 if(ulRbCb->mode == RLC_MODE_UM)
306 uint32_t pdusInReceptionBuffer = 0;
307 uint32_t totalSegs = 0;
309 for(i = 0; i< RLC_RCV_BUF_BIN_SIZE; i++)
311 RlcUmRecBuf *recBuf = rlcUtlGetUmRecBuf(ulRbCb->m.umUl.recBufLst, i);
314 pdusInReceptionBuffer++;
315 totalSegs += (recBuf->segLst.count);
319 DU_LOG("\nDEBUG --> RLC_UL: UM UL UEID:%d CELLID:%d Reception Buffer size = %d Total segs = %d",
320 ulRbCb->rlcId.ueId, ulRbCb->rlcId.cellId, pdusInReceptionBuffer, totalSegs);
322 else if(ulRbCb->mode == RLC_MODE_AM)
325 uint32_t pdusInReceptionBuffer = 0;
326 uint32_t totalSegs = 0;
327 uint32_t windSz = RLC_AM_GET_WIN_SZ(ulRbCb->m.amUl.snLen) << 1;
329 for(i = 0; i< windSz; i++)
331 RlcAmRecBuf *recBuf = rlcUtlGetRecBuf(ulRbCb->m.amUl.recBufLst, i);
334 pdusInReceptionBuffer++;
335 totalSegs += (recBuf->segLst.count);
339 DU_LOG("\nDEBUG --> RLC_UL: AM UL UEID:%d CELLID:%d Reception Buf size = %d total segs = %d",
340 ulRbCb->rlcId.ueId, ulRbCb->rlcId.cellId, pdusInReceptionBuffer, totalSegs);
344 Void DumpRLCUlDebugInformation(Void)
346 RlcCb* ulInst = rlcCb[0]; /* TODO : Check whether UL is 0 or 1 */
347 RlcUlCb* ulCb = ulInst->u.ulCb;
348 RlcUlUeCb *ueCb = NULLP;
350 /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
351 while (ROK == cmHashListGetNext(&ulCb->ueLstCp,
356 for(i = 0; i< RLC_MAX_SRB_PER_UE; i++)
358 RlcUlRbCb* ulRbCb = ueCb->srbCb[i];
361 dumpRLCUlRbInformation(ulRbCb);
364 for(i = 0; i< RLC_MAX_DRB_PER_UE; i++)
366 RlcUlRbCb* ulRbCb = ueCb->drbCb[i];
369 dumpRLCUlRbInformation(ulRbCb);
377 * kwUtlFreeUlRbCb() function is split into two functions
378 * - rlcAmmFreeUlRbCb() ---> gp_amm_ul.c
379 * - rlcUmmFreeUlRbCb() ---> gp_umm_ul.c
380 * and placed in respective files mentioned above
385 /* kw005.201 added support for L2 Measurement */
391 * Handler for initialisation of measurement
393 * @param[in] gCb - RLC instance Control Block
398 S16 rlcUtlL2MeasUlInit(RlcCb *gCb)
402 gCb->u.ulCb->rlcL2Cb.rlcNumMeas=0;
403 for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
405 memset(&(gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[cntr]), 0, sizeof(RlcL2MeasEvtCb));
407 gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_UL_IP].measCb.measType = LKW_L2MEAS_UL_IP;
414 * Handler to calculate the Ul Ip throughput for a LCH
419 * @param[in] rbCb RB control block
420 * @param[in] pdu Pdu of LCH
425 Void rlcUtlCalUlIpThrPutIncTTI(RlcCb *gCb,RlcUlRbCb *rbCb,uint32_t ttiCnt)
427 volatile uint32_t startTime = 0;
430 SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
432 DU_LOG("\nDEBUG --> RLC_UL : Log for ul ip throughput:"
433 "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d",
434 rbCb->rbL2Cb.measOn,ttiCnt,
438 DU_LOG("\nDEBUG --> RLC_UL : Log for ul ip throughput:"
439 "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d",
440 rbCb->rbL2Cb.measOn,ttiCnt,
445 /*Check if UL IP throughput measurement is ON for this RB or not*/
446 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))
448 if (TRUE == rbCb->ueCb->isUlBurstActive)
450 if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
452 /*Removed Error Print*/
454 if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
456 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.timeSummation +=
457 (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
461 rbCb->ueCb->firstPacketTTI = ttiCnt;
463 rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
467 rbCb->l2MeasIpThruput.prevTtiCnt = 0;
472 SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
473 } /* rlcUtlCalUlIpThrPutIncTTI */
480 * Handler to calculate the Ul Ip throughput for a LCH
485 * @param[in] rbCb RB control block
486 * @param[in] pdu Pdu of LCH
491 Void rlcUtlCalUlIpThrPut
499 MsgLen rlcSduSz = 0; /*Holds length of Rlc Sdu*/
500 volatile uint32_t startTime = 0;
503 SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
505 /*Check if UL IP throughput measurement is ON for this RB or not*/
506 if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&
507 (TRUE == rbCb->ueCb->isUlBurstActive) &&
508 (rbCb->ueCb->firstPacketTTI) &&
509 (ttiCnt != rbCb->ueCb->firstPacketTTI))
511 SFndLenMsg(pdu, &rlcSduSz);
513 rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
517 SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
518 } /* rlcUtlCalUlIpThrPut */
523 * @brief Handler for L2 Measurement timer expiry.
527 * This function is called when the l2 measurement timer expires.
528 * This function sends a consolidates the mesaurements taken during
529 * this time and sends the confirm .
531 * @param[in] measEvtCb Measurement Event Control Block.
538 S16 rlcUtlHdlL2TmrExp(RlcCb *gCb,RlcL2MeasEvtCb *measEvtCb)
541 #ifdef LTE_L2_MEAS_RLC
545 /* Clean up the RB data structures */
546 if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
547 (measEvtCb->measCb.val.nonIpThMeas.numSamples))
549 measCb = &measEvtCb->measCb;
551 for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
553 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe +=
554 rlcCb.rlcL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
555 measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
557 measEvtCb->val.nonIpThMeas.measCb.numSamples--;
558 rlcStartTmr(gCb, (PTR)measEvtCb, EVENT_RLC_L2_TMR);
563 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb);
566 } /* rlcUtlHdlL2TmrExp */
569 * @brief Handler for Sending L2 Measurement confirm.
573 * This function sends a consolidates the mesaurements taken during
574 * this time and sends the confirm .
576 * @param[in] measEvtCb Measurement Event Control Block.
583 S16 rlcUtlSndUlL2MeasCfm(RlcCb *gCb,RlcL2MeasEvtCb *measEvtCb)
587 RlcL2MeasCfmEvt measCfmEvt;
591 /* Discard new changes starts */
594 /* Discard new changes ends */
596 /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
598 DU_LOG("\nDEBUG --> RLC_UL : rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
600 DU_LOG("\nDEBUG --> RLC_UL : rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
603 /* Clean up the RB data structures */
604 measCb = &measEvtCb->measCb;
606 memset(&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
607 measCfmEvt.transId = measEvtCb->transId;
609 measCfmEvt.measType = measCb->measType;
610 measCfmEvt.status.status = LCM_PRIM_OK;
611 measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
613 if( measCb->measType & LKW_L2MEAS_UL_IP)
615 RlcL2MeasCbUeMeasInfo *pUeInfoLstCb = measCb->val.ipThMeas.ueInfoLst;
616 RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
617 for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)
619 pUeInfoLstCfm[cfmIdx].numCfm = 0;
620 if (pUeInfoLstCb[cntr].isValid == TRUE)
622 pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
623 pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
625 for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
627 qci = pUeInfoLstCb[cntr].qci[qciIdx];
628 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
630 if(measCb->measType & LKW_L2MEAS_UL_IP)
632 ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
633 ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
636 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
640 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
642 /* Converting it to kbps */
643 pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
646 /* Reset the values after reporting to Application */
647 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
648 pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
650 pUeInfoLstCfm[cfmIdx].numCfm++;
655 measCfmEvt.val.ipThMeas.numUes = cfmIdx;
657 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
659 } /* rlcUtlSndUlL2MeasCfm */
662 * @brief Handler for Sending Negative confirm .
666 * This function is called when the l2 measurement cannot be started
667 * This function sends negative confirm for all the requests
669 * @param[in] gCb - RLC instance control block
670 * @param[in] measReqEvt Measurement Req Structure
671 * @param[in] measCfmEvt Confirmation to be sent to layer manager
678 S16 rlcUtlSndUlL2MeasNCfm(RlcCb *gCb,RlcL2MeasReqEvt *measReqEvt,RlcL2MeasCfmEvt *measCfmEvt)
681 RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
683 } /* kwUtlSndL2MeasNCfm */
685 #ifdef LTE_L2_MEAS_RLC
687 * @brief Validates the measurement request parameters.
691 * Function :rlcUtlValidateL2Meas
693 * @param[in] measReqEvt L2 measurement request received from layer manager.
694 * @param[out] measCfmEvt L2 measurement confirm to be prepared.
695 * @param[out] lChId List of LCh for the given Ue corresponding to QCIs
696 given in measurement request.
697 * @param[out] numLCh Number of LCh in array lChId.
700 S16 rlcUtlValidateL2Meas
702 RlcL2MeasReqEvt *measReqEvt,
703 RlcL2MeasCfmEvt *measCfmEvt,
719 uint8_t lsbNibble = 0;
720 uint8_t msbNibble = 0;
721 uint8_t numFaild = 0;
726 measType = measReqEvt->measReq.measType;
727 /* Check for the range of measType */
728 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
729 if((measType == 0x00) ||
732 measCfmEvt->transId = measReqEvt->transId;
733 measCfmEvt->measType = measType;
734 measCfmEvt->status.status = LCM_PRIM_NOK;
735 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
738 /*User can either request for Active UE,*
739 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
740 lsbNibble = measType & 0x0F;
741 msbNibble = measType & 0xF0;
743 if( (lsbNibble != 0) && (msbNibble != 0) )
745 measCfmEvt->transId = measReqEvt->transId;
746 measCfmEvt->measType = measType;
747 measCfmEvt->status.status = LCM_PRIM_NOK;
748 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
752 /* Check for total maximum number of Measurement Control Block */
753 if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
755 measCfmEvt->transId = measReqEvt->transId;
756 measCfmEvt->measType = measType;
757 measCfmEvt->status.status = LCM_PRIM_NOK;
758 measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
762 /* Check that number of samples should be a non-zero value */
763 if(((measType & LKW_L2MEAS_ACT_UE) &&
764 (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
766 measCfmEvt->transId = measReqEvt->transId;
767 measCfmEvt->measType = measType;
768 measCfmEvt->status.status = LCM_PRIM_NOK;
769 measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
772 /* Check that measurement period should be completely divisible *
773 * number of sample. */
774 if(((measType & LKW_L2MEAS_ACT_UE) &&
775 ((measReqEvt->measPeriod %
776 measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
778 measCfmEvt->transId = measReqEvt->transId;
779 measCfmEvt->measType = measType;
780 measCfmEvt->status.status = LCM_PRIM_NOK;
781 measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
785 numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
786 qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
788 /* Check whether qci is configured or not */
789 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
791 qci = qciVal[qciIdx];
792 ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp),
793 (uint8_t *)&qci, (uint16_t)sizeof(qci), 0, (PTR *)&rbCb);
796 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
797 measCfmEvt->val.nonIpThMeas.numCfm++;
801 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
803 measCfmEvt->status.status = LCM_PRIM_NOK;
804 measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
805 measCfmEvt->measType = measType;
806 measCfmEvt->transId = measReqEvt->transId;
810 for(qciIdx = 0; qciIdx < numQci; qciIdx++)
812 if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
814 /* measurement is already ongoing */
815 measCfmEvt->status.status = LCM_PRIM_NOK;
816 measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
817 measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
818 measCfmEvt->measType = measType;
819 measCfmEvt->val.nonIpThMeas.numCfm++;
823 if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
825 measCfmEvt->transId = measReqEvt->transId;
830 }/* rlcUtlValidateL2Meas */
833 S16 rlcUtlValidateIpThL2Meas(RlcL2MeasReqEvt *measReqEvt,RlcL2MeasCfmEvt *measCfmEvt)
836 uint8_t lsbNibble = 0;
837 uint8_t msbNibble = 0;
839 measType = measReqEvt->measReq.measType;
840 /* Check for the range of measType */
841 /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
842 if((measType == 0x00) ||
845 measCfmEvt->transId = measReqEvt->transId;
846 measCfmEvt->measType = measType;
847 measCfmEvt->status.status = LCM_PRIM_NOK;
848 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
851 /*User can either request for Active UE,*
852 *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
853 lsbNibble = measType & 0x0F;
854 msbNibble = measType & 0xF0;
856 if( (lsbNibble != 0) && (msbNibble != 0) )
858 measCfmEvt->transId = measReqEvt->transId;
859 measCfmEvt->measType = measType;
860 measCfmEvt->status.status = LCM_PRIM_NOK;
861 measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
865 }/* rlcUtlValidateL2Meas */
869 * @brief Handler for resetting the RB data structures
873 * This function resets the RB data structure after the expiry of
876 * @param[in] measCb Measurement Control Block.
882 Void rlcUtlResetUlL2MeasInRlcRb(RlcCb *gCb,RlcL2MeasCb *measCb,uint8_t measType)
887 RlcUlUeCb *ueCb = NULL;
891 if (measCb->measType & LKW_L2MEAS_UL_IP)
893 for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
895 if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
897 for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
899 if (measType & LKW_L2MEAS_UL_IP)
901 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
902 measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
906 if(ROK != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
907 measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
912 for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
914 if (ueCb->drbCb[rbIdx])
916 ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
922 } /* rlcUtlResetUlL2MeasInRlcRb */
926 * @brief Handler for storing address of MeasData in rbCb at right index
930 * This function is called when LM sends measReq message to RLC.
940 Void rlcUtlPlcMeasDatInL2Sts(RlcL2Cntr *measData,RlcL2MeasRbCb *rbL2Cb,uint8_t measType)
942 /* We should check the number of measType in the request. This can be done
943 * by looking at each bit in the measType. Also store the measData in the
944 * correct index of l2Sts in RbCb.
947 if(measType & LKW_L2MEAS_ACT_UE)
949 rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
951 if(measType & LKW_L2MEAS_UU_LOSS)
953 rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
955 if(measType & LKW_L2MEAS_DL_IP )
957 rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
959 if(measType & LKW_L2MEAS_UL_IP)
961 rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
963 if(measType & LKW_L2MEAS_DL_DISC)
965 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
967 if(measType & LKW_L2MEAS_DL_DELAY)
969 rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
971 }/* End of rlcUtlPlcMeasDatInL2Sts */
972 #endif /* LTE_L2_MEAS */
976 * @brief Store the UL buffer in hashList
981 * Use the SN % binSize as key and store the received UL buffer
982 * @param[in] recBufLst List CP array
983 * @param[in] recBuf received buffer
984 * @param[in] sn sn of the received buffer
989 void rlcUtlStoreRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcSn sn)
993 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
994 recBuf->lnk.node = (PTR)recBuf;
995 cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
998 } /* rlcUtlStoreRecBuf */
1002 * @brief Retrieve the UL buffer from the list
1007 * Use the SN % binSize as key and retrieve the UL buffer
1008 * @param[in] recBufLst List CP array
1009 * @param[in] sn sn of the received buffer
1014 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn)
1017 CmLListCp *recBufLstCp;
1018 RlcAmRecBuf *recBuf;
1019 CmLList *node = NULLP;
1021 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1023 recBufLstCp = &recBufLst[hashKey];
1024 CM_LLIST_FIRST_NODE(recBufLstCp, node);
1027 recBuf = (RlcAmRecBuf *) node->node;
1028 if(recBuf->amHdr.sn == sn)
1032 CM_LLIST_NEXT_NODE(recBufLstCp, node);
1035 } /* rlcUtlGetRecBuf */
1038 * @brief Delete the UL buffer from the list
1043 * Use the SN % binSize as key and retrieve the UL buffer
1044 * @param[in] recBufLst List CP array
1045 * @param[in] sn sn of the received buffer
1050 void rlcUtlDelRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcCb *gCb)
1053 CmLListCp *recBufLstCp;
1055 hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE );
1057 recBufLstCp = &recBufLst[hashKey];
1058 cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1059 RLC_FREE(gCb, recBuf, sizeof(RlcAmRecBuf));
1062 } /* rlcUtlDelRecBuf */
1066 * @brief Store the UL buffer in hashList
1070 * Use the SN % binSize as key and store the received UL buffer
1071 * @param[in] recBufLst List CP array
1072 * @param[in] recBuf received buffer
1073 * @param[in] sn sn of the received buffer
1077 void rlcUtlStoreUmRecBuf(CmLListCp *recBufLst, RlcUmRecBuf *recBuf, RlcSn sn)
1081 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1082 recBuf->lnk.node = (PTR)recBuf;
1083 cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1086 } /* rlcUtlStoreUmRecBuf */
1090 * @brief Retrieve the UL buffer from the list
1094 * Use the SN % binSize as key and retrieve the UL buffer
1095 * @param[in] recBufLst List CP array
1096 * @param[in] sn sn of the received buffer
1100 RlcUmRecBuf* rlcUtlGetUmRecBuf(CmLListCp *recBufLst, RlcSn sn)
1103 CmLListCp *recBufLstCp;
1104 RlcUmRecBuf *recBuf;
1105 CmLList *node = NULLP;
1107 hashKey = (sn % RLC_RCV_BUF_BIN_SIZE );
1109 recBufLstCp = &recBufLst[hashKey];
1110 CM_LLIST_FIRST_NODE(recBufLstCp, node);
1113 recBuf = (RlcUmRecBuf *) node->node;
1114 if(recBuf->umHdr.sn == sn)
1118 CM_LLIST_NEXT_NODE(recBufLstCp, node);
1121 } /* rlcUtlGetUmRecBuf */
1125 * @brief Delete the UM Mode UL buffer from the list
1129 * Use the SN % binSize as key and retrieve the UL buffer
1131 * @param[in] *recBufLst List CP array
1132 * @param[in] *recBuf Received buffer
1136 void rlcUtlDelUmRecBuf(RlcCb *gCb, CmLListCp *recBufLst, RlcUmRecBuf *recBuf)
1139 CmLListCp *recBufLstCp;
1141 hashKey = (recBuf->sn % RLC_RCV_BUF_BIN_SIZE );
1142 recBufLstCp = &recBufLst[hashKey];
1143 cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1144 RLC_FREE(gCb, recBuf, sizeof(RlcUmRecBuf));
1147 } /* rlcUtlDelUmRecBuf */
1149 /********************************************************************30**
1151 **********************************************************************/