Initial commit
[o-du/l2.git] / src / 5gnrmac / rg_l2m.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-MAC layer
22   
23      Type:     C source file
24   
25      Desc:     C source code for  L2 Measurements in MAC
26   
27      File:     rg_l2m.c
28   
29 **********************************************************************/
30
31 /** @file rg_l2m.c
32 @brief This file implements the schedulers main access to MAC layer code.
33 */
34
35 /* header include files -- defines (.h) */
36 #include "envopt.h"        /* environment options */
37 #include "envdep.h"        /* environment dependent */
38 #include "envind.h"        /* environment independent */
39 #include "gen.h"           /* general layer */
40 #include "ssi.h"           /* system service interface */
41 #include "cm_hash.h"       /* common hash list */
42 #include "cm_llist.h"      /* common linked list library */
43 #include "cm_err.h"        /* common error */
44 #include "cm_lte.h"        /* common LTE */
45 #include "lrg.h"
46 #include "crg.h"        
47 #include "rgr.h"
48 #include "rgu.h"           
49 #include "tfu.h"
50 #include "rg_env.h"
51 #include "rg_err.h"
52 #include "rg_sch_inf.h"
53 #include "rg.h"
54
55 /* header/extern include files (.x) */
56 #include "gen.x"           /* general layer typedefs */
57 #include "ssi.x"           /* system services typedefs */
58 #include "cm5.x"           /* common timers */
59 #include "cm_hash.x"       /* common hash list */
60 #include "cm_lib.x"        /* common library */
61 #include "cm_llist.x"      /* common linked list */
62 #include "cm_mblk.x"       /* memory management */
63 #include "cm_tkns.x"       /* common tokens */
64 #include "cm_lte.x"       /* common tokens */
65 #include "rgu.x"           /* RGU types */
66 #include "tfu.x"           /* TFU types */
67 #include "lrg.x"           /* layer management typedefs for MAC */
68 #include "rgr.x"           /* layer management typedefs for MAC */
69 #include "crg.x"           /* layer management typedefs for MAC */
70 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
71 #include "rg_prg.x"        /* typedefs for PRG interface */
72 #include "rg.x"            /* MAC types */
73
74 #ifdef LTE_L2_MEAS
75 static const char* RLOG_MODULE_NAME="MAC";
76 static int RLOG_FILE_ID=183;
77 static int RLOG_MODULE_ID=4096;
78 #endif 
79
80 /* local defines */
81 #ifdef LTE_L2_MEAS
82 PRIVATE S16 rgL2mInsertMeasCb ARGS((
83          RgCellCb       *cell,
84          RgL2MeasCb     *measCb,
85          RgInfL2MeasReq *measInfo ));
86
87 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb ARGS((
88          RgCellCb       *cell,
89          RgInfL2MeasReq *measInfo,
90          RgErrInfo      *err));
91
92 /* Function definitions */
93
94 /** @brief This function creates the measCb
95  *
96  * @details
97  *
98  *     Function: rgL2mCreateMeasCb
99  *         Processing steps:
100  *         - Check the measType
101  *         - Create measCb for every qci
102  *
103  * @param  [in] RgCellCb       *cell
104  * @param  [in] RgInfL2MeasReq *measInfo
105  * @param  [in] U8             measType
106  * @param  [out] RgErrInfo      *err
107  * @return  S16
108  *      -# ROK 
109  *      -# RFAILED 
110  *
111  */
112 #ifdef ANSI
113 PUBLIC S16 rgL2mCreateMeasCb 
114 (
115 RgCellCb       *cell,
116 RgInfL2MeasReq *measInfo, 
117 U8              measType,
118 RgErrInfo      *err
119 )
120 #else
121 PUBLIC S16 rgL2mCreateMeasCb(cell, measInfo, measType, err)
122 RgCellCb       *cell;
123 RgInfL2MeasReq *measInfo; 
124 U8              measType;
125 RgErrInfo      *err;
126 #endif    
127 {
128   // Inst    inst = cell->macInst - RG_INST_START;
129    U32     idx;
130    RgL2MeasCb       *measCb = NULLP;
131    U8            qciVal = 0;
132
133    UNUSED(measType);
134    UNUSED(err);
135
136    TRC3(rgL2mCreateMeasCb)
137
138       if ((measCb = rgL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
139       {
140          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"Allocation of RgL2MeasCb failed");
141          RETVALUE(RFAILED);
142       }
143    //Memcpy is already done in rgL2mAllocMeasCb
144    /*cmMemcpy((U8 *)&measCb->measReq, (CONSTANT U8 *)measInfo,\
145      sizeof(RgInfL2MeasReq));*/
146    rgL2mInsertMeasCb(cell, measCb, measInfo);
147    measCb->measReq.timePrd = measInfo->timePrd;
148
149    if(measInfo->timePrd == 0)
150    {
151       cell->sndL2Meas = FALSE;
152    }
153
154    for(idx = 0; idx < measInfo->t.prbReq.numQci; idx++)
155    {
156       if(measInfo->timePrd == 0)
157       {
158          qciVal = measInfo->t.prbReq.qci[idx];
159          cell->qciArray[qciVal].qci = qciVal;
160       }
161       cell->qciArray[measInfo->t.prbReq.qci[idx]].mask = TRUE;
162    }
163    RETVALUE(ROK);
164 } /* rgL2mCreateMeasCb */
165
166
167 /**
168  * @brief Layer Manager Measurement request handler. 
169  *
170  * @details
171  *
172  *     Function : rgL2mMeasReq
173  *     
174  *     This function handles  measurement request received at MAC
175  *     from the Scheduler.
176  *     -# Measurement request will be stored in the list in descending order of
177  *     there time period.
178  *     
179  *  @param[in]  Pst *pst, the post structure     
180  *  @param[in]  RgInfL2MeasReq *measInfo, the measurement request structure
181  *  @param[out] RgErrInfo   *err, error information
182  *  @return  S16
183  *      -# ROK
184  **/
185 #ifdef ANSI
186 PUBLIC S16 rgL2mMeasReq 
187 (
188 RgCellCb       *cell,
189 RgInfL2MeasReq *measInfo,
190 RgErrInfo      *err
191 )
192 #else
193 PUBLIC S16 rgL2mMeasReq(cell, measInfo, err)
194 RgCellCb       *cell;
195 RgInfL2MeasReq *measInfo; 
196 RgErrInfo      *err;
197 #endif    
198 {
199    S16  ret=RFAILED;
200
201    TRC3(rgL2mMeasReq)
202    /* Creaet MeasCb Insert in cell->l2mList and return*/
203    if ( (ret = rgL2mCreateMeasCb(cell, measInfo,
204                LRG_L2MEAS_AVG_PRB_PER_QCI_UL, err)) != ROK)
205    {
206       /* Clear Downlink MeasCb created Above If exists*/
207       RETVALUE(ret);
208    }
209    RETVALUE(ROK);
210 } /* rgL2mMeasReq */
211 /** @brief This function sends the measurement confirm
212  *  from mac to scheduler
213  *
214  * @details
215  *
216  *     Function: rgSndL2MeasCfm
217  *
218  * @param  [in] RgCellCb          *cell
219  * @param  [in] RgInfL2MeasCfm    *measCfm
220  */
221 #ifdef ANSI
222 PRIVATE Void rgSndL2MeasCfm
223 (
224 RgCellCb          *cell, 
225 RgInfL2MeasCfm    *measCfm
226 )
227 #else
228 PRIVATE Void rgSndL2MeasCfm (cell, measCfm)
229 RgCellCb          *cell; 
230 RgInfL2MeasCfm    *measCfm;   
231 #endif
232 {
233    Pst             pst;
234    Inst            macInst = cell->macInst - RG_INST_START;
235    TRC3(rgSndL2MeasCfm)
236
237       cmMemset((U8 *)&pst, 0, sizeof(Pst));
238    rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
239    RgMacSchL2Meas(&pst, measCfm);
240
241    RETVOID;
242 }/* rgSndL2MeasCfm */
243
244 /** @brief This function sends the measurement stop confirm
245  *  from mac to scheduler
246  *
247  * @details
248  *
249  *     Function: rgSndL2MeasStopCfm
250  *
251  * @param  [in] RgCellCb          *cell
252  * @param  [in] RgInfL2MeasCfm    *measCfm
253  */
254 #ifdef ANSI
255 PRIVATE Void rgSndL2MeasStopCfm
256 (
257 RgCellCb          *cell,
258 RgInfL2MeasCfm    *measCfm
259 )
260 #else
261 PRIVATE Void rgSndL2MeasStopCfm (cell, measCfm)
262 RgCellCb          *cell;
263 RgInfL2MeasCfm    *measCfm;
264 #endif
265 {
266    Pst             pst;
267    Inst            macInst = cell->macInst - RG_INST_START;
268
269    TRC3(rgSndL2MeasStopCfm)
270       cmMemset((U8 *)&pst, 0, sizeof(Pst));
271    rgGetPstToInst(&pst,macInst, cell->schInstMap.schInst);
272    RgMacSchL2MeasStop(&pst, measCfm);
273
274    RETVOID;
275 }/* rgSndL2MeasStopCfm */
276
277 /**
278  * @brief  L2 Measurement request handler.This function shall be called by
279  *  scheduler to calculate average PRB usage Per Qci in Uplink
280  *
281  * @details
282  *
283  *     Function : RgSchMacL2MeasReq
284  *     
285  *  @param[in]  Pst *pst, the post structure     
286  *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
287  *  @return  S16
288  *      -# ROK
289  *      -# RFAILED
290  **/
291 #ifdef ANSI
292 PUBLIC S16 RgSchMacL2MeasReq
293 (
294 Pst               *pst,          /* post structure  */
295 RgInfL2MeasReq    *measInfo      /* Meas Req Info */
296 )
297 #else
298 PUBLIC S16 RgSchMacL2MeasReq(pst, measInfo)
299 Pst               *pst;          /* post structure  */
300 RgInfL2MeasReq    *measInfo;      /* Meas Req Info */
301 #endif    
302 {
303    Inst            inst;
304    RgCellCb        *cellCb = NULLP;
305    RgErrInfo       err;
306    S16             ret = ROK;
307    RgInfL2MeasCfm   measCfm;
308
309    TRC3(RgSchMacL2MeasReq)
310
311
312    RG_IS_INST_VALID(pst->dstInst);
313    inst   = pst->dstInst - RG_INST_START;
314    cellCb = rgCb[inst].cell;
315    /* Get the  cell using cellId */
316    if ((cellCb == NULLP) ||
317        (cellCb->cellId != measInfo->cellId))
318    {
319       RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,"unable to get the cellCb");
320       RETVALUE(RFAILED);
321    }
322    /* Call L2M Function to store Meas req */
323    ret = rgL2mMeasReq(cellCb, measInfo, &err);
324    if (ret != ROK)
325    {
326       cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
327       measCfm.transId     = measInfo->transId;
328       measCfm.cellId      = measInfo->cellId;
329       measCfm.measType    = measInfo->measType;
330       measCfm.cfm.reason   = LCM_REASON_INVALID_PAR_VAL;
331       measCfm.cfm.status  = LCM_PRIM_NOK;
332       rgSndL2MeasCfm(cellCb, &measCfm);
333       RLOG_ARG2(L_ERROR,DBG_CELLID,measInfo->cellId,
334                "Meas req Failed  errType(%d) errCause(%d)",
335                err.errType, err.errCause);
336       RETVALUE(RFAILED);
337    }
338    RETVALUE(ret);
339 } /* -- RgSchMacL2MeasReq-- */
340
341 /**
342  * @brief  L2 Measurement request handler.This function shall be called by
343  *         sch to to stop l2 measurement in MAC,
344  *
345  * @details
346  *
347  *     Function : RgSchMacL2MeasStopReq
348  *     
349  *  @param[in]  Pst *pst, the post structure     
350  *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
351  *  @return  S16
352  *      -# ROK
353  *      -# RFAILED
354  **/
355 #ifdef ANSI
356 PUBLIC S16 RgSchMacL2MeasStopReq
357 (
358 Pst               *pst,          /* post structure  */
359 RgInfL2MeasStopReq *measInfo      /* Meas Req Info */
360 )
361 #else
362 PUBLIC S16 RgSchMacL2MeasStopReq(pst, measInfo)
363 Pst               *pst;          /* post structure  */
364 RgInfL2MeasStopReq *measInfo;      /* Meas Req Info */
365 #endif
366 {
367    S16             ret = ROK;   
368    CmLList         *node   = NULLP;
369    RgL2MeasCb      *measCb = NULLP;
370    U8               idx;
371    U8               qciVal;
372    Inst             inst;
373    RgCellCb        *cellCb = NULLP;
374
375    RgInfL2MeasCfm  measCfm;
376
377    TRC3(RgSchMacL2MeasStopReq)
378
379
380    RG_IS_INST_VALID(pst->dstInst);
381    inst   = pst->dstInst - RG_INST_START;
382    cellCb = rgCb[inst].cell;
383       /* Get the  cell using cellId */
384    if ((cellCb == NULLP) ||
385        (cellCb->cellId != measInfo->cellId))
386    {
387       
388       RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
389             "Unable to get the cellCb");
390       RETVALUE(RFAILED);
391    }
392    node = cellCb->l2mList.first; 
393    while(node != NULLP)
394    {
395       measCb = (RgL2MeasCb *)(node)->node;
396       node = (node)->next;
397       /*L2 Meas off for qci in cell */
398       for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
399       {
400          qciVal = measCb->measReq.t.prbReq.qci[idx];
401          cellCb->qciArray[qciVal].mask = FALSE;
402       }
403       cmLListDelFrm(&cellCb->l2mList, &measCb->measLnk);
404       rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
405    }
406    cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
407    measCfm.transId     = measInfo->transId;
408    measCfm.cellId      = measInfo->cellId;
409    measCfm.measType    = measInfo->measType;
410    measCfm.cfm.status  = LCM_PRIM_OK;
411    rgSndL2MeasStopCfm(cellCb, &measCfm);
412    RETVALUE(ret);
413 } /* -- RgSchMacL2MeasStopReq-- */
414
415 /**
416  * @brief  L2 Measurement request handler.This function shall be called by
417  *  scheduler for  sending L2 meas 
418  *
419  * @details
420  *
421  *     Function : RgSchMacL2MeasSendReq
422  *     
423  *  @param[in]  Pst *pst, the post structure     
424  *  @param[in]  RgInfL2MeasReq *measInfo, L2 Measurement req structure
425  *  @return  S16
426  *      -# ROK
427  *      -# RFAILED
428  **/
429 #ifdef ANSI
430 PUBLIC S16 RgSchMacL2MeasSendReq
431 (
432 Pst               *pst,          /* post structure  */
433 RgInfL2MeasSndReq *measInfo      /* Meas Req Info */
434 )
435 #else
436 PUBLIC S16 RgSchMacL2MeasSendReq(pst, measInfo)
437 Pst               *pst;          /* post structure  */
438 RgInfL2MeasSndReq *measInfo;      /* Meas Req Info */
439 #endif
440 {
441    Inst            inst;
442    RgCellCb       *cellCb = NULLP;
443    S16             ret    = ROK;
444
445    TRC3(RgSchMacL2MeasSendReq)
446
447
448    RG_IS_INST_VALID(pst->dstInst);
449    inst   = pst->dstInst - RG_INST_START;
450    cellCb = rgCb[inst].cell;
451       /* Get the  cell using cellId */
452    if ((cellCb == NULLP) ||
453        (cellCb->cellId != measInfo->cellId))
454    {
455       
456       RLOG_ARG0(L_ERROR,DBG_CELLID,measInfo->cellId,
457             "Unable to get the cellCb");
458       RETVALUE(RFAILED);
459    }
460    /*set sndL2Meas as applicatoin sent l2 meas info request*/
461    cellCb->sndL2Meas = TRUE;
462
463    RETVALUE(ret);
464 }/*RgSchMacL2MeasSendReq*/ 
465
466 /** @brief This function inserts the MeasCb in to data base
467  *
468  * @details
469  *
470  *     Function: rgL2mInsertMeasCb
471  *
472  * @param  [in] RgCellCb       *cell
473  * @param  [in] RgL2MeasCb     *measCb
474  * @param  [in] RgInfMeasReq   *measInfo
475  * @return  S16
476  *      -# ROK 
477  *      -# RFAILED 
478  */
479 #ifdef ANSI
480 PRIVATE S16 rgL2mInsertMeasCb
481 (
482 RgCellCb       *cell,
483 RgL2MeasCb     *measCb,
484 RgInfL2MeasReq *measInfo
485 )
486 #else
487 PRIVATE S16 rgL2mInsertMeasCb(cell, measCb, measInfo)
488 RgCellCb       *cell;
489 RgL2MeasCb     *measCb;
490 RgInfL2MeasReq *measInfo;
491 #endif
492 {
493    CmLList   *lnk, *node;
494    RgL2MeasCb  *oldMeasCb;
495    U16         diffTime;
496
497    TRC3(rgL2mInsertMeasCb)
498
499       /* 
500        * 1. Check if l2mList has any entries.
501        * 2. If yes 
502        *       1. Take the first entrie's time period and find the diff with
503        *       cell->crntTime.
504        *       2. If the diff is > measInfo->timePeriod then insert before this
505        *       entry.
506        *       3. Else take the next entry in list
507        *       4. If reached without adding to list . Append at the end of list.
508        * 3. If no entries in l2mList add at the first.
509        */
510       lnk = cell->l2mList.first;
511
512    node = &measCb->measLnk;
513    node->node = (PTR)measCb;
514    while(lnk != NULLP )
515    {
516       oldMeasCb = (RgL2MeasCb *)lnk->node;
517       diffTime = (oldMeasCb->measReq.timePrd - 
518             (RG_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
519       if (diffTime > measInfo->timePrd)
520       {
521          cell->l2mList.crnt = lnk;
522          cmLListInsCrnt(&(cell->l2mList), node);
523          RETVALUE(ROK);
524       }
525       else
526       {
527          lnk = lnk->next;
528       }
529    }  /* End of While */
530
531    cmLListAdd2Tail(&(cell->l2mList), node);
532    RETVALUE(ROK);
533 } /* rgL2mInsertMeasCb */
534
535 /** @brief This function allocates memory from the heap
536  *
537  * @details
538  *
539  *     Function: rgL2mAllocMeasCb
540  *
541  * @param  [in] RgCellCb       *cell
542  * @param  [in] RgInfL2MeasReq *measInfo
543  * @param  [out] RgErrInfo      *err
544  * @return  RgSchL2MeasCb *
545  */
546 #ifdef ANSI
547 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb
548 (
549 RgCellCb       *cell,
550 RgInfL2MeasReq *measInfo,
551 RgErrInfo      *err
552 )
553 #else
554 PRIVATE RgL2MeasCb * rgL2mAllocMeasCb(cell, measInfo, err)
555 RgCellCb       *cell;
556 RgInfL2MeasReq *measInfo;
557 RgErrInfo      *err;
558 #endif
559 {
560    RgL2MeasCb       *measCb = NULLP;
561    Inst             inst = cell->macInst - RG_INST_START;
562
563    TRC3(rgL2mAllocMeasCb)
564
565       if((rgAllocSBuf(inst,(Data **)&(measCb),
566                   sizeof(RgL2MeasCb))) == RFAILED)
567       {
568          RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,
569                    "Allocation of RgL2MeasCb failed");
570          err->errType  = RGERR_L2M_MEASREQ;
571          err->errCause = RGERR_RAM_MEM_EXHAUST;
572          RETVALUE(NULLP);
573       }
574    cmMemcpy((U8 *)&measCb->measReq, (U8 *)measInfo, sizeof(RgInfL2MeasReq));
575    RGCPYTIMEINFO(cell->crntTime, measCb->startTime);
576
577    RETVALUE(measCb);
578 } /* rgL2mAllocMeasCb */
579
580
581 /**
582  * @brief This function calculates the measurement for measType 
583  * LRG_L2MEAS_AVG_PRB_PER_QCI_UL and send the end result to the 
584  * MAC Scheduler.
585  *
586  * @details
587  *
588  *  Function : rgL2Meas
589  *     
590  *  @param[in] RgCellCb  *cell
591  *  @return  S16
592  *      -# ROK
593  *      -# RFAILED
594  **/
595 #ifdef ANSI
596 PUBLIC S16 rgL2Meas
597 (
598 RgCellCb  *cell
599 )
600 #else
601 PUBLIC S16 rgL2Meas(cell)
602 RgCellCb  *cell;
603 #endif
604 {
605    CmLList         *node   = NULLP;
606    RgL2MeasCb      *measCb = NULLP;
607    RgInfL2MeasCfm  measCfm;
608    U8              idx = 0;
609    U8              qciVal = 0;
610    U32             measPrd; /*LTE_L2_MEAS_PHASE2*/
611    CmLteTimingInfo  crntTime;
612    Inst           inst = cell->macInst - RG_INST_START;
613    
614    TRC3(rgL2Meas)
615
616    node = cell->l2mList.first;
617
618    while(node != NULLP)
619    {
620       measCb = (RgL2MeasCb *)node->node;
621       node = node->next;
622       crntTime = cell->crntTime;
623
624       if(cell->crntTime.sfn == 0 && (cell->crntTime.subframe % RG_NUM_SUB_FRAMES) == 0)
625       {
626          measCb->sfnCycle++;
627       }
628
629       measPrd = RG_CALC_SFN_SF_DIFF(cell->crntTime, 
630                         measCb->sfnCycle, measCb->startTime);
631       
632       /*LTE_L2_MEAS_PHASE2*/
633       if (cell->sndL2Meas || measPrd == measCb->measReq.timePrd)
634       {
635          cmMemset((U8 *)&measCfm, 0, sizeof(RgInfL2MeasCfm));
636          for(idx = 0; idx < measCb->measReq.t.prbReq.numQci; idx++)
637          {
638             qciVal = measCb->measReq.t.prbReq.qci[idx];
639             measCfm.u.prbCfm.prbUsage[idx].qciValue = qciVal;
640
641             measCfm.transId  = measCb->measReq.transId;
642             measCfm.measType = measCb->measReq.measType;
643             measCfm.cellId    = measCb->measReq.cellId;
644
645             measCfm.u.prbCfm.prbUsage[idx].prbUsage = 
646                cell->qciArray[qciVal].prbCount;
647
648             cell->qciArray[qciVal].prbCount = 0;
649             measCfm.u.prbCfm.numQci++;
650             if(measCb->measReq.timePrd > 0)
651             {
652                cell->qciArray[qciVal].mask = FALSE;
653             }
654          }
655          rgSndL2MeasCfm(cell, &measCfm);
656
657          if(measCb->measReq.timePrd > 0) 
658          {
659             cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
660             rgFreeSBuf(inst,(Data**)&measCb, sizeof(RgL2MeasCb));
661          }
662          else /*if meas period is 0 then do not delette meascb , just reset l2 cntrs value to 0*/
663          { 
664             measCb->startTime = crntTime;
665             measCb->measReq.timePrd = 0;
666             cell->sndL2Meas = FALSE;
667          }
668          continue;
669       } 
670    }
671    RETVALUE(ROK);
672 } /* rgL2MEas */
673
674 #endif /* LTE_L2_MEAS */
675 /**********************************************************************
676  
677          End of file
678 **********************************************************************/