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