RLC BO, BO response and DL Data handling. [Issue-ID: ODUHIGH-181]
[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                RLC_FREE_BUF_WC(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                RLC_FREE_BUF_WC(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       RLC_FREE_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 PRIVATE Void dumpRLCUlRbInformation(RlcUlRbCb* ulRbCb)
274 {
275    if(ulRbCb->mode == CM_LTE_MODE_UM)
276    {
277       U32 i;
278       U32 pdusInReceptionBuffer = 0;
279       U32 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       U32 i;
298       U32 pdusInReceptionBuffer = 0;
299       U32 totalSegs = 0;
300       U32 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       U32 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    U16             cntr;
379
380    gCb->u.ulCb->rlcL2Cb.rlcNumMeas=0;
381    for(cntr = 0; cntr < LKW_MAX_L2MEAS; cntr++)
382    {
383       cmMemset((U8 *)&(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 #ifdef ANSI
404  Void rlcUtlCalUlIpThrPutIncTTI
405 (
406 RlcCb                  *gCb,
407 RlcUlRbCb              *rbCb,
408 U32                   ttiCnt
409 )
410 #else
411 Void rlcUtlCalUlIpThrPutIncTTI(gCb, rbCb, ttiCnt)
412 RlcCb                  *gCb;
413 RlcUlRbCb              *rbCb;
414 U32                   ttiCnt;
415 #endif
416 {
417    VOLATILE U32     startTime = 0;
418    TRC2(rlcUtlCalUlIpThrPutIncTTI)
419
420       /*starting Task*/
421       SStartTask(&startTime, PID_RLC_IP_TPT_INCTTI);
422 #ifndef ALIGN_64BIT
423    RLOG_ARG4(L_UNUSED, DBG_RBID,rbCb->rlcId.rbId,"Log for ul ip throughput:"
424          "RB_MeasOn:%d ttiCnt :%ld UEID:%d CELLID:%d", 
425          rbCb->rbL2Cb.measOn,ttiCnt,
426          rbCb->rlcId.ueId,
427          rbCb->rlcId.cellId);
428 #else
429    RLOG_ARG4(L_UNUSED,DBG_RBID,rbCb->rlcId.rbId, "Log for ul ip throughput:"
430          "RB_MeasOn:%d ttiCnt :%d UEID:%d CELLID:%d", 
431          rbCb->rbL2Cb.measOn,ttiCnt,
432          rbCb->rlcId.ueId,
433          rbCb->rlcId.cellId);
434 #endif
435
436    /*Check if UL IP throughput measurement is ON for this RB or not*/
437    if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb,rbCb))              
438    {
439       if (TRUE  == rbCb->ueCb->isUlBurstActive)
440       {
441          if (ttiCnt < rbCb->l2MeasIpThruput.prevTtiCnt)
442          {
443             /*Removed Error Print*/
444          }
445          if (rbCb->l2MeasIpThruput.prevTtiCnt != 0)
446          {
447             rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.timeSummation += 
448                (ttiCnt - rbCb->l2MeasIpThruput.prevTtiCnt);
449          }
450          else
451          {
452             rbCb->ueCb->firstPacketTTI = ttiCnt;
453          }
454          rbCb->l2MeasIpThruput.prevTtiCnt = ttiCnt;
455       }
456       else
457       {
458          rbCb->l2MeasIpThruput.prevTtiCnt = 0;
459       }
460    }   
461
462    /*stopping Task*/
463    SStopTask(startTime, PID_RLC_IP_TPT_INCTTI);
464 } /* rlcUtlCalUlIpThrPutIncTTI */
465
466
467 /**
468  *
469  * @brief
470  *
471  *        Handler to calculate the Ul Ip throughput for a LCH
472  *
473  * @b Description:
474  *
475  *
476  * @param[in] rbCb         RB control block
477  * @param[in] pdu          Pdu of LCH
478  *
479  *  @return  Void
480  *
481  */
482 #ifdef ANSI
483  Void rlcUtlCalUlIpThrPut
484 (
485 RlcCb                  *gCb,
486 RlcUlRbCb              *rbCb,
487 Buffer                *pdu,
488 U32                   ttiCnt
489 )
490 #else
491 Void rlcUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt)
492    RlcCb                  *gCb;
493    RlcUlRbCb              *rbCb;
494    Buffer                *pdu;
495    U32                   ttiCnt;
496 #endif
497 {
498    MsgLen        rlcSduSz = 0;  /*Holds length of Rlc Sdu*/
499    VOLATILE U32     startTime = 0;
500    TRC2(rlcUtlCalUlIpThrPut)
501
502
503    /*starting Task*/
504    SStartTask(&startTime, PID_RLC_IP_TPT_INCVOL);
505
506    /*Check if UL IP throughput measurement is ON for this RB or not*/
507    if(RLC_MEAS_IS_UL_IP_MEAS_ON_FOR_RB(gCb, rbCb) &&              
508          (TRUE  == rbCb->ueCb->isUlBurstActive) &&
509          (rbCb->ueCb->firstPacketTTI) &&
510          (ttiCnt != rbCb->ueCb->firstPacketTTI))
511    {
512       SFndLenMsg(pdu, &rlcSduSz);
513
514       rbCb->rbL2Cb.l2Sts[RLC_L2MEAS_UL_IP]->ulIpThruput.volSummation += rlcSduSz;
515
516    }
517    /*stopping Task*/
518    SStopTask(startTime, PID_RLC_IP_TPT_INCVOL);
519 } /* rlcUtlCalUlIpThrPut */
520
521 \f
522 /**
523  *
524  * @brief Handler for L2 Measurement timer expiry.
525  *
526  *
527  * @b Description
528  *        This function is called when the l2 measurement timer expires. 
529  *        This function sends a consolidates the mesaurements taken during
530  *        this time and sends the confirm .
531  *
532  *  @param[in] measEvtCb    Measurement Event Control Block.
533  *
534  *
535  *  @return  S16
536  *      -# ROK
537  */
538
539 #ifdef ANSI
540 S16 rlcUtlHdlL2TmrExp
541 (
542 RlcCb          *gCb,
543 RlcL2MeasEvtCb *measEvtCb
544 )
545 #else
546 S16 rlcUtlHdlL2TmrExp(measEvtCb)
547 RlcCb          *gCb;
548 RlcL2MeasEvtCb *measEvtCb;
549 #endif
550 {
551    TRC3(rlcUtlHdlL2TmrExp)
552
553 #ifdef LTE_L2_MEAS_RLC
554    U16             qciIdx;
555    RlcL2MeasCb     *measCb;
556    
557    /* Clean up the RB data structures */
558    if((measEvtCb->measCb.measType & LKW_L2MEAS_ACT_UE) &&
559       (measEvtCb->measCb.val.nonIpThMeas.numSamples))
560    {
561       measCb = &measEvtCb->measCb;
562
563       for(qciIdx = 0; qciIdx < measCb->val.nonIpThMeas.numQci;qciIdx++)
564       {
565          measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.numActvUe   +=   
566                      rlcCb.rlcL2Cb.numActUe[measCb->val.nonIpThMeas.qci[qciIdx]];
567          measCb->val.nonIpThMeas.measData[measCb->val.nonIpThMeas.qci[qciIdx]].actUe.sampOc++;
568       }
569       measEvtCb->val.nonIpThMeas.measCb.numSamples--;
570       rlcStartTmr(gCb, (PTR)measEvtCb, RLC_EVT_L2_TMR); 
571       return (ROK);
572    }
573 #endif
574
575    rlcUtlSndUlL2MeasCfm(gCb, measEvtCb);
576
577    return (ROK);
578 } /* rlcUtlHdlL2TmrExp */
579 /**
580  *
581  * @brief Handler for Sending L2 Measurement confirm.
582  *
583  *
584  * @b Description
585  *        This function sends a consolidates the mesaurements taken during
586  *        this time and sends the confirm .
587  *
588  *  @param[in] measEvtCb    Measurement Event Control Block.
589  *
590  *
591  *  @return  S16
592  *      -# ROK
593  */
594
595 #ifdef ANSI
596 S16 rlcUtlSndUlL2MeasCfm
597 (
598 RlcCb                  *gCb,
599 RlcL2MeasEvtCb         *measEvtCb
600 )
601 #else
602 S16 rlcUtlSndUlL2MeasCfm(gCb, measEvtCb)
603 RlcCb                  *gCb;
604 RlcL2MeasEvtCb         *measEvtCb;
605 #endif
606 {
607    U32                     qciIdx;
608    RlcL2MeasCb              *measCb;
609    RlcL2MeasCfmEvt          measCfmEvt;
610
611    U64                     ulDataVol;
612    U64                     ulTime;
613    U16                     cntr;
614    /* Discard new changes starts */
615    U8                      qci = 0;
616    U32                     cfmIdx =0;
617    /* Discard new changes ends */
618
619    TRC3(rlcUtlSndUlL2MeasCfm)
620
621    /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
622 #ifndef ALIGN_64BIT
623    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
624 #else
625    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
626 #endif
627
628    /* Clean up the RB data structures */
629    measCb = &measEvtCb->measCb;
630    
631    cmMemset((U8*)&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
632    measCfmEvt.transId = measEvtCb->transId;
633
634    measCfmEvt.measType = measCb->measType;
635    measCfmEvt.status.status = LCM_PRIM_OK;
636    measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
637    
638    if( measCb->measType & LKW_L2MEAS_UL_IP)
639    {
640       RlcL2MeasCbUeMeasInfo *pUeInfoLstCb  = measCb->val.ipThMeas.ueInfoLst;
641       RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
642       for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)        
643       {
644          pUeInfoLstCfm[cfmIdx].numCfm = 0;
645          if (pUeInfoLstCb[cntr].isValid == TRUE)
646          {
647             pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
648             pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
649
650             for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
651             {
652                qci = pUeInfoLstCb[cntr].qci[qciIdx];
653                pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
654
655                if(measCb->measType & LKW_L2MEAS_UL_IP)
656                {
657                   ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
658                   ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
659                   if(0 == ulTime)
660                   {
661                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
662                   }
663                   else
664                   {
665                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
666
667                      /* Converting it to kbps */
668                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
669
670                   }
671                   /* Reset the values after reporting to Application */
672                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
673                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
674                }
675                pUeInfoLstCfm[cfmIdx].numCfm++;
676             }
677             cfmIdx++;
678          }
679       }
680       measCfmEvt.val.ipThMeas.numUes = cfmIdx; 
681    }
682    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
683    return (ROK);
684 } /* rlcUtlSndUlL2MeasCfm */
685 /**
686  *
687  * @brief Handler for Sending Negative confirm .
688  *
689  *
690   @b Description
691  *        This function is called when the l2 measurement cannot be started
692  *        This function sends  negative confirm for all the requests
693  *
694  * @param[in] gCb - RLC instance control block
695  * @param[in] measReqEvt    Measurement Req Structure
696  * @param[in] measCfmEvt  Confirmation to be sent to layer manager
697  *
698  *
699  *  @return  S16
700  *      -# ROK
701  */
702
703 #ifdef ANSI
704 S16 rlcUtlSndUlL2MeasNCfm
705 (
706 RlcCb           *gCb,
707 RlcL2MeasReqEvt *measReqEvt,
708 RlcL2MeasCfmEvt *measCfmEvt
709 )
710 #else
711 S16 rlcUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt)
712 RlcCb           *gCb;
713 RlcL2MeasReqEvt *measReqEvt;
714 RlcL2MeasCfmEvt *measCfmEvt;
715 #endif
716 {
717    TRC3(rlcUtlSndUlL2MeasNCfm)
718
719    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
720    return ROK;
721 } /* kwUtlSndL2MeasNCfm */
722
723 #ifdef LTE_L2_MEAS_RLC
724 /**
725  * @brief  Validates the measurement request parameters. 
726  *
727  * @details
728  *
729  *     Function :rlcUtlValidateL2Meas 
730  *
731  *  @param[in]  measReqEvt L2 measurement request received from layer manager.
732  *  @param[out] measCfmEvt L2 measurement confirm to be prepared.
733  *  @param[out] lChId      List of LCh for the given Ue corresponding to QCIs
734                            given in measurement request.
735  *  @param[out] numLCh     Number of LCh in array lChId.
736  **/
737
738 #ifdef ANSI
739 S16 rlcUtlValidateL2Meas
740 (
741 RlcL2MeasReqEvt *measReqEvt,
742 RlcL2MeasCfmEvt *measCfmEvt,
743 CmLteLcId      *lChId,
744 U8             *numLCh
745 )
746 #else
747 S16 rlcUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh)
748 RlcL2MeasReqEvt *measReqEvt;
749 RlcL2MeasCfmEvt *measCfmEvt;
750 CmLteLcId      *lChId;
751 U8             *numLCh;
752 #endif
753 {
754    U8          measType;
755    S16         ret;
756    U8          qciIdx;
757    U8          qci;
758    U8          idx;
759    U8         *qciVal;
760    U8          numQci;
761    RlcUlRbCb  *rbCb;
762
763    RlcUlUeCb   *ueCb;
764    RbCb       **rbCbLst;
765    U8         rbIdx;
766    U8         lsbNibble = 0;
767    U8         msbNibble = 0;
768    U8         numFaild = 0;
769
770
771    TRC3(rlcUtlValidateL2Meas)
772    
773    idx = 0;
774    rbCb = NULLP;
775    ret = ROK;
776    measType = measReqEvt->measReq.measType;
777    /* Check for the range of measType */
778    /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
779    if((measType == 0x00) ||
780        measType > 0x30)
781    {
782       measCfmEvt->transId = measReqEvt->transId;
783       measCfmEvt->measType = measType;
784       measCfmEvt->status.status = LCM_PRIM_NOK;
785       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
786       return RFAILED;
787    }
788    /*User can either request for Active UE,*
789     *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
790    lsbNibble = measType & 0x0F;
791    msbNibble = measType & 0xF0;
792
793    if( (lsbNibble != 0) && (msbNibble != 0) )
794    {
795       measCfmEvt->transId = measReqEvt->transId;
796       measCfmEvt->measType = measType;
797       measCfmEvt->status.status = LCM_PRIM_NOK;
798       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
799       return RFAILED;
800    }
801
802    /* Check for total maximum number of Measurement Control Block */
803    if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
804    {
805       measCfmEvt->transId = measReqEvt->transId;
806       measCfmEvt->measType = measType;
807       measCfmEvt->status.status = LCM_PRIM_NOK;
808       measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
809       return RFAILED;
810    }
811
812    /* Check that number of samples should be a non-zero value */
813    if(((measType & LKW_L2MEAS_ACT_UE) &&
814       (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
815    {
816       measCfmEvt->transId = measReqEvt->transId;
817       measCfmEvt->measType = measType;
818       measCfmEvt->status.status = LCM_PRIM_NOK;
819       measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
820       return RFAILED;
821    }
822    /* Check that measurement period  should be completely divisible *
823     * number of sample.                                             */
824    if(((measType & LKW_L2MEAS_ACT_UE) &&
825       ((measReqEvt->measPeriod % 
826         measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
827    {
828       measCfmEvt->transId = measReqEvt->transId;
829       measCfmEvt->measType = measType;
830       measCfmEvt->status.status = LCM_PRIM_NOK;
831       measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
832       return RFAILED;
833    }
834    {
835       numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
836       qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
837    }
838    /* Check whether qci is configured or not */
839    for(qciIdx = 0; qciIdx < numQci; qciIdx++)
840    {
841       qci = qciVal[qciIdx];
842       ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp), 
843             (U8 *)&qci, (U16)sizeof(qci), 0, (PTR *)&rbCb);
844       if(ret != ROK)
845       {
846          measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
847          measCfmEvt->val.nonIpThMeas.numCfm++;
848
849       }
850    }
851    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
852    {
853       measCfmEvt->status.status = LCM_PRIM_NOK;
854       measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
855       measCfmEvt->measType = measType;
856       measCfmEvt->transId = measReqEvt->transId;
857       return RFAILED;
858    }
859    {
860       for(qciIdx = 0; qciIdx < numQci; qciIdx++)
861       {
862          if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
863          {
864             /* measurement is already ongoing */
865             measCfmEvt->status.status = LCM_PRIM_NOK;
866             measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
867             measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
868             measCfmEvt->measType = measType;
869             measCfmEvt->val.nonIpThMeas.numCfm++;
870          }
871       }
872    }
873    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
874    {
875       measCfmEvt->transId = measReqEvt->transId;
876       return RFAILED;
877    }
878
879    return (ROK);
880 }/* rlcUtlValidateL2Meas */
881 #endif
882
883 #ifdef ANSI
884 S16 rlcUtlValidateIpThL2Meas
885 (
886 RlcL2MeasReqEvt *measReqEvt,
887 RlcL2MeasCfmEvt *measCfmEvt
888 )
889 #else
890 S16 rlcUtlValidateIpThL2Meas(measReqEvt, measCfmEvt)
891 RlcL2MeasReqEvt *measReqEvt;
892 RlcL2MeasCfmEvt *measCfmEvt;
893 #endif
894 {
895    U8      measType;
896    U8         lsbNibble = 0;
897    U8         msbNibble = 0;
898
899    TRC3(rlcUtlValidateIpThL2Meas)
900    
901    measType = measReqEvt->measReq.measType;
902    /* Check for the range of measType */
903    /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
904    if((measType == 0x00) ||
905        measType > 0x30)
906    {
907       measCfmEvt->transId = measReqEvt->transId;
908       measCfmEvt->measType = measType;
909       measCfmEvt->status.status = LCM_PRIM_NOK;
910       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
911       return RFAILED;
912    }
913    /*User can either request for Active UE,*
914     *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
915    lsbNibble = measType & 0x0F;
916    msbNibble = measType & 0xF0;
917
918    if( (lsbNibble != 0) && (msbNibble != 0) )
919    {
920       measCfmEvt->transId = measReqEvt->transId;
921       measCfmEvt->measType = measType;
922       measCfmEvt->status.status = LCM_PRIM_NOK;
923       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
924       return RFAILED;
925    }
926    return (ROK);
927 }/* rlcUtlValidateL2Meas */
928
929 /**
930  *
931  * @brief Handler for resetting the RB data structures
932  *
933  *
934  * @b Description
935  *        This function resets the RB data structure after the expiry of 
936  *        measurement timer.
937  *
938  *  @param[in] measCb    Measurement Control Block.
939  *
940  *
941  *  @return  Void
942  */
943 #ifdef ANSI
944
945 Void rlcUtlResetUlL2MeasInRlcRb
946 (
947 RlcCb       *gCb,
948 RlcL2MeasCb *measCb,
949 U8             measType
950 )
951 #else
952 Void rlcUtlResetUlL2MeasInRlcRb(measCb, measType)
953 RlcCb       *gCb;
954 RlcL2MeasCb *measCb;
955 U8             measType;
956 #endif
957 {
958    U32           rbIdx;
959    U32           ueIdx;
960    U32           qciIdx;
961    RlcUlUeCb         *ueCb = NULL;
962
963
964
965    if (measCb->measType & LKW_L2MEAS_UL_IP)
966    {
967       for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
968       {           
969          if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
970          {
971             for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
972             {
973                if (measType & LKW_L2MEAS_UL_IP)
974                {
975                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
976                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
977                }
978             }
979
980             if(ROK  != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
981                      measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
982             {
983                continue;
984             }
985
986             for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
987             {
988                if (ueCb->drbCb[rbIdx])
989                {
990                   ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
991                }
992             }
993          }
994       }
995    }
996 } /* rlcUtlResetUlL2MeasInRlcRb */
997
998 /**
999  *
1000  * @brief Handler for storing address of MeasData in rbCb at right index
1001  *
1002  *
1003  * @b Description
1004  *        This function is called when LM sends measReq message to RLC.
1005  *
1006  *  @param[in] 
1007  *  @param[out] 
1008  *  @param[in] 
1009  *
1010  *
1011  *  @return  S16
1012  *      -# ROK
1013  */
1014 #ifdef ANSI
1015 Void rlcUtlPlcMeasDatInL2Sts
1016 (
1017 RlcL2Cntr       *measData, 
1018 RlcL2MeasRbCb   *rbL2Cb,
1019 U8             measType
1020 )
1021 #else
1022 Void rlcUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType)
1023 RlcL2Cntr       *measData; 
1024 RlcL2MeasRbCb   *rbL2Cb;
1025 U8             measType;
1026 #endif
1027 {
1028    TRC3(rlcUtlPlcMeasDatInL2Sts)
1029    
1030    /* We should check the number of measType in the request. This can be done 
1031     * by looking at each bit in the measType. Also store the measData in the 
1032     * correct index of l2Sts in RbCb.
1033     * */
1034
1035     if(measType & LKW_L2MEAS_ACT_UE)
1036     {
1037          rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
1038     }
1039     if(measType & LKW_L2MEAS_UU_LOSS)
1040     {
1041          rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
1042     }
1043     if(measType & LKW_L2MEAS_DL_IP )
1044     {
1045          rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
1046     }
1047     if(measType & LKW_L2MEAS_UL_IP)
1048     {
1049          rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
1050     }
1051     if(measType & LKW_L2MEAS_DL_DISC)
1052     {
1053          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
1054     }
1055     if(measType & LKW_L2MEAS_DL_DELAY)
1056     {
1057          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
1058     }
1059 }/* End of rlcUtlPlcMeasDatInL2Sts */
1060 #endif /* LTE_L2_MEAS */
1061
1062 /**
1063  *
1064  * @brief Store the UL buffer in hashList  
1065  *
1066  *
1067  * @b Description
1068  *
1069  *   Use the SN % binSize as key and store the received UL buffer
1070  *  @param[in] recBufLst       List CP array
1071  *  @param[in] recBuf          received buffer
1072  *  @param[in] sn              sn of the received buffer 
1073  *
1074  *
1075  *  @return  Void
1076  */
1077 void rlcUtlStoreRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcSn sn)
1078 {
1079    uint32_t    hashKey; 
1080    
1081    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1082    recBuf->lnk.node = (PTR)recBuf;
1083    cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1084
1085    return;
1086 } /* rlcUtlStoreRecBuf */
1087
1088 /**
1089  *
1090  * @brief Retrieve the UL buffer from the list
1091  *
1092  *
1093  * @Description
1094  *
1095  *   Use the SN % binSize as key and retrieve the UL buffer
1096  *  @param[in] recBufLst       List CP array
1097  *  @param[in] sn              sn of the received buffer 
1098  *
1099  *
1100  *  @return  Void
1101  */
1102 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn)
1103 {
1104    uint32_t            hashKey; 
1105    CmLListCp           *recBufLstCp;
1106    RlcAmRecBuf          *recBuf;
1107    CmLList             *node = NULLP;
1108
1109    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1110  
1111    recBufLstCp = &recBufLst[hashKey];
1112    CM_LLIST_FIRST_NODE(recBufLstCp, node);
1113    while(node)
1114    {
1115       recBuf = (RlcAmRecBuf *) node->node;
1116       if(recBuf->amHdr.sn == sn)
1117       {
1118          return recBuf;
1119       }
1120       CM_LLIST_NEXT_NODE(recBufLstCp, node);
1121    }
1122    return NULLP;
1123 } /* rlcUtlStoreRecBuf */
1124 /**
1125  *
1126  * @brief Delete the UL buffer from the list
1127  *
1128  *
1129  * @Description
1130  *
1131  *   Use the SN % binSize as key and retrieve the UL buffer
1132  *  @param[in] recBufLst       List CP array
1133  *  @param[in] sn              sn of the received buffer 
1134  *
1135  *
1136  *  @return  Void
1137  */
1138 void rlcUtlDelRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcCb *gCb)
1139 {
1140    uint32_t                 hashKey; 
1141    CmLListCp           *recBufLstCp;
1142
1143    hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE ); 
1144  
1145    recBufLstCp = &recBufLst[hashKey];
1146    cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1147    RLC_FREE_WC(gCb, recBuf, sizeof(RlcAmRecBuf));
1148
1149    return;
1150 } /* rlcUtlDelRecBuf */
1151
1152
1153
1154
1155 /********************************************************************30**
1156          End of file
1157 **********************************************************************/