b8a56f479c9a6152dfdb1a5e6b5764abea5a1c3a
[o-du/l2.git] / src / 5gnrrlc / kw_utl_ul.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
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                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
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 *******************************************************************************/
18
19 /**********************************************************************
20
21      Name:     LTE-RLC Layer 
22   
23      Type:     C file
24   
25      Desc:     Source code for RLC Utility Module
26                This file contains following functions
27
28                   --rlcUtlSendToMac
29                   --rlcUtlRcvFrmMac
30                   --rlcUtlEmptySduQ
31                   --rlcUtlSendUlDataToDu 
32                   --kwUtlShutDown
33
34      File:     kw_utl_ul.c
35
36 **********************************************************************/
37 static const char* RLOG_MODULE_NAME="UTL";
38 static int RLOG_MODULE_ID=2048;
39 static int RLOG_FILE_ID=210;
40
41 /** @file kw_utl_ul.c
42 @brief RLC Utility Module 
43 */
44
45 /* header (.h) include files */
46 #include "common_def.h"
47 /* kw005.201 added support for L2 Measurement */
48 #ifdef LTE_L2_MEAS
49 #include <sys/time.h>
50 #endif
51
52 #include "ckw.h"           /* CKW defines */
53 #include "kwu.h"           /* KWU defines */
54 #include "lkw.h"           /* LKW defines */
55 #include "rgu.h"           /* RGU defines */
56
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 */
61
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 */
67
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"
73
74 #ifdef SS_RBUF
75 S16 SMrkUlPkt(Buffer *mbuf);
76 #endif
77 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn);
78 #define RLC_MODULE (RLC_DBGMASK_DUT | RLC_DBGMASK_UL) /* for debugging purpose */
79
80
81 /**
82  *
83  * @brief 
84  *        Handler for receiving data for multiple logical channels from MAC.
85  *
86  * @details
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.  
90  *
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  
94  *
95  * @return  S16
96  *      -# ROK 
97  *      -# RFAILED
98  *
99  */
100 uint8_t rlcUtlRcvFrmMac(RlcCb *gCb, KwDatIndInfo  *datIndInfo)
101 {
102    uint32_t    count;      /* Loop Counter */
103    KwPduInfo   *pduInfo;   /* PDU Information */
104    RlcUlRbCb    *rbCb;      /* RB Control Block */
105    RlcUlUeCb    *ueCb;      /* UE Control Block */
106
107    ueCb = NULLP;
108    
109    /* fetch UeCb  */
110    if( ROK != rlcDbmFetchUlUeCb(gCb,datIndInfo->rnti,datIndInfo->cellId,&(ueCb)))
111    {
112       /* Fetch UeCb failed */
113       DU_LOG("\nRLC : rlcUtlRcvFrmMac : UEID:%d UeCb not found",
114                datIndInfo->rnti);
115       /* free the buffers inside the datIndInfo */
116       uint32_t i,j;
117       for(i = 0; i< datIndInfo->numLch; i++)
118       {
119          for(j = 0; j < datIndInfo->lchData[i].pdu.numPdu; j++)
120          {
121             if(datIndInfo->lchData[i].pdu.mBuf[j])
122             {
123                ODU_PUT_MSG_BUF(datIndInfo->lchData[i].pdu.mBuf[j]);
124             }
125          }
126       }
127       
128       return RFAILED;
129    }
130
131 #ifdef LTE_L2_MEAS
132
133    if (RGU_L2M_UL_BURST_START == datIndInfo->burstInd)
134    {
135       ueCb->isUlBurstActive = TRUE;
136    }
137    else
138    {
139       ueCb->firstPacketTTI = 0;
140       ueCb->isUlBurstActive = FALSE;
141    }
142 #endif
143    for ( count = 0;count < datIndInfo->numLch; count++ )
144    {
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
150        */
151       if(rbCb == NULLP)
152       {
153          uint32_t j;
154          for(j = 0; j < pduInfo->numPdu; j++)
155          {
156             if(pduInfo->mBuf[j])
157             {
158                ODU_PUT_MSG_BUF(pduInfo->mBuf[j]);
159             }
160          }
161          continue;
162       }
163
164 #ifdef SS_RBUF
165       SMrkUlPkt(pduInfo->mBuf[0]);
166 #endif
167       if ( rbCb->mode == CM_LTE_MODE_UM )
168       {
169 /* kw005.201 added support for L2 Measurement */
170 #ifdef LTE_L2_MEAS
171          rlcUmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
172 #else
173          rlcUmmProcessPdus(gCb,rbCb,pduInfo);
174 #endif
175       }
176       else if (rbCb->mode == CM_LTE_MODE_AM )
177       {
178 /* kw005.201 added support for L2 Measurement */
179 #ifdef LTE_L2_MEAS
180          rlcAmmProcessPdus(gCb,rbCb,  pduInfo, datIndInfo->ttiCnt);
181 #else
182          rlcAmmProcessPdus(gCb,rbCb,pduInfo);
183 #endif
184       }
185    }
186    return ROK;
187 }
188
189 /**
190  *
191  * @brief 
192  *    Handler for sending Data Indication to the upper layer. 
193  * 
194  * @Details
195  *    This function is used to send re-assembled SDU to the upper layer.
196  *
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 
200  *
201  * @return  S16
202  *      -# ROK 
203  */
204 uint8_t rlcUtlSendUlDataToDu(RlcCb *gCb, RlcUlRbCb *rbCb, Buffer *sdu)
205 {
206 #ifndef KW_PDCP
207    KwuDatIndInfo   *datIndInfo;   /* Data Indication Information */
208    KwuDatIndInfo datIndInfoTmp;
209 #endif
210    RlcUlRrcMsgInfo *ulRrcMsgInfo;
211    uint16_t        msgLen, copyLen;
212    Pst             pst;
213
214 #ifndef KW_PDCP
215    /* Creating static memory for KwuDatIndInfo. #else will be 
216     * removed once the testing is done on all platforms */
217    datIndInfo = &datIndInfoTmp;
218
219 #if (ERRCLASS & ERRCLS_ADD_RES )
220    if ( datIndInfo == NULLP  )
221    {
222       DU_LOG("\nRLC : rlcUtlSendUlDataToDu: Memory allocation failed UEID:%d \
223          CELLID:%d", rbCb->rlcId.ueId, rbCb->rlcId.cellId);
224       ODU_PUT_MSG_BUF(sdu);
225       return RFAILED;
226    }
227 #endif /* ERRCLASS & ERRCLS_ADD_RES */
228
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; 
233 #endif /* KW_PDCP */
234    
235    /* Filling UL RRC Message Info */
236    RLC_ALLOC_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL,
237       ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
238    if (ulRrcMsgInfo)
239    {
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)
246        {
247           ODU_GET_MSG_LEN(sdu, (MsgLen *)&msgLen);
248           ODU_COPY_MSG_TO_FIX_BUF(sdu, 0, msgLen, ulRrcMsgInfo->rrcMsg, (MsgLen *)&copyLen);
249           ulRrcMsgInfo->msgLen = msgLen;
250
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);
255        }
256        else
257        {
258           DU_LOG("\nRLC : rlcUtlSendUlDataToDu: Memory allocation failed for rrcMsg");
259           RLC_FREE_SHRABL_BUF(RLC_MEM_REGION_UL, RLC_POOL, ulRrcMsgInfo, sizeof(RlcUlRrcMsgInfo));
260           return RFAILED;
261        }
262     }
263     else
264     {
265        DU_LOG("\nRLC : rlcUtlSendUlDataToDu: Memory allocation failed for ulRrcMsgInfo");
266        return RFAILED;
267     }
268
269    return ROK;
270 } /* rlcUtlSendUlDataToDu */
271
272
273 static Void dumpRLCUlRbInformation(RlcUlRbCb* ulRbCb)
274 {
275    if(ulRbCb->mode == CM_LTE_MODE_UM)
276    {
277       uint32_t i;
278       uint32_t pdusInReceptionBuffer = 0;
279       uint32_t windSz  = ulRbCb->m.umUl.umWinSz << 1;
280
281       for(i = 0; i< windSz; i++)
282       {
283          if(ulRbCb->m.umUl.recBuf[i] != NULLP)
284          {
285             pdusInReceptionBuffer++;
286          }
287       }
288       
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);
294    }
295    else if(ulRbCb->mode == CM_LTE_MODE_AM)
296    {
297       uint32_t i;
298       uint32_t pdusInReceptionBuffer = 0;
299       uint32_t totalSegs = 0;
300       uint32_t windSz  = RLC_AM_GET_WIN_SZ(ulRbCb->m.amUl.snLen) << 1;
301       
302       for(i = 0; i< windSz; i++)
303       {
304          RlcAmRecBuf *recBuf = rlcUtlGetRecBuf(ulRbCb->m.amUl.recBufLst, i);
305          if(recBuf != NULLP)
306          {
307             pdusInReceptionBuffer++;
308             totalSegs += (recBuf->segLst.count);
309          }
310       }
311
312       RLOG_ARG4(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
313                 "AM UL UEID:%d CELLID:%d Reception Buf size = %d"
314                 "total segs = %d", 
315                        (int)ulRbCb->rlcId.ueId,
316                        (int)ulRbCb->rlcId.cellId,
317                        (int)pdusInReceptionBuffer, 
318                        (int)totalSegs);
319    }
320 }
321
322 Void DumpRLCUlDebugInformation(Void)
323 {
324    RlcCb* ulInst = rlcCb[0]; /* TODO : Check whether UL is 0 or 1 */
325    RlcUlCb* ulCb = ulInst->u.ulCb;
326    RlcUlUeCb *ueCb = NULLP; 
327
328    /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
329    while (ROK == cmHashListGetNext(&ulCb->ueLstCp, 
330                                    (PTR) ueCb, 
331                                    (PTR *)&ueCb))
332    {
333       uint32_t i;
334       for(i = 0; i< RLC_MAX_SRB_PER_UE; i++)
335       {
336          RlcUlRbCb* ulRbCb = ueCb->srbCb[i]; 
337          if(ulRbCb != NULLP)
338          {
339             dumpRLCUlRbInformation(ulRbCb);
340          }
341       }
342       for(i = 0; i< RLC_MAX_DRB_PER_UE; i++)
343       {
344          RlcUlRbCb* ulRbCb = ueCb->drbCb[i]; 
345          if(ulRbCb != NULLP)
346          {
347             dumpRLCUlRbInformation(ulRbCb);
348          }
349       }
350    }
351 }
352
353
354 /*
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
359  */
360
361
362
363 /* kw005.201 added support for L2 Measurement */
364 #ifdef LTE_L2_MEAS
365
366 /**
367  *
368  * @brief 
369  *    Handler for initialisation of measurement 
370  * 
371  * @param[in]  gCb    - RLC instance Control Block 
372  *
373  * @return  S16
374  *      -# ROK 
375  */
376 S16 rlcUtlL2MeasUlInit(RlcCb *gCb)
377 {
378    uint16_t             cntr;
379
380    gCb->u.ulCb->rlcL2Cb.rlcNumMeas=0;
381    for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
382    {
383       memset(&(gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[cntr]), 0, sizeof(RlcL2MeasEvtCb));
384    }
385    gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_UL_IP].measCb.measType = LKW_L2MEAS_UL_IP;
386    return ROK;
387 }
388 /**
389  *
390  * @brief
391  *
392  *        Handler to calculate the Ul Ip throughput for a LCH
393  *
394  * @b Description:
395  *
396  *
397  * @param[in] rbCb         RB control block
398  * @param[in] pdu          Pdu of LCH
399  *
400  *  @return  Void
401  *
402  */
403 Void rlcUtlCalUlIpThrPutIncTTI(RlcCb *gCb,RlcUlRbCb *rbCb,uint32_t ttiCnt)
404 {
405    volatile uint32_t     startTime = 0;
406
407       /*starting Task*/
408       SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
409 #ifndef ALIGN_64BIT
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,
413          rbCb->rlcId.ueId,
414          rbCb->rlcId.cellId);
415 #else
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,
419          rbCb->rlcId.ueId,
420          rbCb->rlcId.cellId);
421 #endif
422
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))              
425    {
426       if (TRUE  == rbCb->ueCb->isUlBurstActive)
427       {
428          if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
429          {
430             /*Removed Error Print*/
431          }
432          if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
433          {
434             rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.timeSummation += 
435                (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
436          }
437          else
438          {
439             rbCb->ueCb->firstPacketTTI = ttiCnt;
440          }
441          rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
442       }
443       else
444       {
445          rbCb->l2MeasIpThruput.prevTtiCnt = 0;
446       }
447    }   
448
449    /*stopping Task*/
450    SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
451 } /* rlcUtlCalUlIpThrPutIncTTI */
452
453
454 /**
455  *
456  * @brief
457  *
458  *        Handler to calculate the Ul Ip throughput for a LCH
459  *
460  * @b Description:
461  *
462  *
463  * @param[in] rbCb         RB control block
464  * @param[in] pdu          Pdu of LCH
465  *
466  *  @return  Void
467  *
468  */
469 Void rlcUtlCalUlIpThrPut
470 (
471 RlcCb        *gCb,
472 RlcUlRbCb    *rbCb,
473 Buffer       *pdu,
474 uint32_t     ttiCnt
475 )
476 {
477    MsgLen        rlcSduSz = 0;  /*Holds length of Rlc Sdu*/
478    volatile uint32_t     startTime = 0;
479
480    /*starting Task*/
481    SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
482
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))
488    {
489       SFndLenMsg(pdu, &rlcSduSz);
490
491       rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
492
493    }
494    /*stopping Task*/
495    SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
496 } /* rlcUtlCalUlIpThrPut */
497
498 \f
499 /**
500  *
501  * @brief Handler for L2 Measurement timer expiry.
502  *
503  *
504  * @b Description
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 .
508  *
509  *  @param[in] measEvtCb    Measurement Event Control Block.
510  *
511  *
512  *  @return  S16
513  *      -# ROK
514  */
515
516 S16 rlcUtlHdlL2TmrExp(RlcCb *gCb,RlcL2MeasEvtCb *measEvtCb)
517 {
518
519 #ifdef LTE_L2_MEAS_RLC
520    uint16_t             qciIdx;
521    RlcL2MeasCb     *measCb;
522    
523    /* Clean up the RB data structures */
524    if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
525       (measEvtCb->measCb.val.nonIpThMeas.numSamples))
526    {
527       measCb = &measEvtCb->measCb;
528
529       for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
530       {
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++;
534       }
535       measEvtCb->val.nonIpThMeas.measCb.numSamples--;
536       rlcStartTmr(gCb, (PTR)measEvtCb, RLC_EVT_L2_TMR); 
537       return (ROK);
538    }
539 #endif
540
541    rlcUtlSndUlL2MeasCfm(gCb, measEvtCb);
542
543    return (ROK);
544 } /* rlcUtlHdlL2TmrExp */
545 /**
546  *
547  * @brief Handler for Sending L2 Measurement confirm.
548  *
549  *
550  * @b Description
551  *        This function sends a consolidates the mesaurements taken during
552  *        this time and sends the confirm .
553  *
554  *  @param[in] measEvtCb    Measurement Event Control Block.
555  *
556  *
557  *  @return  S16
558  *      -# ROK
559  */
560
561 S16 rlcUtlSndUlL2MeasCfm(RlcCb *gCb,RlcL2MeasEvtCb  *measEvtCb)
562 {
563    uint32_t            qciIdx;
564    RlcL2MeasCb         *measCb;
565    RlcL2MeasCfmEvt     measCfmEvt;
566    uint64_t            ulDataVol;
567    uint64_t            ulTime;
568    uint16_t            cntr;
569    /* Discard new changes starts */
570    uint8_t             qci = 0;
571    uint32_t            cfmIdx =0;
572    /* Discard new changes ends */
573
574    /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
575 #ifndef ALIGN_64BIT
576    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
577 #else
578    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
579 #endif
580
581    /* Clean up the RB data structures */
582    measCb = &measEvtCb->measCb;
583    
584    memset(&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
585    measCfmEvt.transId = measEvtCb->transId;
586
587    measCfmEvt.measType = measCb->measType;
588    measCfmEvt.status.status = LCM_PRIM_OK;
589    measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
590    
591    if( measCb->measType & LKW_L2MEAS_UL_IP)
592    {
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++)        
596       {
597          pUeInfoLstCfm[cfmIdx].numCfm = 0;
598          if (pUeInfoLstCb[cntr].isValid == TRUE)
599          {
600             pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
601             pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
602
603             for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
604             {
605                qci = pUeInfoLstCb[cntr].qci[qciIdx];
606                pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
607
608                if(measCb->measType & LKW_L2MEAS_UL_IP)
609                {
610                   ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
611                   ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
612                   if(0 == ulTime)
613                   {
614                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
615                   }
616                   else
617                   {
618                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
619
620                      /* Converting it to kbps */
621                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
622
623                   }
624                   /* Reset the values after reporting to Application */
625                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
626                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
627                }
628                pUeInfoLstCfm[cfmIdx].numCfm++;
629             }
630             cfmIdx++;
631          }
632       }
633       measCfmEvt.val.ipThMeas.numUes = cfmIdx; 
634    }
635    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
636    return (ROK);
637 } /* rlcUtlSndUlL2MeasCfm */
638 /**
639  *
640  * @brief Handler for Sending Negative confirm .
641  *
642  *
643   @b Description
644  *        This function is called when the l2 measurement cannot be started
645  *        This function sends  negative confirm for all the requests
646  *
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
650  *
651  *
652  *  @return  S16
653  *      -# ROK
654  */
655
656 S16 rlcUtlSndUlL2MeasNCfm(RlcCb *gCb,RlcL2MeasReqEvt *measReqEvt,RlcL2MeasCfmEvt *measCfmEvt)
657 {
658
659    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
660    return ROK;
661 } /* kwUtlSndL2MeasNCfm */
662
663 #ifdef LTE_L2_MEAS_RLC
664 /**
665  * @brief  Validates the measurement request parameters. 
666  *
667  * @details
668  *
669  *     Function :rlcUtlValidateL2Meas 
670  *
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.
676  **/
677
678 S16 rlcUtlValidateL2Meas
679 (
680 RlcL2MeasReqEvt *measReqEvt,
681 RlcL2MeasCfmEvt *measCfmEvt,
682 CmLteLcId       *lChId,
683 uint8_t         *numLCh
684 )
685 {
686    uint8_t    measType;
687    S16        ret;
688    uint8_t    qciIdx;
689    uint8_t    qci;
690    uint8_t    idx;
691    uint8_t    *qciVal;
692    uint8_t    numQci;
693    RlcUlRbCb  *rbCb;
694    RlcUlUeCb  *ueCb;
695    RbCb       **rbCbLst;
696    uint8_t    rbIdx;
697    uint8_t    lsbNibble = 0;
698    uint8_t    msbNibble = 0;
699    uint8_t    numFaild = 0;
700
701    idx = 0;
702    rbCb = NULLP;
703    ret = ROK;
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) ||
708        measType > 0x30)
709    {
710       measCfmEvt->transId = measReqEvt->transId;
711       measCfmEvt->measType = measType;
712       measCfmEvt->status.status = LCM_PRIM_NOK;
713       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
714       return RFAILED;
715    }
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;
720
721    if( (lsbNibble != 0) && (msbNibble != 0) )
722    {
723       measCfmEvt->transId = measReqEvt->transId;
724       measCfmEvt->measType = measType;
725       measCfmEvt->status.status = LCM_PRIM_NOK;
726       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
727       return RFAILED;
728    }
729
730    /* Check for total maximum number of Measurement Control Block */
731    if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
732    {
733       measCfmEvt->transId = measReqEvt->transId;
734       measCfmEvt->measType = measType;
735       measCfmEvt->status.status = LCM_PRIM_NOK;
736       measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
737       return RFAILED;
738    }
739
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)))
743    {
744       measCfmEvt->transId = measReqEvt->transId;
745       measCfmEvt->measType = measType;
746       measCfmEvt->status.status = LCM_PRIM_NOK;
747       measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
748       return RFAILED;
749    }
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)))
755    {
756       measCfmEvt->transId = measReqEvt->transId;
757       measCfmEvt->measType = measType;
758       measCfmEvt->status.status = LCM_PRIM_NOK;
759       measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
760       return RFAILED;
761    }
762    {
763       numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
764       qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
765    }
766    /* Check whether qci is configured or not */
767    for(qciIdx = 0; qciIdx < numQci; qciIdx++)
768    {
769       qci = qciVal[qciIdx];
770       ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp), 
771             (uint8_t *)&qci, (uint16_t)sizeof(qci), 0, (PTR *)&rbCb);
772       if(ret != ROK)
773       {
774          measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
775          measCfmEvt->val.nonIpThMeas.numCfm++;
776
777       }
778    }
779    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
780    {
781       measCfmEvt->status.status = LCM_PRIM_NOK;
782       measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
783       measCfmEvt->measType = measType;
784       measCfmEvt->transId = measReqEvt->transId;
785       return RFAILED;
786    }
787    {
788       for(qciIdx = 0; qciIdx < numQci; qciIdx++)
789       {
790          if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
791          {
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++;
798          }
799       }
800    }
801    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
802    {
803       measCfmEvt->transId = measReqEvt->transId;
804       return RFAILED;
805    }
806
807    return (ROK);
808 }/* rlcUtlValidateL2Meas */
809 #endif
810
811 S16 rlcUtlValidateIpThL2Meas(RlcL2MeasReqEvt *measReqEvt,RlcL2MeasCfmEvt *measCfmEvt)
812 {
813    uint8_t      measType;
814    uint8_t         lsbNibble = 0;
815    uint8_t         msbNibble = 0;
816
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) ||
821        measType > 0x30)
822    {
823       measCfmEvt->transId = measReqEvt->transId;
824       measCfmEvt->measType = measType;
825       measCfmEvt->status.status = LCM_PRIM_NOK;
826       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
827       return RFAILED;
828    }
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;
833
834    if( (lsbNibble != 0) && (msbNibble != 0) )
835    {
836       measCfmEvt->transId = measReqEvt->transId;
837       measCfmEvt->measType = measType;
838       measCfmEvt->status.status = LCM_PRIM_NOK;
839       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
840       return RFAILED;
841    }
842    return (ROK);
843 }/* rlcUtlValidateL2Meas */
844
845 /**
846  *
847  * @brief Handler for resetting the RB data structures
848  *
849  *
850  * @b Description
851  *        This function resets the RB data structure after the expiry of 
852  *        measurement timer.
853  *
854  *  @param[in] measCb    Measurement Control Block.
855  *
856  *
857  *  @return  Void
858  */
859
860 Void rlcUtlResetUlL2MeasInRlcRb(RlcCb *gCb,RlcL2MeasCb *measCb,uint8_t measType)
861 {
862    uint32_t           rbIdx;
863    uint32_t           ueIdx;
864    uint32_t           qciIdx;
865    RlcUlUeCb         *ueCb = NULL;
866
867
868
869    if (measCb->measType & LKW_L2MEAS_UL_IP)
870    {
871       for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
872       {           
873          if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
874          {
875             for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
876             {
877                if (measType & LKW_L2MEAS_UL_IP)
878                {
879                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
880                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
881                }
882             }
883
884             if(ROK  != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
885                      measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
886             {
887                continue;
888             }
889
890             for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
891             {
892                if (ueCb->drbCb[rbIdx])
893                {
894                   ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
895                }
896             }
897          }
898       }
899    }
900 } /* rlcUtlResetUlL2MeasInRlcRb */
901
902 /**
903  *
904  * @brief Handler for storing address of MeasData in rbCb at right index
905  *
906  *
907  * @b Description
908  *        This function is called when LM sends measReq message to RLC.
909  *
910  *  @param[in] 
911  *  @param[out] 
912  *  @param[in] 
913  *
914  *
915  *  @return  S16
916  *      -# ROK
917  */
918 Void rlcUtlPlcMeasDatInL2Sts(RlcL2Cntr *measData,RlcL2MeasRbCb *rbL2Cb,uint8_t measType)
919 {
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.
923     * */
924
925     if(measType & LKW_L2MEAS_ACT_UE)
926     {
927          rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
928     }
929     if(measType & LKW_L2MEAS_UU_LOSS)
930     {
931          rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
932     }
933     if(measType & LKW_L2MEAS_DL_IP )
934     {
935          rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
936     }
937     if(measType & LKW_L2MEAS_UL_IP)
938     {
939          rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
940     }
941     if(measType & LKW_L2MEAS_DL_DISC)
942     {
943          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
944     }
945     if(measType & LKW_L2MEAS_DL_DELAY)
946     {
947          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
948     }
949 }/* End of rlcUtlPlcMeasDatInL2Sts */
950 #endif /* LTE_L2_MEAS */
951
952 /**
953  *
954  * @brief Store the UL buffer in hashList  
955  *
956  *
957  * @b Description
958  *
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 
963  *
964  *
965  *  @return  Void
966  */
967 void rlcUtlStoreRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcSn sn)
968 {
969    uint32_t    hashKey; 
970    
971    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
972    recBuf->lnk.node = (PTR)recBuf;
973    cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
974
975    return;
976 } /* rlcUtlStoreRecBuf */
977
978 /**
979  *
980  * @brief Retrieve the UL buffer from the list
981  *
982  *
983  * @Description
984  *
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 
988  *
989  *
990  *  @return  Void
991  */
992 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn)
993 {
994    uint32_t            hashKey; 
995    CmLListCp           *recBufLstCp;
996    RlcAmRecBuf         *recBuf;
997    CmLList             *node = NULLP;
998
999    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1000  
1001    recBufLstCp = &recBufLst[hashKey];
1002    CM_LLIST_FIRST_NODE(recBufLstCp, node);
1003    while(node)
1004    {
1005       recBuf = (RlcAmRecBuf *) node->node;
1006       if(recBuf->amHdr.sn == sn)
1007       {
1008          return recBuf;
1009       }
1010       CM_LLIST_NEXT_NODE(recBufLstCp, node);
1011    }
1012    return NULLP;
1013 } /* rlcUtlGetRecBuf */
1014 /**
1015  *
1016  * @brief Delete the UL buffer from the list
1017  *
1018  *
1019  * @Description
1020  *
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 
1024  *
1025  *
1026  *  @return  Void
1027  */
1028 void rlcUtlDelRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcCb *gCb)
1029 {
1030    uint32_t            hashKey; 
1031    CmLListCp           *recBufLstCp;
1032
1033    hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE ); 
1034  
1035    recBufLstCp = &recBufLst[hashKey];
1036    cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1037    RLC_FREE(gCb, recBuf, sizeof(RlcAmRecBuf));
1038
1039    return;
1040 } /* rlcUtlDelRecBuf */
1041
1042 #ifdef NR_RLC_UL
1043 /**
1044  *
1045  * @brief Store the UL buffer in hashList  
1046  *
1047  *
1048  * @b Description
1049  *
1050  *   Use the SN % binSize as key and store the received UL buffer
1051  *  @param[in] recBufLst       List CP array
1052  *  @param[in] recBuf          received buffer
1053  *  @param[in] sn              sn of the received buffer 
1054  *
1055  *
1056  *  @return  Void
1057  */
1058 void rlcUtlStoreUmRecBuf(CmLListCp *recBufLst, RlcUmRecBuf *recBuf, RlcSn sn)
1059 {
1060    uint32_t    hashKey; 
1061    
1062    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1063    recBuf->lnk.node = (PTR)recBuf;
1064    cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1065
1066    return;
1067 } /* rlcUtlStoreUmRecBuf */
1068 /**
1069  *
1070  * @brief Retrieve the UL buffer from the list
1071  *
1072  *
1073  * @Description
1074  *
1075  *   Use the SN % binSize as key and retrieve the UL buffer
1076  *  @param[in] recBufLst       List CP array
1077  *  @param[in] sn              sn of the received buffer 
1078  *
1079  *
1080  *  @return  Void
1081  */
1082 RlcUmRecBuf* rlcUtlGetUmRecBuf(CmLListCp *recBufLst, RlcSn sn)
1083 {
1084    uint32_t            hashKey; 
1085    CmLListCp           *recBufLstCp;
1086    RlcUmRecBuf         *recBuf;
1087    CmLList             *node = NULLP;
1088
1089    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1090  
1091    recBufLstCp = &recBufLst[hashKey];
1092    CM_LLIST_FIRST_NODE(recBufLstCp, node);
1093    while(node)
1094    {
1095       recBuf = (RlcUmRecBuf *) node->node;
1096       if(recBuf->umHdr.sn == sn)
1097       {
1098          return recBuf;
1099       }
1100       CM_LLIST_NEXT_NODE(recBufLstCp, node);
1101    }
1102    return NULLP;
1103 } /* rlcUtlGetUmRecBuf */
1104 #endif
1105
1106
1107 /********************************************************************30**
1108          End of file
1109 **********************************************************************/