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