replaced cmMemSet, cmMemcpy with memset and memcpy resp AND Removed TRC() traces...
[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       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 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
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 U32                   ttiCnt
488 )
489 #else
490 Void rlcUtlCalUlIpThrPut(gCb, rbCb, pdu, ttiCnt)
491    RlcCb                  *gCb;
492    RlcUlRbCb              *rbCb;
493    Buffer                *pdu;
494    U32                   ttiCnt;
495 #endif
496 {
497    MsgLen        rlcSduSz = 0;  /*Holds length of Rlc Sdu*/
498    VOLATILE U32     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    U16             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    U32                     qciIdx;
604    RlcL2MeasCb              *measCb;
605    RlcL2MeasCfmEvt          measCfmEvt;
606
607    U64                     ulDataVol;
608    U64                     ulTime;
609    U16                     cntr;
610    /* Discard new changes starts */
611    U8                      qci = 0;
612    U32                     cfmIdx =0;
613    /* Discard new changes ends */
614
615    /* kw006.201 ccpu00120058 emoved 64 bit compilation warning */
616 #ifndef ALIGN_64BIT
617    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%ld))", measEvtCb->transId);
618 #else
619    RLOG1(L_DEBUG,"rlcUtlSndUlL2MeasCfm(transId(%d))", measEvtCb->transId);
620 #endif
621
622    /* Clean up the RB data structures */
623    measCb = &measEvtCb->measCb;
624    
625    memset(&measCfmEvt, 0, sizeof(RlcL2MeasCfmEvt));
626    measCfmEvt.transId = measEvtCb->transId;
627
628    measCfmEvt.measType = measCb->measType;
629    measCfmEvt.status.status = LCM_PRIM_OK;
630    measCfmEvt.status.reason = LCM_REASON_NOT_APPL;
631    
632    if( measCb->measType & LKW_L2MEAS_UL_IP)
633    {
634       RlcL2MeasCbUeMeasInfo *pUeInfoLstCb  = measCb->val.ipThMeas.ueInfoLst;
635       RlcL2MeasCfmUeInfoLst *pUeInfoLstCfm = measCfmEvt.val.ipThMeas.ueInfoLst;
636       for(cntr = 0;(cntr < measCb->val.ipThMeas.numUes) && (cntr < gCb->genCfg.maxUe);cntr++)        
637       {
638          pUeInfoLstCfm[cfmIdx].numCfm = 0;
639          if (pUeInfoLstCb[cntr].isValid == TRUE)
640          {
641             pUeInfoLstCfm[cfmIdx].ueId = pUeInfoLstCb[cntr].ueId;
642             pUeInfoLstCfm[cfmIdx].cellId = pUeInfoLstCb[cntr].cellId;
643
644             for(qciIdx = 0; qciIdx < pUeInfoLstCb[cntr].numQci; qciIdx++)
645             {
646                qci = pUeInfoLstCb[cntr].qci[qciIdx];
647                pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].qci = qci;
648
649                if(measCb->measType & LKW_L2MEAS_UL_IP)
650                {
651                   ulDataVol = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation;
652                   ulTime = pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation;
653                   if(0 == ulTime)
654                   {
655                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = 0;
656                   }
657                   else
658                   {
659                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut = (ulDataVol / ulTime);
660
661                      /* Converting it to kbps */
662                      pUeInfoLstCfm[cfmIdx].measCfm[pUeInfoLstCfm[cfmIdx].numCfm].val.ipThrput.ulIpThPut *= 8;
663
664                   }
665                   /* Reset the values after reporting to Application */
666                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.volSummation = 0;
667                   pUeInfoLstCb[cntr].measData[qci].ulIpThruput.timeSummation = 0;
668                }
669                pUeInfoLstCfm[cfmIdx].numCfm++;
670             }
671             cfmIdx++;
672          }
673       }
674       measCfmEvt.val.ipThMeas.numUes = cfmIdx; 
675    }
676    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, &measCfmEvt);
677    return (ROK);
678 } /* rlcUtlSndUlL2MeasCfm */
679 /**
680  *
681  * @brief Handler for Sending Negative confirm .
682  *
683  *
684   @b Description
685  *        This function is called when the l2 measurement cannot be started
686  *        This function sends  negative confirm for all the requests
687  *
688  * @param[in] gCb - RLC instance control block
689  * @param[in] measReqEvt    Measurement Req Structure
690  * @param[in] measCfmEvt  Confirmation to be sent to layer manager
691  *
692  *
693  *  @return  S16
694  *      -# ROK
695  */
696
697 #ifdef ANSI
698 S16 rlcUtlSndUlL2MeasNCfm
699 (
700 RlcCb           *gCb,
701 RlcL2MeasReqEvt *measReqEvt,
702 RlcL2MeasCfmEvt *measCfmEvt
703 )
704 #else
705 S16 rlcUtlSndUlL2MeasNCfm(gCb, measReqEvt, measCfmEvt)
706 RlcCb           *gCb;
707 RlcL2MeasReqEvt *measReqEvt;
708 RlcL2MeasCfmEvt *measCfmEvt;
709 #endif
710 {
711
712    RlcMiLkwL2MeasCfm(&gCb->genCfg.lmPst, measCfmEvt);
713    return ROK;
714 } /* kwUtlSndL2MeasNCfm */
715
716 #ifdef LTE_L2_MEAS_RLC
717 /**
718  * @brief  Validates the measurement request parameters. 
719  *
720  * @details
721  *
722  *     Function :rlcUtlValidateL2Meas 
723  *
724  *  @param[in]  measReqEvt L2 measurement request received from layer manager.
725  *  @param[out] measCfmEvt L2 measurement confirm to be prepared.
726  *  @param[out] lChId      List of LCh for the given Ue corresponding to QCIs
727                            given in measurement request.
728  *  @param[out] numLCh     Number of LCh in array lChId.
729  **/
730
731 #ifdef ANSI
732 S16 rlcUtlValidateL2Meas
733 (
734 RlcL2MeasReqEvt *measReqEvt,
735 RlcL2MeasCfmEvt *measCfmEvt,
736 CmLteLcId      *lChId,
737 U8             *numLCh
738 )
739 #else
740 S16 rlcUtlValidateL2Meas(measReqEvt, measCfmEvt, lChId, numLCh)
741 RlcL2MeasReqEvt *measReqEvt;
742 RlcL2MeasCfmEvt *measCfmEvt;
743 CmLteLcId      *lChId;
744 U8             *numLCh;
745 #endif
746 {
747    U8          measType;
748    S16         ret;
749    U8          qciIdx;
750    U8          qci;
751    U8          idx;
752    U8         *qciVal;
753    U8          numQci;
754    RlcUlRbCb  *rbCb;
755
756    RlcUlUeCb   *ueCb;
757    RbCb       **rbCbLst;
758    U8         rbIdx;
759    U8         lsbNibble = 0;
760    U8         msbNibble = 0;
761    U8         numFaild = 0;
762
763    idx = 0;
764    rbCb = NULLP;
765    ret = ROK;
766    measType = measReqEvt->measReq.measType;
767    /* Check for the range of measType */
768    /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
769    if((measType == 0x00) ||
770        measType > 0x30)
771    {
772       measCfmEvt->transId = measReqEvt->transId;
773       measCfmEvt->measType = measType;
774       measCfmEvt->status.status = LCM_PRIM_NOK;
775       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
776       return RFAILED;
777    }
778    /*User can either request for Active UE,*
779     *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
780    lsbNibble = measType & 0x0F;
781    msbNibble = measType & 0xF0;
782
783    if( (lsbNibble != 0) && (msbNibble != 0) )
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
792    /* Check for total maximum number of Measurement Control Block */
793    if(rlcCb.rlcL2Cb.rlcNumMeas >= LKW_MAX_L2MEAS )
794    {
795       measCfmEvt->transId = measReqEvt->transId;
796       measCfmEvt->measType = measType;
797       measCfmEvt->status.status = LCM_PRIM_NOK;
798       measCfmEvt->status.reason = LKW_CAUSE_EXCEED_NUMMEAS;
799       return RFAILED;
800    }
801
802    /* Check that number of samples should be a non-zero value */
803    if(((measType & LKW_L2MEAS_ACT_UE) &&
804       (measReqEvt->measReq.val.nonIpThMeas.numSamples == 0)))
805    {
806       measCfmEvt->transId = measReqEvt->transId;
807       measCfmEvt->measType = measType;
808       measCfmEvt->status.status = LCM_PRIM_NOK;
809       measCfmEvt->status.reason = LKW_CAUSE_ZERO_NUMSAM;
810       return RFAILED;
811    }
812    /* Check that measurement period  should be completely divisible *
813     * number of sample.                                             */
814    if(((measType & LKW_L2MEAS_ACT_UE) &&
815       ((measReqEvt->measPeriod % 
816         measReqEvt->measReq.val.nonIpThMeas.numSamples) != 0)))
817    {
818       measCfmEvt->transId = measReqEvt->transId;
819       measCfmEvt->measType = measType;
820       measCfmEvt->status.status = LCM_PRIM_NOK;
821       measCfmEvt->status.reason = LKW_CAUSE_INVALID_NUMSAM;
822       return RFAILED;
823    }
824    {
825       numQci = measReqEvt->measReq.val.nonIpThMeas.numQci;
826       qciVal = measReqEvt->measReq.val.nonIpThMeas.qci;
827    }
828    /* Check whether qci is configured or not */
829    for(qciIdx = 0; qciIdx < numQci; qciIdx++)
830    {
831       qci = qciVal[qciIdx];
832       ret = cmHashListFind(&(rlcCb.rlcL2Cb.qciHlCp), 
833             (U8 *)&qci, (U16)sizeof(qci), 0, (PTR *)&rbCb);
834       if(ret != ROK)
835       {
836          measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
837          measCfmEvt->val.nonIpThMeas.numCfm++;
838
839       }
840    }
841    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
842    {
843       measCfmEvt->status.status = LCM_PRIM_NOK;
844       measCfmEvt->status.reason = LKW_CAUSE_INVALID_QCI;
845       measCfmEvt->measType = measType;
846       measCfmEvt->transId = measReqEvt->transId;
847       return RFAILED;
848    }
849    {
850       for(qciIdx = 0; qciIdx < numQci; qciIdx++)
851       {
852          if(rlcCb.rlcL2Cb.measOn[qci] & measReqEvt->measReq.measType)
853          {
854             /* measurement is already ongoing */
855             measCfmEvt->status.status = LCM_PRIM_NOK;
856             measCfmEvt->status.reason = LKW_CAUSE_MEAS_ALREADY_ENA;
857             measCfmEvt->val.nonIpThMeas.measCfm[measCfmEvt->val.nonIpThMeas.numCfm].qci = qci;
858             measCfmEvt->measType = measType;
859             measCfmEvt->val.nonIpThMeas.numCfm++;
860          }
861       }
862    }
863    if(measCfmEvt->val.nonIpThMeas.numCfm > 0)
864    {
865       measCfmEvt->transId = measReqEvt->transId;
866       return RFAILED;
867    }
868
869    return (ROK);
870 }/* rlcUtlValidateL2Meas */
871 #endif
872
873 #ifdef ANSI
874 S16 rlcUtlValidateIpThL2Meas
875 (
876 RlcL2MeasReqEvt *measReqEvt,
877 RlcL2MeasCfmEvt *measCfmEvt
878 )
879 #else
880 S16 rlcUtlValidateIpThL2Meas(measReqEvt, measCfmEvt)
881 RlcL2MeasReqEvt *measReqEvt;
882 RlcL2MeasCfmEvt *measCfmEvt;
883 #endif
884 {
885    U8      measType;
886    U8         lsbNibble = 0;
887    U8         msbNibble = 0;
888
889    measType = measReqEvt->measReq.measType;
890    /* Check for the range of measType */
891    /* LKW_L2MEAS_DL_IP+ LKW_L2MEAS_UL_IP = 0x0030*/
892    if((measType == 0x00) ||
893        measType > 0x30)
894    {
895       measCfmEvt->transId = measReqEvt->transId;
896       measCfmEvt->measType = measType;
897       measCfmEvt->status.status = LCM_PRIM_NOK;
898       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
899       return RFAILED;
900    }
901    /*User can either request for Active UE,*
902     *Dl delay, Dl discard, Uu Loss OR Dl ip throughput, Ul ip throughput. */
903    lsbNibble = measType & 0x0F;
904    msbNibble = measType & 0xF0;
905
906    if( (lsbNibble != 0) && (msbNibble != 0) )
907    {
908       measCfmEvt->transId = measReqEvt->transId;
909       measCfmEvt->measType = measType;
910       measCfmEvt->status.status = LCM_PRIM_NOK;
911       measCfmEvt->status.reason = LKW_CAUSE_INVALID_MEASTYPE;
912       return RFAILED;
913    }
914    return (ROK);
915 }/* rlcUtlValidateL2Meas */
916
917 /**
918  *
919  * @brief Handler for resetting the RB data structures
920  *
921  *
922  * @b Description
923  *        This function resets the RB data structure after the expiry of 
924  *        measurement timer.
925  *
926  *  @param[in] measCb    Measurement Control Block.
927  *
928  *
929  *  @return  Void
930  */
931 #ifdef ANSI
932
933 Void rlcUtlResetUlL2MeasInRlcRb
934 (
935 RlcCb       *gCb,
936 RlcL2MeasCb *measCb,
937 U8             measType
938 )
939 #else
940 Void rlcUtlResetUlL2MeasInRlcRb(measCb, measType)
941 RlcCb       *gCb;
942 RlcL2MeasCb *measCb;
943 U8             measType;
944 #endif
945 {
946    U32           rbIdx;
947    U32           ueIdx;
948    U32           qciIdx;
949    RlcUlUeCb         *ueCb = NULL;
950
951
952
953    if (measCb->measType & LKW_L2MEAS_UL_IP)
954    {
955       for(ueIdx = 0; ueIdx < measCb->val.ipThMeas.numUes; ueIdx++)
956       {           
957          if (measCb->val.ipThMeas.ueInfoLst[ueIdx].isValid == TRUE)
958          {
959             for (qciIdx =0; qciIdx < measCb->val.ipThMeas.ueInfoLst[ueIdx].numQci; qciIdx++)
960             {
961                if (measType & LKW_L2MEAS_UL_IP)
962                {
963                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.volSummation = 0;
964                   measCb->val.ipThMeas.ueInfoLst[ueIdx].measData[qciIdx].ulIpThruput.timeSummation = 0;
965                }
966             }
967
968             if(ROK  != rlcDbmFetchUlUeCb(gCb, measCb->val.ipThMeas.ueInfoLst[ueIdx].ueId,
969                      measCb->val.ipThMeas.ueInfoLst[ueIdx].cellId, &ueCb))
970             {
971                continue;
972             }
973
974             for (rbIdx = 0; rbIdx < RLC_MAX_DRB_PER_UE; rbIdx++)
975             {
976                if (ueCb->drbCb[rbIdx])
977                {
978                   ueCb->drbCb[rbIdx]->rbL2Cb.measOn &= ~measType;
979                }
980             }
981          }
982       }
983    }
984 } /* rlcUtlResetUlL2MeasInRlcRb */
985
986 /**
987  *
988  * @brief Handler for storing address of MeasData in rbCb at right index
989  *
990  *
991  * @b Description
992  *        This function is called when LM sends measReq message to RLC.
993  *
994  *  @param[in] 
995  *  @param[out] 
996  *  @param[in] 
997  *
998  *
999  *  @return  S16
1000  *      -# ROK
1001  */
1002 #ifdef ANSI
1003 Void rlcUtlPlcMeasDatInL2Sts
1004 (
1005 RlcL2Cntr       *measData, 
1006 RlcL2MeasRbCb   *rbL2Cb,
1007 U8             measType
1008 )
1009 #else
1010 Void rlcUtlPlcMeasDatInL2Sts(measData, rbL2Cb, measType)
1011 RlcL2Cntr       *measData; 
1012 RlcL2MeasRbCb   *rbL2Cb;
1013 U8             measType;
1014 #endif
1015 {
1016    /* We should check the number of measType in the request. This can be done 
1017     * by looking at each bit in the measType. Also store the measData in the 
1018     * correct index of l2Sts in RbCb.
1019     * */
1020
1021     if(measType & LKW_L2MEAS_ACT_UE)
1022     {
1023          rbL2Cb->l2Sts[RLC_L2MEAS_ACT_UE] = measData;
1024     }
1025     if(measType & LKW_L2MEAS_UU_LOSS)
1026     {
1027          rbL2Cb->l2Sts[RLC_L2MEAS_UU_LOSS] = measData;
1028     }
1029     if(measType & LKW_L2MEAS_DL_IP )
1030     {
1031          rbL2Cb->l2Sts[RLC_L2MEAS_DL_IP] = measData;
1032     }
1033     if(measType & LKW_L2MEAS_UL_IP)
1034     {
1035          rbL2Cb->l2Sts[RLC_L2MEAS_UL_IP] = measData;
1036     }
1037     if(measType & LKW_L2MEAS_DL_DISC)
1038     {
1039          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DISC] = measData;
1040     }
1041     if(measType & LKW_L2MEAS_DL_DELAY)
1042     {
1043          rbL2Cb->l2Sts[RLC_L2MEAS_DL_DELAY] = measData;
1044     }
1045 }/* End of rlcUtlPlcMeasDatInL2Sts */
1046 #endif /* LTE_L2_MEAS */
1047
1048 /**
1049  *
1050  * @brief Store the UL buffer in hashList  
1051  *
1052  *
1053  * @b Description
1054  *
1055  *   Use the SN % binSize as key and store the received UL buffer
1056  *  @param[in] recBufLst       List CP array
1057  *  @param[in] recBuf          received buffer
1058  *  @param[in] sn              sn of the received buffer 
1059  *
1060  *
1061  *  @return  Void
1062  */
1063 void rlcUtlStoreRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcSn sn)
1064 {
1065    uint32_t    hashKey; 
1066    
1067    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1068    recBuf->lnk.node = (PTR)recBuf;
1069    cmLListAdd2Tail(&(recBufLst[hashKey]), &recBuf->lnk);
1070
1071    return;
1072 } /* rlcUtlStoreRecBuf */
1073
1074 /**
1075  *
1076  * @brief Retrieve the UL buffer from the list
1077  *
1078  *
1079  * @Description
1080  *
1081  *   Use the SN % binSize as key and retrieve the UL buffer
1082  *  @param[in] recBufLst       List CP array
1083  *  @param[in] sn              sn of the received buffer 
1084  *
1085  *
1086  *  @return  Void
1087  */
1088 RlcAmRecBuf* rlcUtlGetRecBuf(CmLListCp *recBufLst, RlcSn sn)
1089 {
1090    uint32_t            hashKey; 
1091    CmLListCp           *recBufLstCp;
1092    RlcAmRecBuf          *recBuf;
1093    CmLList             *node = NULLP;
1094
1095    hashKey = (sn % RLC_RCV_BUF_BIN_SIZE ); 
1096  
1097    recBufLstCp = &recBufLst[hashKey];
1098    CM_LLIST_FIRST_NODE(recBufLstCp, node);
1099    while(node)
1100    {
1101       recBuf = (RlcAmRecBuf *) node->node;
1102       if(recBuf->amHdr.sn == sn)
1103       {
1104          return recBuf;
1105       }
1106       CM_LLIST_NEXT_NODE(recBufLstCp, node);
1107    }
1108    return NULLP;
1109 } /* rlcUtlStoreRecBuf */
1110 /**
1111  *
1112  * @brief Delete the UL buffer from the list
1113  *
1114  *
1115  * @Description
1116  *
1117  *   Use the SN % binSize as key and retrieve the UL buffer
1118  *  @param[in] recBufLst       List CP array
1119  *  @param[in] sn              sn of the received buffer 
1120  *
1121  *
1122  *  @return  Void
1123  */
1124 void rlcUtlDelRecBuf(CmLListCp *recBufLst, RlcAmRecBuf *recBuf, RlcCb *gCb)
1125 {
1126    uint32_t                 hashKey; 
1127    CmLListCp           *recBufLstCp;
1128
1129    hashKey = (recBuf->amHdr.sn % RLC_RCV_BUF_BIN_SIZE ); 
1130  
1131    recBufLstCp = &recBufLst[hashKey];
1132    cmLListDelFrm(recBufLstCp, &recBuf->lnk);
1133    RLC_FREE_WC(gCb, recBuf, sizeof(RlcAmRecBuf));
1134
1135    return;
1136 } /* rlcUtlDelRecBuf */
1137
1138
1139
1140
1141 /********************************************************************30**
1142          End of file
1143 **********************************************************************/