Moving all common header file into common_def.h file
[o-du/l2.git] / src / 5gnrsch / rg_sch_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 Measurement fucntions
26   
27      File:     rg_sch_l2m.c
28   
29 **********************************************************************/
30
31 /** @file rg_sch_l2m.c
32 @brief This file implements the L2 Measurement feature code.
33 */
34
35 /* header include files -- defines (.h) */
36 #include "common_def.h"
37 #include "lrg.h"
38 #include "rgr.h"
39 #include "rgm.h"
40 #include "tfu.h"
41 #include "rg_env.h"
42 #include "rg_sch.h"
43 #include "rg_sch_cmn.h"
44 #include "rg_sch_inf.h"         /* typedefs for Scheduler */
45 #include "rg_sch_err.h"
46 #include "rl_interface.h"
47 #include "rl_common.h"
48
49 /* header/extern include files (.x) */
50 #include "tfu.x"           /* TFU types */
51 #include "lrg.x"           /* layer management typedefs for MAC */
52 #include "rgr.x"           /* layer management typedefs for MAC */
53 #include "rgm.x"           /* layer management typedefs for MAC */
54 #include "rg_sch_inf.x"    /* typedefs for Scheduler */
55 #include "rg_sch.x"        /* typedefs for Scheduler */
56 #include "rg_sch_cmn.x"    /* typedefs for Scheduler */
57 /* local defines */
58 U32 dlPrbCnt;
59 #ifdef LTE_L2_MEAS
60
61 static const char* RLOG_MODULE_NAME="MAC";
62 static int RLOG_MODULE_ID=4096;
63 static int RLOG_FILE_ID=166;
64
65 PRIVATE S16 rgSchL2mInsertMeasCb ARGS((
66          RgSchCellCb       *cell,
67          RgSchL2MeasCb     *measCb,
68          LrgSchMeasReqInfo *measInfo ));
69
70 PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb ARGS((
71          RgSchCellCb       *cell,
72          LrgSchMeasReqInfo *measInfo,
73          RgSchErrInfo      err));
74
75 /* Function definitions */
76
77 /** @brief This function fills the L2 measurement confirm structure
78  *
79  * @details
80  *
81  *     Function: rgSchFillL2MeasCfm
82  *
83  * @param  [in] RgSchCellCb *cell 
84  * @param  [in] RgSchL2MeasCb *measCb
85  * @param  [out] LrgSchMeasCfmInfo *measCfm
86  * @param  [in] measTime
87  * @return  Void
88  */
89 #ifdef ANSI
90 PUBLIC S16 rgSchFillL2MeasCfm
91 (
92 RgSchCellCb       *cell,
93 RgSchL2MeasCb     *measCb,
94 LrgSchMeasCfmInfo *cfm,
95 U32               measTime   
96 )
97 #else
98 PUBLIC S16 rgSchFillL2MeasCfm(cell, measCb, cfm, measTime)
99 RgSchCellCb       *cell;
100 RgSchL2MeasCb     *measCb;
101 LrgSchMeasCfmInfo *cfm;
102 U32               measTime;
103 #endif
104 {
105    U8                 idx;
106    LrgSchMeasReqInfo  *measInfo;
107    U8                 qciVal = 0;
108    U32                 sampOc = 0;
109
110    TRC3(rgSchFillL2MeasCfm)
111    
112    measInfo = &measCb->measReq;   
113
114    cfm->hdr.transId  = measInfo->hdr.transId;
115    cfm->measType     = measInfo->measType;
116    cfm->cellId       = measInfo->cellId;
117    cfm->cfm.status   = LCM_PRIM_OK;
118    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_DL) &&
119                                     (measCb->dlTotalBw))
120    {
121        cfm->avgPrbDl.prbPerc = ((cell->avgPrbDl.prbCount * 100) /
122                                  measCb->dlTotalBw);
123        /* Resetting the prbCount to 0,  fix for ccpu00125002 */
124        cell->avgPrbDl.prbCount = 0;
125    }
126    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL) &&
127                                     (measCb->ulTotalBw))
128    {
129        cfm->avgPrbUl.prbPerc = ((cell->avgPrbUl.prbCount * 100) /
130                                  measCb->ulTotalBw);
131        /* Resetting the prbCount to 0,  fix for ccpu00125002 */
132        cell->avgPrbUl.prbCount = 0;
133    }
134    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL) &&
135                                     (measCb->dlTotalBw))
136    {
137        cfm->avgPrbQciDlCfm.numQci = measCb->measReq.avgPrbQciDl.numQci;
138        for(idx = 0; idx < measCb->measReq.avgPrbQciDl.numQci; idx++)
139        {
140           qciVal = measCb->measReq.avgPrbQciDl.qci[idx];
141           cfm->avgPrbQciDlCfm.prbPercQci[idx].prbPercQci = 
142           ((cell->qciArray[qciVal].dlPrbCount * 100) /
143             measCb->dlTotalBw);
144             cfm->avgPrbQciDlCfm.prbPercQci[idx].qciValue = qciVal;
145           cell->qciArray[qciVal].dlPrbCount = 0;
146        }
147    }
148    if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL) && 
149                                     (measCb->ulTotalBw))
150    {
151        cfm->avgPrbQciUlCfm.numQci = measCb->measReq.avgPrbQciUl.numQci;
152        for(idx = 0; idx < measCb->measReq.avgPrbQciUl.numQci; idx++)
153        {
154           cfm->avgPrbQciUlCfm.prbPercQci[idx].qciValue = 
155                                  measCb->avgPrbQciUl.prbUsage[idx].qciValue;
156
157           if(measCb->avgPrbQciUl.prbUsage[idx].prbUsage > measCb->ulTotalBw)
158           {
159              measCb->avgPrbQciUl.prbUsage[idx].prbUsage = measCb->ulTotalBw;
160           }   
161
162           cfm->avgPrbQciUlCfm.prbPercQci[idx].prbPercQci = 
163              ((measCb->avgPrbQciUl.prbUsage[idx].prbUsage * 100) /
164                measCb->ulTotalBw);
165        }
166    }
167    if(measCb->measReq.measType & LRG_L2MEAS_RA_PREAMBLE)
168    {
169        cfm->raPrmbsCfm.dedPreambles        = cell->raPrmbs.dedPream;
170        cfm->raPrmbsCfm.randSelPreLowRange  = cell->raPrmbs.preamGrpA;
171        cfm->raPrmbsCfm.randSelPreHighRange = cell->raPrmbs.preamGrpB;
172        cell->raPrmbs.dedPream              = 0;
173        cell->raPrmbs.preamGrpA             = 0;
174        cell->raPrmbs.preamGrpB             = 0;
175    }
176    if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL)
177    {
178        cfm->numUeQciDlCfm.numQci = measInfo->nmbActvUeQciDl.numQci;
179        sampOc = (measTime / measInfo->nmbActvUeQciDl.sampPrd);
180        
181        if(sampOc)
182        {   
183           if (measCb->measReq.nmbActvUeQciDl.numQci)
184           {
185              for(idx = 0; idx < measCb->measReq.nmbActvUeQciDl.numQci; idx++)
186              {
187                 qciVal = measCb->measReq.nmbActvUeQciDl.qci[idx];
188                 /* L2_COUNTERS */
189                 cell->qciArray[qciVal].dlTotal_UeCount +=
190                    cell->qciArray[qciVal].dlUeCount;
191                 cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci =
192                    cell->qciArray[qciVal].dlTotal_UeCount / sampOc;
193                 cfm->numUeQciDlCfm.numActvUeQci[idx].qciValue = qciVal;
194                 
195                 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
196                       "L2_MEAS:CFM DL QCI %u TOTAL Count %lu Active UE %d ",
197                       qciVal,cell->qciArray[qciVal].dlTotal_UeCount,
198                       cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci);
199                 
200                 cell->qciArray[qciVal].dlTotal_UeCount = 0;
201              }
202           }
203           else
204           {
205              idx = 0;
206              for(qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
207              {
208                 /* L2_COUNTERS */
209                 cell->qciArray[qciVal].dlTotal_UeCount +=
210                    cell->qciArray[qciVal].dlUeCount;
211                 if (cell->qciArray[qciVal].dlTotal_UeCount)
212                 {
213                    cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci =
214                       cell->qciArray[qciVal].dlTotal_UeCount / sampOc;
215                    cfm->numUeQciDlCfm.numActvUeQci[idx].qciValue = qciVal;
216
217                    RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
218                          "L2_MEAS:CFM DL QCI %u TOTAL Count %lu Active UE %d ",
219                          qciVal,cell->qciArray[qciVal].dlTotal_UeCount,
220                          cfm->numUeQciDlCfm.numActvUeQci[idx].numActvUeQci);
221
222                    cell->qciArray[qciVal].dlTotal_UeCount = 0;
223                    idx++;
224                 }
225              }
226              cfm->numUeQciDlCfm.numQci = idx;
227           }
228        }
229    }
230    if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL)
231    {
232        cfm->numUeQciUlCfm.numQci = measInfo->nmbActvUeQciUl.numQci;
233        sampOc = (measTime / measInfo->nmbActvUeQciUl.sampPrd);
234        
235        
236        if(sampOc)
237        {   
238           if (measCb->measReq.nmbActvUeQciUl.numQci)
239           {
240              for(idx = 0; idx < measCb->measReq.nmbActvUeQciUl.numQci; idx++)
241              {
242                 cell->qciArray[qciVal].ulTotal_UeCount +=
243                    cell->qciArray[qciVal].ulUeCount;
244                 qciVal = measCb->measReq.nmbActvUeQciUl.qci[idx]; 
245                 cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci =
246                    cell->qciArray[qciVal].ulTotal_UeCount/ sampOc;
247                 cfm->numUeQciUlCfm.numActvUeQci[idx].qciValue = qciVal;
248                 
249                 RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
250                       "L2_MEAS:CFM UL QCI %d TOTAL Count %lu Active UE %d ",
251                       qciVal,cell->qciArray[qciVal].ulTotal_UeCount,
252                       cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci);
253                 
254                 cell->qciArray[qciVal].ulTotal_UeCount = 0;
255              }
256           }
257           else
258           {
259              idx = 0;
260              for(qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
261              {
262                 cell->qciArray[qciVal].ulTotal_UeCount +=
263                    cell->qciArray[qciVal].ulUeCount;
264                 if (cell->qciArray[qciVal].ulTotal_UeCount)
265                 {
266                    cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci =
267                       cell->qciArray[qciVal].ulTotal_UeCount/ sampOc;
268                    cfm->numUeQciUlCfm.numActvUeQci[idx].qciValue = qciVal;
269
270                    RLOG_ARG3(L_DEBUG,DBG_CELLID,cell->cellId,
271                          "L2_MEAS:CFM UL QCI %d TOTAL Count %lu Active UE %d ",
272                          qciVal,cell->qciArray[qciVal].ulTotal_UeCount,
273                          cfm->numUeQciUlCfm.numActvUeQci[idx].numActvUeQci);
274
275                    cell->qciArray[qciVal].ulTotal_UeCount = 0;
276                    idx++;
277                 }
278              }
279              cfm->numUeQciUlCfm.numQci = idx;
280           }
281        }
282    }
283    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_DL_COUNT)
284    {
285       cfm->tbTransDlTotalCnt = cell->dlUlTbCnt.tbTransDlTotalCnt;
286       cell->dlUlTbCnt.tbTransDlTotalCnt = 0;
287    }   
288    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_DL_FAULTY_COUNT)
289    {
290       cfm->tbTransDlFaulty = cell->dlUlTbCnt.tbTransDlFaulty;
291       cell->dlUlTbCnt.tbTransDlFaulty = 0;
292    }   
293    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_UL_COUNT)
294    {
295       cfm->tbTransUlTotalCnt = cell->dlUlTbCnt.tbTransUlTotalCnt;
296       cell->dlUlTbCnt.tbTransUlTotalCnt = 0;
297    }   
298    if(measCb->measReq.measType & LRG_L2MEAS_TB_TRANS_UL_FAULTY_COUNT)
299    {
300       cfm->tbTransUlFaulty = cell->dlUlTbCnt.tbTransUlFaulty;
301       cell->dlUlTbCnt.tbTransUlFaulty = 0;
302    }
303
304    measCb->dlTotalBw = 0;
305    measCb->ulTotalBw = 0;
306
307    RETVALUE(ROK);
308 } /* rgSchFillL2MeasCfm */
309
310 /** @brief This function sends the L2 measurement confirm to LM 
311  * from Shceduler
312  *
313  * @details
314  *
315  *     Function: rgSchL2mSndCfm
316  *
317  * @param  [in] Pst   *pst
318  * @param  [in] RgSchL2MeasCb *measCb
319  * @param  [in] Bool     isErr
320  * @return  Void
321  */
322 #ifdef ANSI
323 PUBLIC S16 rgSchL2mSndCfm
324 (
325 Pst               *pst,
326 RgSchL2MeasCb     *measCb,
327 LrgSchMeasReqInfo *measInfo,
328 Bool              isErr
329 )
330 #else
331 PUBLIC S16 rgSchL2mSndCfm(pst, measCb, measInfo, isErr)
332 Pst               *pst;
333 RgSchL2MeasCb     *measCb;
334 LrgSchMeasReqInfo *measInfo;
335 Bool              isErr;
336 #endif
337 {
338    LrgSchMeasCfmInfo   cfm;
339
340    TRC3(rgSchL2mSndCfm)
341
342    cmMemset((U8 *)&cfm, (U8)0, sizeof(LrgSchMeasCfmInfo));
343    cfm.hdr.transId  = measInfo->hdr.transId;
344    cfm.measType     = measInfo->measType;
345    cfm.cellId       = measInfo->cellId;
346    cfm.cfm.status   = LCM_PRIM_OK;
347    if(isErr == TRUE)
348    {
349       cfm.cfm.status   = LCM_PRIM_NOK;
350       cfm.cfm.reason   = LCM_REASON_INVALID_PAR_VAL;
351       RgMiLrgSchL2MeasCfm(pst, &cfm);
352       RETVALUE(ROK);
353    }
354    RETVALUE(ROK);
355 } /* rgSchL2mSndCfm */
356
357 /** @brief This function fills the LM confirmation pst structure 
358  *
359  * @details
360  *
361  *     Function: rgSchL2mFillCfmPst
362  *
363  * @param  [in] Pst    *pst
364  * @param  [out] Pst    *cfmPst
365  * @param  [in] LrgSchMeasReqInfo *measInfo
366  * @return  Void
367  */
368 #ifdef ANSI
369 PUBLIC Void rgSchL2mFillCfmPst
370 (
371 Pst    *pst,
372 Pst    *cfmPst,
373 LrgSchMeasReqInfo *measInfo 
374 )
375 #else
376 PUBLIC Void rgSchL2mFillCfmPst(pst, cfmPst, measInfo)
377 Pst    *pst;
378 Pst    *cfmPst;
379 LrgSchMeasReqInfo *measInfo;
380 #endif
381 {
382  
383
384    TRC3(rgSchL2mFillCfmPst)
385
386
387    cfmPst->srcEnt    = pst->dstEnt;
388    cfmPst->srcInst   = pst->dstInst;
389    cfmPst->srcProcId = pst->dstProcId;
390    cfmPst->dstEnt    = pst->srcEnt;
391    cfmPst->dstInst   = pst->srcInst;
392    cfmPst->dstProcId = pst->srcProcId;
393
394    cfmPst->selector  = measInfo->hdr.response.selector;
395    cfmPst->prior     = measInfo->hdr.response.prior;
396    cfmPst->route     = measInfo->hdr.response.route;
397    cfmPst->region    = measInfo->hdr.response.mem.region;
398    cfmPst->pool      = measInfo->hdr.response.mem.pool;
399
400    RETVOID;
401 } /* rgSchL2mFillCfmPst */
402
403 /** @brief This function inserts the MeasCb in to data base
404  *
405  * @details
406  *
407  *     Function: rgSchL2mInsertMeasCb
408  *
409  * @param  [in] RgSchCellCb       *cell
410  * @param  [in] RgSchL2MeasCb     *measCb
411  * @param  [in] LrgSchMeasReqInfo *measInfo
412  * @return  S16
413  *      -# ROK 
414  *      -# RFAILED 
415  */
416 #ifdef ANSI
417 PRIVATE S16 rgSchL2mInsertMeasCb
418 (
419 RgSchCellCb       *cell,
420 RgSchL2MeasCb     *measCb,
421 LrgSchMeasReqInfo *measInfo
422 )
423 #else
424 PRIVATE S16 rgSchL2mInsertMeasCb(cell, measCb, measInfo)
425 RgSchCellCb       *cell;
426 RgSchL2MeasCb     *measCb;
427 LrgSchMeasReqInfo *measInfo;
428 #endif
429 {
430    CmLList   *lnk, *node;
431    RgSchL2MeasCb   *oldMeasCb;
432    U32              diffTime;
433    
434    TRC3(rgSchL2mInsertMeasCb)
435    /* 
436     * 1. Check if l2mList has any entries.
437     * 2. If yes 
438     *       1. Take the first entrie's time period and find the diff with
439     *       cell->crntTime.
440     *       2. If the diff is > measInfo->timePeriod then insert before this
441     *       entry.
442     *       3. Else take the next entry in list
443     *       4. If reached without adding to list . Append at the end of list.
444     * 3. If no entries in l2mList add at the first.
445     */
446    lnk = cell->l2mList.first;
447    node = &measCb->measLnk;
448    node->node = (PTR)measCb;
449    while(lnk != NULLP )
450    {
451       oldMeasCb = (RgSchL2MeasCb *)lnk->node;
452       diffTime = (oldMeasCb->measReq.timePrd - 
453                  (RGSCH_CALC_SF_DIFF(cell->crntTime, oldMeasCb->startTime)));
454       if (diffTime > measInfo->timePrd)
455       {
456          cell->l2mList.crnt = lnk;
457          cmLListInsCrnt(&(cell->l2mList), node);
458          RETVALUE(ROK);
459       }
460       else
461       {
462          lnk = lnk->next;
463       }
464    }  /* End of While */
465    cmLListAdd2Tail(&(cell->l2mList), node);
466    RETVALUE(ROK);
467 } /* rgSchL2mInsertMeasCb */
468
469 /** @brief This function calculates the Down link prb count 
470  * for a DlSf
471  *
472  * @details
473  *
474  *     Function: rgSchL2CalDlPrbCount
475  *
476  * @param  [in] RgSchCellCb       *cell
477  */
478 #ifdef ANSI
479 PRIVATE Void rgSchL2CalDlPrbCount
480 (
481 RgSchCellCb       *cell
482 )
483 #else
484 PRIVATE Void rgSchL2CalDlPrbCount(cell)
485 RgSchCellCb       *cell;
486 #endif
487 {
488    CmLteTimingInfo    frm;
489    RgSchDlSf          *sf = NULLP;
490 #ifdef LTE_TDD
491    U8                 idx;
492 #endif
493
494    TRC3(rgSchL2CalDlPrbCount)
495
496    frm   = cell->crntTime;
497    RGSCH_INCR_SUB_FRAME(frm, RG_SCH_CMN_DL_DELTA);
498    sf = rgSCHUtlSubFrmGet(cell, frm);
499 #ifdef LTE_TDD
500    idx = (cell->crntTime.slot + RG_SCH_CMN_DL_DELTA) % 
501                   RGSCH_NUM_SUB_FRAMES;
502    if(RG_SCH_CMN_CHK_DL_DATA_ALLOWED(cell, idx)) 
503    {
504       cell->avgPrbDl.prbCount += sf->bwAssigned;
505       dlPrbCnt += sf->bwAssigned;
506    }
507 #else
508    cell->avgPrbDl.prbCount += sf->bwAssigned;
509 #endif
510    RETVOID;
511 }
512
513 /** @brief This function calculates the up link prb count 
514  * for a UlSf
515  *
516  * @details
517  *
518  *     Function: rgSchL2CalUlPrbCount
519  *
520  * @param  [in] RgSchCellCb       *cell
521  */
522 #ifdef ANSI
523 PRIVATE Void rgSchL2CalUlPrbCount
524 (
525 RgSchCellCb       *cell
526 )
527 #else
528 PRIVATE Void rgSchL2CalUlPrbCount(cell)
529 RgSchCellCb       *cell;
530 #endif
531 {
532    RgSchUlSf        *sf = NULLP;
533    RgSchCmnUlCell   *cellUl = RG_SCH_CMN_GET_UL_CELL(cell);
534 #ifdef LTE_TDD
535    U8                 idx;
536 #endif
537
538    TRC3(rgSchL2CalUlPrbCount)
539
540 #ifdef LTE_TDD
541    idx = cellUl->schdIdx;
542    if(idx < cellUl->numUlSubfrms)
543    {
544       sf = &cellUl->ulSfArr[idx];
545       cell->avgPrbUl.prbCount += sf->totPrb;
546    }
547 #else
548    sf = &cellUl->ulSfArr[cellUl->schdIdx];
549    cell->avgPrbUl.prbCount += sf->totPrb;
550 #endif
551    RETVOID;
552 }
553 /** @brief This function allocates memory from the heap
554  *
555  * @details
556  *
557  *     Function: rgSchL2mAllocMeasCb
558  *
559  * @param  [in] RgSchCellCb       *cell
560  * @param  [in] RgSchL2MeasCb     *measInfo
561  * @param  [out] RgSchErrInfo      *err
562  * @return  RgSchL2MeasCb *
563  */
564 #ifdef ANSI
565 PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb
566 (
567 RgSchCellCb       *cell,
568 LrgSchMeasReqInfo *measInfo,
569 RgSchErrInfo      err
570 )
571 #else
572 PRIVATE RgSchL2MeasCb * rgSchL2mAllocMeasCb(cell, measInfo, err)
573 RgSchCellCb       *cell;
574 LrgSchMeasReqInfo *measInfo;
575 RgSchErrInfo      err;
576 #endif
577 {
578    RgSchL2MeasCb       *measCb = NULLP;
579    Inst                inst = cell->instIdx;
580    UNUSED(err);
581    TRC3(rgSchL2mAllocMeasCb)
582
583    if((rgSCHUtlAllocSBuf(inst, (Data **)&measCb,
584                    sizeof(RgSchL2MeasCb))) == RFAILED)
585    {
586       RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId,"rgSchL2mAllocMeasCb():"
587                   "Allocation of RgSchL2MeasCb failed");
588       RETVALUE(NULLP);
589    }
590    cmMemcpy((U8 *)&measCb->measReq, (U8 *)measInfo, sizeof(LrgSchMeasReqInfo));
591    RGSCHCPYTIMEINFO(cell->crntTime, measCb->startTime);
592
593    measCb->dlTotalBw = 0;
594    measCb->ulTotalBw = 0;
595
596    RETVALUE(measCb);
597 } /* rgSchL2mAllocMeasCb */
598
599 /**
600  * @brief Layer Manager Measurement request handler. 
601  *
602  * @details
603  *
604  *     Function : rgSchL2mMeasReq
605  *     
606  *     This function handles  measurement request received at scheduler instance
607  *     from the Layer Manager.
608  *     -# Measurement request will be stored in the list in ascending order of
609  *     their time period.
610  *     
611  *  @param[in]  Pst *pst, the post structure     
612  *  @param[in]  LrgSchMeasReqInfo *measInfo, the measurement request structure
613  *  @param[out] RgSchErrInfo   *err, error information
614  *  @return  S16
615  *      -# ROK
616  *      -# RFAILED
617  **/
618 #ifdef ANSI
619 PUBLIC S16 rgSchL2mMeasReq 
620 (
621 RgSchCellCb       *cell,
622 LrgSchMeasReqInfo *measInfo,
623 RgSchErrInfo      err
624 )
625 #else
626 PUBLIC S16 rgSchL2mMeasReq(cell, measInfo, err)
627 RgSchCellCb       *cell;
628 LrgSchMeasReqInfo *measInfo;
629 RgSchErrInfo      err;
630 #endif    
631 {
632    RgSchL2MeasCb *measCb;
633    U8            idx;
634    U8            qciVal;
635
636    TRC3(rgSchL2mMeasReq)
637
638    qciVal = 0;
639    if ((measCb = rgSchL2mAllocMeasCb(cell, measInfo, err)) == NULLP)
640    {
641        RGSCHFILLERR(err, RGSCHERR_L2M_MEASREQ,
642                     RGSCHERR_SCH_ALLOC_FAILED);
643        RLOG_ARG0(L_ERROR,DBG_CELLID,cell->cellId, "rgSchL2mMeasReq():"
644                 "Allocation of RgSchL2MeasCb failed");
645        RETVALUE(RFAILED);
646    }
647    /*cmMemcpy((U8 *)&measCb->measReq, (CONSTANT U8 *)measInfo,\
648              sizeof(LrgSchMeasReqInfo));*/
649    rgSchL2mInsertMeasCb(cell, measCb, measInfo);
650   
651    if (measInfo->timePrd == 0)
652    {
653       cell->sndL2Meas = FALSE;
654       if (measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_DL)
655       {
656          for (idx = 0; idx < measInfo->avgPrbQciDl.numQci; idx++)
657          {
658             qciVal = measInfo->avgPrbQciDl.qci[idx];
659             cell->qciArray[qciVal].qci = qciVal;
660          }
661       }
662       if (measInfo->measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL)
663       {
664          for (idx = 0; idx < measInfo->nmbActvUeQciDl.numQci; idx++)
665          {
666             qciVal = measInfo->nmbActvUeQciDl.qci[idx];
667             cell->qciArray[qciVal].qci = qciVal;
668          }
669       }
670       if (measInfo->measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL)
671       {
672          for (idx = 0; idx < measInfo->nmbActvUeQciUl.numQci; idx++)
673          {
674             qciVal = measInfo->nmbActvUeQciUl.qci[idx];
675             cell->qciArray[qciVal].qci = qciVal;
676          }
677       }
678    }
679    /* Here post the message to MAC */
680    if(measInfo->measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL)
681    {
682       RgInfL2MeasReq    measReq;
683       Pst               pst;
684       cmMemset((U8 *)&measReq, 0, sizeof(RgInfL2MeasReq));
685       measReq.transId  = measInfo->hdr.transId;
686       measReq.measType = measInfo->measType;
687       measReq.timePrd  = measInfo->timePrd;
688       measReq.cellId   = measInfo->cellId;
689       measReq.t.prbReq.numQci = measInfo->avgPrbQciUl.numQci;
690       for (idx = 0; idx < measInfo->avgPrbQciUl.numQci; idx++)
691       {
692         measReq.t.prbReq.qci[idx] = measInfo->avgPrbQciUl.qci[idx]; 
693       }
694       /* Send measReq to MAC */
695       rgSCHUtlGetPstToLyr(&pst, &rgSchCb[cell->instIdx], cell->macInst);
696       RgSchMacL2Meas(&pst, &measReq);
697    }
698    RETVALUE(ROK);
699 } /* rgSchL2mMeasReq */
700
701 /**
702  * @brief This function calculates the measurement for differnt measurement type
703  * and send the end result to the layer manager
704  *
705  * @details
706  *
707  *     Function : rgSCHL2Meas
708  *     
709  *  @param[in] RgSchCellCb  *cell
710  *  @return  S16
711  *      -# ROK
712  *      -# RFAILED
713  **/
714 #ifdef ANSI
715 PUBLIC S16 rgSCHL2Meas
716 (
717 RgSchCellCb  *cell,
718 U8 isCalrCrcInd
719 )
720 #else
721 PUBLIC S16 rgschL2Meas(cell,isCalrCrcInd)
722 RgSchCellCb  *cell;
723 U8 isCalrCrcInd
724 #endif
725 {
726    CmLList           *node = NULLP;
727    RgSchL2MeasCb     *measCb = NULLP;
728    U8                idx;
729    LrgSchMeasCfmInfo measCfm;
730    U8                qciVal = 0;
731    U32               sfDiff;
732    U32               meas;
733 #ifdef LTE_TDD
734    U8                sfIdx;
735    Bool              isDlDataAllowed;  
736    U8                rem;
737    U32               numDlSf;
738    U32               numUlSf;
739 #endif
740    TRC3(rgSCHL2Meas)
741
742       node = cell->l2mList.first;
743    cmMemset((U8 *)&measCfm, 0, sizeof(LrgSchMeasCfmInfo));
744    while(node != NULLP)
745    {
746       measCb = (RgSchL2MeasCb *)node->node;
747       node = node->next;
748       if(cell->crntTime.sfn == 1023 && cell->crntTime.slot == 9)  
749       {
750          /*calculates diff between crnt time and start time*/
751          meas = RGSCH_CALC_SFN_SF_DIFF(cell->crntTime, 
752                measCb->sfnCycle, measCb->startTime);
753          measCb->sfnCycle++;
754       }
755       else
756       {
757          /*calculates diff between crnt time and start time*/
758          meas = RGSCH_CALC_SFN_SF_DIFF(cell->crntTime, 
759                measCb->sfnCycle, measCb->startTime);
760       }
761
762       if (cell->sndL2Meas || meas == measCb->measReq.timePrd)
763       {
764 #ifdef LTE_TDD
765          rem = meas % RGSCH_NUM_SUB_FRAMES;
766          /* Get the total number of DL and UL subframes within the reporting period*/
767          numDlSf = (meas / RGSCH_NUM_SUB_FRAMES) * rgSchTddNumDlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
768          numUlSf = (meas / RGSCH_NUM_SUB_FRAMES) * rgSchTddNumUlSubfrmTbl[cell->ulDlCfgIdx][RGSCH_NUM_SUB_FRAMES-1];
769
770          sfIdx = (measCb->startTime.slot + 1) % RGSCH_NUM_SUB_FRAMES;
771
772          while(rem)
773          {
774             isDlDataAllowed = RG_SCH_CMN_CHK_DL_DATA_ALLOWED(cell, sfIdx); 
775             if(isDlDataAllowed)
776             {
777                numDlSf++;
778             }   
779             else if(rgSchTddUlDlSubfrmTbl[cell->ulDlCfgIdx][sfIdx] == 
780                   RG_SCH_TDD_UL_SUBFRAME)
781             {
782                numUlSf++;
783             }     
784             sfIdx = (sfIdx + 1) % RGSCH_NUM_SUB_FRAMES;
785             rem--;
786          }   
787
788          measCb->dlTotalBw = numDlSf * cell->bwCfg.dlTotalBw;
789          measCb->ulTotalBw = numUlSf * cell->bwCfg.ulTotalBw;
790
791 #else            
792          measCb->dlTotalBw = meas * cell->bwCfg.dlTotalBw;
793          measCb->ulTotalBw = meas * cell->bwCfg.ulTotalBw;
794 #endif            
795          if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_PER_QCI_UL))
796          {
797             if(measCb->cfmRcvd)
798             {
799                rgSchFillL2MeasCfm(cell, measCb, &measCfm, meas);
800             }
801             else
802             {
803                continue;
804             }
805          }
806          else
807          {
808             rgSchFillL2MeasCfm(cell, measCb, &measCfm, meas);
809          }
810          RgMiLrgSchL2MeasCfm(&(rgSchCb[cell->instIdx].rgSchInit.lmPst),
811                &measCfm);
812          cmMemset((U8 *)&measCfm, 0, sizeof(LrgSchMeasCfmInfo));
813          
814          /* Delete this measCb from the list */
815          if(measCb->measReq.timePrd > 0)
816          {
817             cmLListDelFrm(&cell->l2mList, &measCb->measLnk);
818             rgSCHUtlFreeSBuf(cell->instIdx, (Data **)&measCb,
819                   sizeof(RgSchL2MeasCb));
820          }
821          else/*do not delete measCb, will use for next measurement*/
822          {
823             measCb->startTime = cell->crntTime;
824             measCb->sfnCycle = 0;
825             measCb->cfmRcvd = FALSE;
826             cmMemset((U8 *)&measCb->avgPrbQciUl, 0, sizeof(LrgAvgPrbQCICfm));
827             cell->sndL2Meas = FALSE;
828          } 
829          /* ccpu00117052 - MOD - Passing double pointer
830             for proper NULLP assignment*/
831       }
832       else
833       {
834          /* Just update the AVERAGE UL PRB counter here and return
835           * if the caller is CRCIndication() and the UL scheduling happens
836           * as a part of it*/
837 #ifdef RG_ULSCHED_AT_CRC 
838          if(isCalrCrcInd)
839          {
840             if(measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL)
841             {
842                rgSchL2CalUlPrbCount(cell);
843             }
844             continue;
845          }
846 #else
847          /* UL PRB counter gets updated as a part of CRC indication 
848           * if the UL scheduling happens there */
849          if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_UL))
850          {
851             rgSchL2CalUlPrbCount(cell);
852          }
853 #endif
854          if((measCb->measReq.measType & LRG_L2MEAS_AVG_PRB_DL))
855          {
856             rgSchL2CalDlPrbCount(cell);
857          }
858          if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_DL)
859          {
860             sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime, measCb->startTime);
861
862             if((sfDiff % measCb->measReq.nmbActvUeQciDl.sampPrd) == 0)
863             {
864                if (measCb->measReq.nmbActvUeQciDl.numQci)
865                {
866                   for (idx = 0; idx < measCb->measReq.nmbActvUeQciDl.numQci; 
867                         idx++)
868                   {
869                      qciVal = measCb->measReq.nmbActvUeQciDl.qci[idx];
870                      cell->qciArray[qciVal].dlTotal_UeCount +=
871                         cell->qciArray[qciVal].dlUeCount;
872                   }
873                }
874                else
875                {
876                   for (qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
877                   {
878                      cell->qciArray[qciVal].dlTotal_UeCount +=
879                         cell->qciArray[qciVal].dlUeCount;
880                   }
881                }
882             }
883          }
884          if(measCb->measReq.measType & LRG_L2MEAS_NMB_ACTV_UE_PER_QCI_UL)
885          {
886             sfDiff = RGSCH_CALC_SF_DIFF(cell->crntTime , measCb->startTime);
887             if((sfDiff % measCb->measReq.nmbActvUeQciUl.sampPrd) == 0)
888             {
889                if (measCb->measReq.nmbActvUeQciUl.numQci)
890                {
891                   for (idx = 0; idx < measCb->measReq.nmbActvUeQciUl.numQci; 
892                         idx++)
893                   {
894                      qciVal = measCb->measReq.nmbActvUeQciUl.qci[idx];
895                      cell->qciArray[qciVal].ulTotal_UeCount += 
896                         cell->qciArray[qciVal].ulUeCount;
897                   }
898                }
899                else
900                {
901                   for (qciVal = 1; qciVal < LRG_MAX_QCI_PER_REQ; qciVal++)
902                   {
903                      cell->qciArray[qciVal].ulTotal_UeCount += 
904                         cell->qciArray[qciVal].ulUeCount;
905                   }
906                }
907             }
908          }
909       }
910    }/* end of while */
911    RETVALUE(ROK);
912 } /* rgSCHL2MEas */
913 #endif /* LTE_L2_MEAS */
914 /**********************************************************************
915  
916          End of file
917 **********************************************************************/