1b70dcec66256d890fa5bfb2b204a88549cf0c28
[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                   --rlcUtlSndToLi
29                   --rlcUtlRcvFrmLi
30                   --rlcUtlEmptySduQ
31                   --rlcUtlSndDatInd 
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 "ss_rbuf.h"
71 #include "ss_rbuf.x"
72 #ifdef SS_RBUF
73 S16 SMrkUlPkt(Buffer *mbuf);
74 #endif
75 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn);
76 #define RLC_MODULE (RLC_DBGMASK_DUT | RLC_DBGMASK_UL) /* for debugging purpose */
77
78
79 /**
80  *
81  * @brief 
82  *        Handler for receiving data for multiple logical channels from MAC.
83  *
84  * @details
85  *        This function receives the data sent by MAC for one or more 
86  *        logical channels.It calls the UMM or AMM functions to process
87  *        the PDUs and send them to the uppper layer.  
88  *
89  * @param[in] gCb          - RLC instance control block 
90  * @param[in] datIndInfo   - Data Indication Information containing the PDU(s)
91  *                            for one or more logical channels  
92  *
93  * @return  S16
94  *      -# ROK 
95  *      -# RFAILED
96  *
97  */
98 #ifdef ANSI
99 S16 rlcUtlRcvFrmLi
100 (
101 RlcCb           *gCb,                              
102 KwDatIndInfo   *datIndInfo                       
103 )
104 #else
105 S16 rlcUtlRcvFrmLi(gCb,datIndInfo)  
106 RlcCb           *gCb;                     
107 KwDatIndInfo   *datIndInfo;             
108 #endif
109 {
110    U32         count;      /* Loop Counter */
111    KwPduInfo   *pduInfo;   /* PDU Information */
112    RlcUlRbCb    *rbCb;      /* RB Control Block */
113    RlcUlUeCb    *ueCb;      /* UE Control Block */
114 /* kw005.201 added support for L2 Measurement */
115
116    TRC2(rlcUtlRcvFrmLi)
117
118
119    ueCb = NULLP;
120    
121    /* fetch UeCb  */
122    if( ROK != rlcDbmFetchUlUeCb(gCb,datIndInfo->rnti,datIndInfo->cellId,&(ueCb)))
123    {
124       /* Fetch UeCb failed */
125       RLOG_ARG1(L_ERROR,DBG_CELLID,datIndInfo->cellId,
126                "UEID:%d UeCb not found",
127                datIndInfo->rnti);
128       /* free the buffers inside the datIndInfo */
129       U32 i,j;
130       for(i = 0; i< datIndInfo->numLch; i++)
131       {
132          for(j = 0; j < datIndInfo->lchData[i].pdu.numPdu; j++)
133          {
134             if(datIndInfo->lchData[i].pdu.mBuf[j])
135             {
136                RLC_FREE_BUF_WC(datIndInfo->lchData[i].pdu.mBuf[j]);
137             }
138          }
139       }
140       
141       return RFAILED;
142    }
143
144 #ifdef LTE_L2_MEAS
145
146    if (RGU_L2M_UL_BURST_START == datIndInfo->burstInd)
147    {
148       ueCb->isUlBurstActive = TRUE;
149    }
150    else
151    {
152       ueCb->firstPacketTTI = 0;
153       ueCb->isUlBurstActive = FALSE;
154    }
155 #endif
156    for ( count = 0;count < datIndInfo->numLch; count++ )
157    {
158       rbCb = ueCb->lCh[datIndInfo->lchData[count].lcId - 1].ulRbCb;
159       /* kw002.201 Removed allocation of pduInfo */ 
160       pduInfo = &(datIndInfo->lchData[count].pdu);
161       /* Fix for CR ccpu00138374,sometimes rbCb is NULL in UL path,
162        * So inorder to avoid the crash, added this preventive check
163        */
164       if(rbCb == NULLP)
165       {
166          U32 j;
167          for(j = 0; j < pduInfo->numPdu; j++)
168          {
169             if(pduInfo->mBuf[j])
170             {
171                RLC_FREE_BUF_WC(pduInfo->mBuf[j]);
172             }
173          }
174          continue;
175       }
176
177 #ifdef SS_RBUF
178       SMrkUlPkt(pduInfo->mBuf[0]);
179 #endif
180       if ( rbCb->mode == CM_LTE_MODE_UM )
181       {
182 /* kw005.201 added support for L2 Measurement */
183 #ifdef LTE_L2_MEAS
184          rlcUmmProcessPdus(gCb,rbCb, pduInfo, datIndInfo->ttiCnt);
185 #else
186          rlcUmmProcessPdus(gCb,rbCb,pduInfo);
187 #endif
188       }
189       else if (rbCb->mode == CM_LTE_MODE_AM )
190       {
191 /* kw005.201 added support for L2 Measurement */
192 #ifdef LTE_L2_MEAS
193          rlcAmmProcessPdus(gCb,rbCb,  pduInfo, datIndInfo->ttiCnt);
194 #else
195          rlcAmmProcessPdus(gCb,rbCb,pduInfo);
196 #endif
197       }
198    }
199    return ROK;
200 }
201
202 /**
203  *
204  * @brief 
205  *    Handler for sending Data Indication to the upper layer. 
206  * 
207  * @Details
208  *    This function is used to send re-assembled SDU to the upper layer.
209  *
210  * @param[in]  gCb    - RLC instance Control Block 
211  * @param[in]  rbCb   - RB Control Block 
212  * @param[in]  sdu    - SDU to be sent to upper layer 
213  *
214  * @return  S16
215  *      -# ROK 
216  */
217 #ifdef ANSI
218 S16 rlcUtlSndDatInd
219 (
220 RlcCb       *gCb,
221 RlcUlRbCb   *rbCb,                   
222 Buffer     *sdu                    
223 )
224 #else
225 S16 rlcUtlSndDatInd(gCb,rbCb,sdu)
226 RlcCb       *gCb;
227 RlcUlRbCb   *rbCb;                  
228 Buffer     *sdu;                    
229 #endif
230 {
231 #ifndef KW_PDCP
232    KwuDatIndInfo   *datIndInfo;   /* Data Indication Information */
233    KwuDatIndInfo datIndInfoTmp;
234 #endif
235
236    TRC3(rlcUtlSndDatInd)
237
238
239 #ifndef KW_PDCP
240    /* Creating static memory for KwuDatIndInfo. #else will be 
241     * removed once the testing is done on all platforms */
242    datIndInfo = &datIndInfoTmp;
243
244 #if (ERRCLASS & ERRCLS_ADD_RES )
245    if ( datIndInfo == NULLP  )
246    {
247       RLOG_ARG2(L_FATAL,DBG_RBID,rbCb->rlcId.rbId,
248                "Memory allocation failed UEID:%d CELLID:%d",
249                rbCb->rlcId.ueId,
250                rbCb->rlcId.cellId);
251       RLC_FREE_BUF(sdu);
252       return RFAILED;
253    }
254 #endif /* ERRCLASS & ERRCLS_ADD_RES */
255
256    RLC_MEM_CPY(&(datIndInfo->rlcId),&(rbCb->rlcId),sizeof(CmLteRlcId));
257    /* Set the "isOutofSeq" flag for each packet 
258     * If packets are in-sequence set flag as TRUE else FALSE */
259    datIndInfo->isOutOfSeq = rbCb->m.amUl.isOutOfSeq; 
260 #endif /* KW_PDCP */
261    
262    /* If trace flag is enabled send the trace indication */
263    if(gCb->init.trc == TRUE)
264    {
265       /* Populate the trace params */
266       rlcLmmSendTrc(gCb,KWU_EVT_DAT_IND, sdu);
267    }
268 #ifndef KW_PDCP
269
270    RlcUiKwuDatInd(&gCb->genCfg.lmPst, datIndInfo, sdu);
271 #endif   
272    return (ROK);
273 } /* rlcUtlSndDatInd */
274
275
276 PRIVATE Void dumpRLCUlRbInformation(RlcUlRbCb* ulRbCb)
277 {
278    if(ulRbCb->mode == CM_LTE_MODE_UM)
279    {
280       U32 i;
281       U32 pdusInReceptionBuffer = 0;
282       U32 windSz  = ulRbCb->m.umUl.umWinSz << 1;
283
284       for(i = 0; i< windSz; i++)
285       {
286          if(ulRbCb->m.umUl.recBuf[i] != NULLP)
287          {
288             pdusInReceptionBuffer++;
289          }
290       }
291       
292       RLOG_ARG3(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
293                "UM UL UEID:%d CELLID:%d Reception Buffer size = %d", 
294                        (int)ulRbCb->rlcId.ueId,
295                        (int)ulRbCb->rlcId.cellId,
296                        (int)pdusInReceptionBuffer);
297    }
298    else if(ulRbCb->mode == CM_LTE_MODE_AM)
299    {
300       U32 i;
301       U32 pdusInReceptionBuffer = 0;
302       U32 totalSegs = 0;
303       U32 windSz  = RLC_AM_GET_WIN_SZ(ulRbCb->m.amUl.snLen) << 1;
304       
305       for(i = 0; i< windSz; i++)
306       {
307          RlcAmRecBuf *recBuf = rlcUtlGetRecBuf(ulRbCb->m.amUl.recBufLst, i);
308          if(recBuf != NULLP)
309          {
310             pdusInReceptionBuffer++;
311             totalSegs += (recBuf->segLst.count);
312          }
313       }
314
315       RLOG_ARG4(L_DEBUG,DBG_RBID,ulRbCb->rlcId.rbId,
316                 "AM UL UEID:%d CELLID:%d Reception Buf size = %d"
317                 "total segs = %d", 
318                        (int)ulRbCb->rlcId.ueId,
319                        (int)ulRbCb->rlcId.cellId,
320                        (int)pdusInReceptionBuffer, 
321                        (int)totalSegs);
322    }
323 }
324
325 Void DumpRLCUlDebugInformation(Void)
326 {
327    RlcCb* ulInst = rlcCb[0]; /* TODO : Check whether UL is 0 or 1 */
328    RlcUlCb* ulCb = ulInst->u.ulCb;
329    RlcUlUeCb *ueCb = NULLP; 
330
331    /* Until no more ueCb is ueLstCp hash list get and delete ueCb */
332    while (ROK == cmHashListGetNext(&ulCb->ueLstCp, 
333                                    (PTR) ueCb, 
334                                    (PTR *)&ueCb))
335    {
336       U32 i;
337       for(i = 0; i< RLC_MAX_SRB_PER_UE; i++)
338       {
339          RlcUlRbCb* ulRbCb = ueCb->srbCb[i]; 
340          if(ulRbCb != NULLP)
341          {
342             dumpRLCUlRbInformation(ulRbCb);
343          }
344       }
345       for(i = 0; i< RLC_MAX_DRB_PER_UE; i++)
346       {
347          RlcUlRbCb* ulRbCb = ueCb->drbCb[i]; 
348          if(ulRbCb != NULLP)
349          {
350             dumpRLCUlRbInformation(ulRbCb);
351          }
352       }
353    }
354 }
355
356
357 /*
358  * kwUtlFreeUlRbCb() function is split into two functions 
359  *  -  rlcAmmFreeUlRbCb() ---> gp_amm_ul.c 
360  *  -  rlcUmmFreeUlRbCb() ---> gp_umm_ul.c
361  * and placed in respective files mentioned above
362  */
363
364
365
366 /* kw005.201 added support for L2 Measurement */
367 #ifdef LTE_L2_MEAS
368
369 /**
370  *
371  * @brief 
372  *    Handler for initialisation of measurement 
373  * 
374  * @param[in]  gCb    - RLC instance Control Block 
375  *
376  * @return  S16
377  *      -# ROK 
378  */
379 S16 rlcUtlL2MeasUlInit(RlcCb *gCb)
380 {
381    U16             cntr;
382
383    gCb->u.ulCb->rlcL2Cb.rlcNumMeas=0;
384    for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
385    {
386       cmMemset((U8 *)&(gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[cntr]), 0, sizeof(RlcL2MeasEvtCb));
387    }
388    gCb->u.ulCb->rlcL2Cb.rlcL2EvtCb[RLC_L2MEAS_UL_IP].measCb.measType = LKW_L2MEAS_UL_IP;
389    return ROK;
390 }
391 /**
392  *
393  * @brief
394  *
395  *        Handler to calculate the Ul Ip throughput for a LCH
396  *
397  * @b Description:
398  *
399  *
400  * @param[in] rbCb         RB control block
401  * @param[in] pdu          Pdu of LCH
402  *
403  *  @return  Void
404  *
405  */
406 #ifdef ANSI
407  Void rlcUtlCalUlIpThrPutIncTTI
408 (
409 RlcCb                  *gCb,
410 RlcUlRbCb              *rbCb,
411 U32                   ttiCnt
412 )
413 #else
414 Void rlcUtlCalUlIpThrPutIncTTI(gCb, rbCb, ttiCnt)
415 RlcCb                  *gCb;
416 RlcUlRbCb              *rbCb;
417 U32                   ttiCnt;
418 #endif
419 {
420    VOLATILE U32     startTime = 0;
421    TRC2(rlcUtlCalUlIpThrPutIncTTI)
422
423       /*starting Task*/
424       SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
425 #ifndef ALIGN_64BIT
426    RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:"
427          "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d", 
428          rbCb->rbL2Cb.measOn,ttiCnt,
429          rbCb->rlcId.ueId,
430          rbCb->rlcId.cellId);
431 #else
432    RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:"
433          "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d", 
434          rbCb->rbL2Cb.measOn,ttiCnt,
435          rbCb->rlcId.ueId,
436          rbCb->rlcId.cellId);
437 #endif
438
439    /*Check if UL IP throughput measurement is ON for this RB or not*/
440    if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))              
441    {
442       if (TRUE  == rbCb->ueCb->isUlBurstActive)
443       {
444          if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
445          {
446             /*Removed Error Print*/
447          }
448          if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
449          {
450             rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.timeSummation += 
451                (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
452          }
453          else
454          {
455             rbCb->ueCb->firstPacketTTI = ttiCnt;
456          }
457          rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
458       }
459       else
460       {
461          rbCb->l2MeasIpThruput.prevTtiCnt = 0;
462       }
463    }   
464
465    /*stopping Task*/
466    SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
467 } /* rlcUtlCalUlIpThrPutIncTTI */
468
469
470 /**
471  *
472  * @brief
473  *
474  *        Handler to calculate the Ul Ip throughput for a LCH
475  *
476  * @b Description:
477  *
478  *
479  * @param[in] rbCb         RB control block
480  * @param[in] pdu          Pdu of LCH
481  *
482  *  @return  Void
483  *
484  */
485 #ifdef ANSI
486  Void rlcUtlCalUlIpThrPut
487 (
488 RlcCb                  *gCb,
489 RlcUlRbCb              *rbCb,
490 Buffer                *pdu,
491 U32                   ttiCnt
492 )
493 #else
494 Void rlcUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt)
495    RlcCb                  *gCb;
496    RlcUlRbCb              *rbCb;
497    Buffer                *pdu;
498    U32                   ttiCnt;
499 #endif
500 {
501    MsgLen        rlcSduSz = 0;  /*Holds length of Rlc Sdu*/
502    VOLATILE U32     startTime = 0;
503    TRC2(rlcUtlCalUlIpThrPut)
504
505
506    /*starting Task*/
507    SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
508
509    /*Check if UL IP throughput measurement is ON for this RB or not*/
510    if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&              
511          (TRUE  == rbCb->ueCb->isUlBurstActive) &&
512          (rbCb->ueCb->firstPacketTTI) &&
513          (ttiCnt != rbCb->ueCb->firstPacketTTI))
514    {
515       SFndLenMsg(pdu, &rlcSduSz);
516
517       rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
518
519    }
520    /*stopping Task*/
521    SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
522 } /* rlcUtlCalUlIpThrPut */
523
524 \f
525 /**
526  *
527  * @brief Handler for L2 Measurement timer expiry.
528  *
529  *
530  * @b Description
531  *        This function is called when the l2 measurement timer expires. 
532  *        This function sends a consolidates the mesaurements taken during
533  *        this time and sends the confirm .
534  *
535  *  @param[in] measEvtCb    Measurement Event Control Block.
536  *
537  *
538  *  @return  S16
539  *      -# ROK
540  */
541
542 #ifdef ANSI
543 S16 rlcUtlHdlL2TmrExp
544 (
545 RlcCb          *gCb,
546 RlcL2MeasEvtCb *measEvtCb
547 )
548 #else
549 S16 rlcUtlHdlL2TmrExp(measEvtCb)
550 RlcCb          *gCb;
551 RlcL2MeasEvtCb *measEvtCb;
552 #endif
553 {
554    TRC3(rlcUtlHdlL2TmrExp)
555
556 #ifdef LTE_L2_MEAS_RLC
557    U16             qciIdx;
558    RlcL2MeasCb     *measCb;
559    
560    /* Clean up the RB data structures */
561    if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
562       (measEvtCb->measCb.val.nonIpThMeas.numSamples))
563    {
564       measCb = &measEvtCb->measCb;
565
566       for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
567       {
568          measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe   +=   
569                      rlcCb.rlcL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
570          measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
571       }
572       measEvtCb->val.nonIpThMeas.measCb.numSamples--;
573       rlcStartTmr(gCb, (PTR)measEvtCb, RLC_EVT_L2_TMR); 
574       return (ROK);
575    }
576 #endif
577
578    rlcUtlSndUlL2MeasCfm(gCb, measEvtCb);
579
580    return (ROK);
581 } /* rlcUtlHdlL2TmrExp */
582 /**
583  *
584  * @brief Handler for Sending L2 Measurement confirm.
585  *
586  *
587  * @b Description
588  *        This function sends a consolidates the mesaurements taken during
589  *        this time and sends the confirm .
590  *
591  *  @param[in] measEvtCb    Measurement Event Control Block.
592  *
593  *
594  *  @return  S16
595  *      -# ROK
596  */
597
598 #ifdef ANSI
599 S16 rlcUtlSndUlL2MeasCfm
600 (
601 RlcCb                  *gCb,
602 RlcL2MeasEvtCb         *measEvtCb
603 )
604 #else
605 S16 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb)
606 RlcCb                  *gCb;
607 RlcL2MeasEvtCb         *measEvtCb;
608 #endif
609 {
610    U32                     qciIdx;
611    RlcL2MeasCb              *measCb;
612    RlcL2MeasCfmEvt          measCfmEvt;
613
614    U64                     ulDataVol;
615    U64                     ulTime;
616    U16                     cntr;
617    /* Discard new changes starts */
618    U8                      qci = 0;
619    U32                     cfmIdx =0;
620    /* Discard new changes ends */
621
622    TRC3(rlcUtlSndUlL2MeasCfm)
623
624    /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
625 #ifndef ALIGN_64BIT
626    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
627 #else
628    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
629 #endif
630
631    /* Clean up the RB data structures */
632    measCb = &measEvtCb->measCb;
633    
634    cmMemset((U8*)&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
635    measCfmEvt.transId = measEvtCb->transId;
636
637    measCfmEvt.measType = measCb->measType;
638    measCfmEvt.status.status = LCM_PRIM_OK;
639    measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
640    
641    if( measCb->measType & LKW_L2MEAS_UL_IP)
642    {
643       RlcL2MeasCbUeMeasInfo *pUeInfoLstCb  = measCb->val.ipThMeas.ueInfoLst;
644       RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
645       for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)        
646       {
647          pUeInfoLstCfm[cfmIdx].numCfm = 0;
648          if (pUeInfoLstCb[cntr].isValid == TRUE)
649          {
650             pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
651             pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
652
653             for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
654             {
655                qci = pUeInfoLstCb[cntr].qci[qciIdx];
656                pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
657
658                if(measCb->measType & LKW_L2MEAS_UL_IP)
659                {
660                   ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
661                   ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
662                   if(0 == ulTime)
663                   {
664                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
665                   }
666                   else
667                   {
668                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
669
670                      /* Converting it to kbps */
671                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
672
673                   }
674                   /* Reset the values after reporting to Application */
675                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
676                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
677                }
678                pUeInfoLstCfm[cfmIdx].numCfm++;
679             }
680             cfmIdx++;
681          }
682       }
683       measCfmEvt.val.ipThMeas.numUes = cfmIdx; 
684    }
685    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
686    return (ROK);
687 } /* rlcUtlSndUlL2MeasCfm */
688 /**
689  *
690  * @brief Handler for Sending Negative confirm .
691  *
692  *
693   @b Description
694  *        This function is called when the l2 measurement cannot be started
695  *        This function sends  negative confirm for all the requests
696  *
697  * @param[in] gCb - RLC instance control block
698  * @param[in] measReqEvt    Measurement Req Structure
699  * @param[in] measCfmEvt  Confirmation to be sent to layer manager
700  *
701  *
702  *  @return  S16
703  *      -# ROK
704  */
705
706 #ifdef ANSI
707 S16 rlcUtlSndUlL2MeasNCfm
708 (
709 RlcCb           *gCb,
710 RlcL2MeasReqEvt *measReqEvt,
711 RlcL2MeasCfmEvt *measCfmEvt
712 )
713 #else
714 S16 rlcUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt)
715 RlcCb           *gCb;
716 RlcL2MeasReqEvt *measReqEvt;
717 RlcL2MeasCfmEvt *measCfmEvt;
718 #endif
719 {
720    TRC3(rlcUtlSndUlL2MeasNCfm)
721
722    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
723    return ROK;
724 } /* kwUtlSndL2MeasNCfm */
725
726 #ifdef LTE_L2_MEAS_RLC
727 /**
728  * @brief  Validates the measurement request parameters. 
729  *
730  * @details
731  *
732  *     Function :rlcUtlValidateL2Meas 
733  *
734  *  @param[in]  measReqEvt L2 measurement request received from layer manager.
735  *  @param[out] measCfmEvt L2 measurement confirm to be prepared.
736  *  @param[out] lChId      List of LCh for the given Ue corresponding to QCIs
737                            given in measurement request.
738  *  @param[out] numLCh     Number of LCh in array lChId.
739  **/
740
741 #ifdef ANSI
742 S16 rlcUtlValidateL2Meas
743 (
744 RlcL2MeasReqEvt *measReqEvt,
745 RlcL2MeasCfmEvt *measCfmEvt,
746 CmLteLcId      *lChId,
747 U8             *numLCh
748 )
749 #else
750 S16 rlcUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh)
751 RlcL2MeasReqEvt *measReqEvt;
752 RlcL2MeasCfmEvt *measCfmEvt;
753 CmLteLcId      *lChId;
754 U8             *numLCh;
755 #endif
756 {
757    U8          measType;
758    S16         ret;
759    U8          qciIdx;
760    U8          qci;
761    U8          idx;
762    U8         *qciVal;
763    U8          numQci;
764    RlcUlRbCb  *rbCb;
765
766    RlcUlUeCb   *ueCb;
767    RbCb       **rbCbLst;
768    U8         rbIdx;
769    U8         lsbNibble = 0;
770    U8         msbNibble = 0;
771    U8         numFaild = 0;
772
773
774    TRC3(rlcUtlValidateL2Meas)
775    
776    idx = 0;
777    rbCb = NULLP;
778    ret = ROK;
779    measType = measReqEvt->measReq.measType;
780    /* Check for the range of measType */
781    /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
782    if((measType == 0x00) ||
783        measType > 0x30)
784    {
785       measCfmEvt->transId = measReqEvt->transId;
786       measCfmEvt->measType = measType;
787       measCfmEvt->status.status = LCM_PRIM_NOK;
788       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
789       return RFAILED;
790    }
791    /*User can either request for Active UE,*
792     *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
793    lsbNibble = measType & 0x0F;
794    msbNibble = measType & 0xF0;
795
796    if( (lsbNibble != 0) && (msbNibble != 0) )
797    {
798       measCfmEvt->transId = measReqEvt->transId;
799       measCfmEvt->measType = measType;
800       measCfmEvt->status.status = LCM_PRIM_NOK;
801       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
802       return RFAILED;
803    }
804
805    /* Check for total maximum number of Measurement Control Block */
806    if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
807    {
808       measCfmEvt->transId = measReqEvt->transId;
809       measCfmEvt->measType = measType;
810       measCfmEvt->status.status = LCM_PRIM_NOK;
811       measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
812       return RFAILED;
813    }
814
815    /* Check that number of samples should be a non-zero value */
816    if(((measType & LKW_L2MEAS_ACT_UE) &&
817       (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
818    {
819       measCfmEvt->transId = measReqEvt->transId;
820       measCfmEvt->measType = measType;
821       measCfmEvt->status.status = LCM_PRIM_NOK;
822       measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
823       return RFAILED;
824    }
825    /* Check that measurement period  should be completely divisible *
826     * number of sample.                                             */
827    if(((measType & LKW_L2MEAS_ACT_UE) &&
828       ((measReqEvt->measPeriod % 
829         measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
830    {
831       measCfmEvt->transId = measReqEvt->transId;
832       measCfmEvt->measType = measType;
833       measCfmEvt->status.status = LCM_PRIM_NOK;
834       measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
835       return RFAILED;
836    }
837    {
838       numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
839       qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
840    }
841    /* Check whether qci is configured or not */
842    for(qciIdx = 0; qciIdx < numQci; qciIdx++)
843    {
844       qci = qciVal[qciIdx];
845       ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp), 
846             (U8 *)&qci, (U16)sizeof(qci), 0, (PTR *)&rbCb);
847       if(ret != ROK)
848       {
849          measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
850          measCfmEvt->val.nonIpThMeas.numCfm++;
851
852       }
853    }
854    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
855    {
856       measCfmEvt->status.status = LCM_PRIM_NOK;
857       measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
858       measCfmEvt->measType = measType;
859       measCfmEvt->transId = measReqEvt->transId;
860       return RFAILED;
861    }
862    {
863       for(qciIdx = 0; qciIdx < numQci; qciIdx++)
864       {
865          if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
866          {
867             /* measurement is already ongoing */
868             measCfmEvt->status.status = LCM_PRIM_NOK;
869             measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
870             measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
871             measCfmEvt->measType = measType;
872             measCfmEvt->val.nonIpThMeas.numCfm++;
873          }
874       }
875    }
876    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
877    {
878       measCfmEvt->transId = measReqEvt->transId;
879       return RFAILED;
880    }
881
882    return (ROK);
883 }/* rlcUtlValidateL2Meas */
884 #endif
885
886 #ifdef ANSI
887 S16 rlcUtlValidateIpThL2Meas
888 (
889 RlcL2MeasReqEvt *measReqEvt,
890 RlcL2MeasCfmEvt *measCfmEvt
891 )
892 #else
893 S16 rlcUtlValidateIpThL2Meas(measReqEvt, measCfmEvt)
894 RlcL2MeasReqEvt *measReqEvt;
895 RlcL2MeasCfmEvt *measCfmEvt;
896 #endif
897 {
898    U8      measType;
899    U8         lsbNibble = 0;
900    U8         msbNibble = 0;
901
902    TRC3(rlcUtlValidateIpThL2Meas)
903    
904    measType = measReqEvt->measReq.measType;
905    /* Check for the range of measType */
906    /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
907    if((measType == 0x00) ||
908        measType > 0x30)
909    {
910       measCfmEvt->transId = measReqEvt->transId;
911       measCfmEvt->measType = measType;
912       measCfmEvt->status.status = LCM_PRIM_NOK;
913       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
914       return RFAILED;
915    }
916    /*User can either request for Active UE,*
917     *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
918    lsbNibble = measType & 0x0F;
919    msbNibble = measType & 0xF0;
920
921    if( (lsbNibble != 0) && (msbNibble != 0) )
922    {
923       measCfmEvt->transId = measReqEvt->transId;
924       measCfmEvt->measType = measType;
925       measCfmEvt->status.status = LCM_PRIM_NOK;
926       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
927       return RFAILED;
928    }
929    return (ROK);
930 }/* rlcUtlValidateL2Meas */
931
932 /**
933  *
934  * @brief Handler for resetting the RB data structures
935  *
936  *
937  * @b Description
938  *        This function resets the RB data structure after the expiry of 
939  *        measurement timer.
940  *
941  *  @param[in] measCb    Measurement Control Block.
942  *
943  *
944  *  @return  Void
945  */
946 #ifdef ANSI
947
948 Void rlcUtlResetUlL2MeasInRlcRb
949 (
950 RlcCb       *gCb,
951 RlcL2MeasCb *measCb,
952 U8             measType
953 )
954 #else
955 Void rlcUtlResetUlL2MeasInRlcRb(measCb, measType)
956 RlcCb       *gCb;
957 RlcL2MeasCb *measCb;
958 U8             measType;
959 #endif
960 {
961    U32           rbIdx;
962    U32           ueIdx;
963    U32           qciIdx;
964    RlcUlUeCb         *ueCb = NULL;
965
966
967
968    if (measCb->measType & LKW_L2MEAS_UL_IP)
969    {
970       for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
971       {           
972          if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
973          {
974             for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
975             {
976                if (measType & LKW_L2MEAS_UL_IP)
977                {
978                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
979                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
980                }
981             }
982
983             if(ROK  != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
984                      measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
985             {
986                continue;
987             }
988
989             for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
990             {
991                if (ueCb->drbCb[rbIdx])
992                {
993                   ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
994                }
995             }
996          }
997       }
998    }
999 } /* rlcUtlResetUlL2MeasInRlcRb */
1000
1001 /**
1002  *
1003  * @brief Handler for storing address of MeasData in rbCb at right index
1004  *
1005  *
1006  * @b Description
1007  *        This function is called when LM sends measReq message to RLC.
1008  *
1009  *  @param[in] 
1010  *  @param[out] 
1011  *  @param[in] 
1012  *
1013  *
1014  *  @return  S16
1015  *      -# ROK
1016  */
1017 #ifdef ANSI
1018 Void rlcUtlPlcMeasDatInL2Sts
1019 (
1020 RlcL2Cntr       *measData, 
1021 RlcL2MeasRbCb   *rbL2Cb,
1022 U8             measType
1023 )
1024 #else
1025 Void rlcUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType)
1026 RlcL2Cntr       *measData; 
1027 RlcL2MeasRbCb   *rbL2Cb;
1028 U8             measType;
1029 #endif
1030 {
1031    TRC3(rlcUtlPlcMeasDatInL2Sts)
1032    
1033    /* We should check the number of measType in the request. This can be done 
1034     * by looking at each bit in the measType. Also store the measData in the 
1035     * correct index of l2Sts in RbCb.
1036     * */
1037
1038     if(measType & LKW_L2MEAS_ACT_UE)
1039     {
1040          rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
1041     }
1042     if(measType & LKW_L2MEAS_UU_LOSS)
1043     {
1044          rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
1045     }
1046     if(measType & LKW_L2MEAS_DL_IP )
1047     {
1048          rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
1049     }
1050     if(measType & LKW_L2MEAS_UL_IP)
1051     {
1052          rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
1053     }
1054     if(measType & LKW_L2MEAS_DL_DISC)
1055     {
1056          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
1057     }
1058     if(measType & LKW_L2MEAS_DL_DELAY)
1059     {
1060          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
1061     }
1062 }/* End of rlcUtlPlcMeasDatInL2Sts */
1063 #endif /* LTE_L2_MEAS */
1064
1065 /**
1066  *
1067  * @brief Store the UL buffer in hashList  
1068  *
1069  *
1070  * @b Description
1071  *
1072  *   Use the SN % binSize as key and store the received UL buffer
1073  *  @param[in] recBufLst       List CP array
1074  *  @param[in] recBuf          received buffer
1075  *  @param[in] sn              sn of the received buffer 
1076  *
1077  *
1078  *  @return  Void
1079  */
1080 #ifdef ANSI
1081 Void rlcUtlStoreRecBuf 
1082 (
1083 CmLListCp        *recBufLst,
1084 RlcAmRecBuf       *recBuf,
1085 RlcSn              sn
1086 )
1087 #else
1088 Void rlcUtlStoreRecBuf(recBufLst, recBuf, sn)
1089 CmLListCp        *recBufLst;
1090 RlcAmRecBuf       *recBuf;
1091 RlcSn              sn;
1092 #endif
1093 {
1094    U32             hashKey; 
1095
1096    TRC3(rlcUtlStoreRecBuf)
1097    
1098    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1099    recBuf->lnk.node = (PTR)recBuf;
1100    cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1101
1102    RETVOID;
1103 } /* rlcUtlStoreRecBuf */
1104
1105 /**
1106  *
1107  * @brief Retrieve the UL buffer from the list
1108  *
1109  *
1110  * @Description
1111  *
1112  *   Use the SN % binSize as key and retrieve the UL buffer
1113  *  @param[in] recBufLst       List CP array
1114  *  @param[in] sn              sn of the received buffer 
1115  *
1116  *
1117  *  @return  Void
1118  */
1119 #ifdef ANSI
1120 RlcAmRecBuf* rlcUtlGetRecBuf 
1121 (
1122 CmLListCp        *recBufLst,
1123 RlcSn             sn
1124 )
1125 #else
1126 RlcAmRecBuf* rlcUtlGetRecBuf(recBufLst, sn)
1127 CmLListCp        *recBufLst;
1128 RlcSn             sn;
1129 #endif
1130 {
1131    U32                 hashKey; 
1132    CmLListCp           *recBufLstCp;
1133    RlcAmRecBuf          *recBuf;
1134    CmLList             *node = NULLP;
1135
1136    TRC3(rlcUtlGetRecBuf)
1137
1138    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1139  
1140    recBufLstCp = &recBufLst[hashKey];
1141    CM_LLIST_FIRST_NODE(recBufLstCp, node);
1142    while(node)
1143    {
1144       recBuf = (RlcAmRecBuf *) node->node;
1145       if(recBuf->amHdr.sn == sn)
1146       {
1147          return (recBuf);
1148       }
1149       CM_LLIST_NEXT_NODE(recBufLstCp, node);
1150    }
1151    return (NULLP);
1152 } /* rlcUtlStoreRecBuf */
1153 /**
1154  *
1155  * @brief Delete the UL buffer from the list
1156  *
1157  *
1158  * @Description
1159  *
1160  *   Use the SN % binSize as key and retrieve the UL buffer
1161  *  @param[in] recBufLst       List CP array
1162  *  @param[in] sn              sn of the received buffer 
1163  *
1164  *
1165  *  @return  Void
1166  */
1167 #ifdef ANSI
1168 Void rlcUtlDelRecBuf 
1169 (
1170 CmLListCp        *recBufLst,
1171 RlcAmRecBuf       *recBuf,
1172 RlcCb              *gCb                              
1173 )
1174 #else
1175 Void rlcUtlDelRecBuf(recBufLst, recBufi, gCb)
1176 CmLListCp        *recBufLst;
1177 RlcAmRecBuf       *recBuf;
1178 RlcCb             *gCb;                              
1179 #endif
1180 {
1181    U32                 hashKey; 
1182    CmLListCp           *recBufLstCp;
1183
1184    TRC3(rlcUtlDelRecBuf)
1185
1186    hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE ); 
1187  
1188    recBufLstCp = &recBufLst[hashKey];
1189    cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1190    RLC_FREE_WC(gCb, recBuf, sizeof(RlcAmRecBuf));
1191
1192    RETVOID;
1193 } /* rlcUtlDelRecBuf */
1194
1195
1196
1197
1198 /********************************************************************30**
1199          End of file
1200 **********************************************************************/