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