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