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