Merge "Get alarm-list implementation.[Issue-Id: ODUHIGH-230]"
[o-du/l2.git] / src / 5gnrmac / rg_dux.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 Entry point fucntions
26   
27      File:    rg_dux.c 
28   
29 **********************************************************************/
30
31 /** @file rg_dux.c
32 @brief This module handles de-multiplexing of the data recieved at MAC.
33 */
34
35 static const char* RLOG_MODULE_NAME="MAC";
36 static int RLOG_FILE_ID=176;
37 static int RLOG_MODULE_ID=4096;
38 /* header include files -- defines (.h) */
39 #include "common_def.h"
40   
41 #include "rg_env.h"        /* MAC Environment Defines */
42 #include "tfu.h"           /* CRG Interface defines */
43 #include "crg.h"           /* CRG Interface defines */
44 #include "rg_sch_inf.h"           /* RGR Interface defines */
45 #include "rgu.h"           /* RGU Interface defines */
46 #include "lrg.h"           /* LRG Interface defines */
47
48 #include "rg.h"            /* MAC defines */
49 #include "rg_err.h"        /* MAC error defines */
50
51 /* header/extern include files (.x) */
52
53 #include "rgu.x"           /* RGU types */
54 #include "tfu.x"           /* CRG Interface includes */
55 #include "crg.x"           /* CRG Interface includes */
56 #include "rg_sch_inf.x"    /* SCH Interface includes */
57 #include "rg_prg.x"        /* PRG interface includes */
58 #include "rgu.x"           /* RGU Interface includes */
59 #include "lrg.x"           /* LRG Interface includes */
60
61 #include "du_app_mac_inf.h"
62 #include "rg.x"            /* MAC includes */
63
64 /* local defines */
65
66 /* local typedefs */
67  
68 /* local externs */
69  
70 /* forward references */
71
72 #define RG_DUX_ALLOC(_pdu, _size, _dataPtr, _ret) {\
73    _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
74 }
75
76 #define RG_INIT_SDU(_sdu, _lcId, _len) {\
77    (_sdu)->lcId = (_lcId); \
78    (_sdu)->len = (_len); \
79    (_sdu)->mBuf = NULLP; \
80    (_sdu)->sduLstEnt.next = NULLP; \
81    (_sdu)->sduLstEnt.prev = NULLP; \
82    (_sdu)->sduLstEnt.node = (PTR)(_sdu); \
83 }
84
85 #define RG_EXT_BS(_bsr, _bs1, _bs2, _bs3, _bs4)  {\
86    _bs1 = _bsr[0] >> 2; \
87    _bs2 = (((_bsr[0] & 0x3) << 4) | (_bsr[1] >> 4)); \
88    _bs3 = (((_bsr[1] & 0x0F) << 2) | (_bsr[2] >> 6)); \
89    _bs4 = _bsr[2] & 0x3F; \
90 }
91
92 #define RG_UNPACK_LONG_BSR(_bsr, _mBuf, _ret) {\
93    _ret = SRemPreMsgMult((_bsr), 3, (_mBuf)); \
94 }
95
96 #define RG_UNPACK_SHORT_BSR(_bsr, _mBuf, _ret) {\
97    _ret = oduPackUInt8((_bsr), (_mBuf)); \
98 }
99
100 #define RG_UNPACK_TRUNC_BSR(_bsr, _mBuf, _ret) {\
101    _ret = oduPackUInt8((_bsr), (_mBuf)); \
102 }
103
104 #define RG_UNPACK_PHR(_phr, _mBuf, _ret) {\
105    _ret = oduPackUInt8((_phr), (_mBuf)); \
106 }
107
108 #define RG_UNPACK_CRNTI(_rnti, _mBuf, _ret) {\
109    Data _unpkArray[2];\
110    *_rnti = 0;\
111    _ret = SRemPreMsgMult(_unpkArray, (MsgLen) 2, _mBuf);\
112    if (_ret == ROK)\
113    {\
114       *_rnti = (uint16_t) PutHiByte(*_rnti, (uint8_t) _unpkArray[0]);\
115       *_rnti = (uint16_t) PutLoByte(*_rnti, (uint8_t) _unpkArray[1]);\
116    }\
117 }
118
119 /* For EXT PHR DEMUX */
120 #define RG_UNPACK_EXT_PHR_CI(_ci, _mBuf, _ret) {\
121    _ret = oduPackUInt8((_ci), (_mBuf)); \
122 }
123
124 #define RG_UNPACK_EXT_PHR(_extPhr, _mBuf, _ret) {\
125    _ret = oduPackUInt8((_extPhr), (_mBuf)); \
126 }
127
128
129
130 /**
131  * @brief Handles the insertion of SDU in to PDU.
132  *
133  * @details
134  *
135  *     Function: rgDUXInsSdu
136  *     
137  *     This API handles the insertion of SDU in to PDU.
138  *     
139  *     Processing Steps: 
140  *      - Append the sdu to the sduLst of pdu.
141  *
142  *  @param[in]  Inst        inst
143  *  @param[out] *pdu
144  *  @param[in]  lcId
145  *  @param[in]  sduLen
146  *  @param[out] *err
147  *  @return  S16
148  *      -# ROK 
149  *      -# RFAILED 
150  **/
151 static S16 rgDUXInsSdu(Inst inst, RgMacPdu *pdu, RgMacSdu **sdu, uint8_t lcId, uint16_t sduLen, RgErrInfo *err)
152 {
153    S16         ret;
154    RgMacSdu    *sduAloc = NULLP;
155
156
157    RG_DUX_ALLOC(pdu, sizeof(RgMacSdu), sduAloc, ret);
158    if(ret != ROK)
159    {
160       RLOG1(L_ERROR, "Allocation of RgSubHdr failed for LCID:%d",lcId);
161       err->errCause = RGERR_DUX_MEM_EXHAUST;
162       return RFAILED;
163    }
164    *sdu = sduAloc; 
165    RG_INIT_SDU(sduAloc, lcId, sduLen);
166    cmLListAdd2Tail(&pdu->sduLst, &sduAloc->sduLstEnt);
167    return ROK;
168 }
169
170 /**
171  * @brief Handles extracting the CE sub headers from the MAC PDU.
172  *
173  * @details
174  *
175  *     Function: rgDUXExtSubHdr
176  *     
177  *     This API handles extracting the  sub headers from the MAC PDU.
178  *     
179  *     Processing Steps: 
180  *      - Extract the each sub header.
181  *
182  *  @param[in]  Inst        inst
183  *  @param[out]  *pdu
184  *  @param[in]  *mBuf
185  *  @param[out] *lcId
186  *  @param[out] *len
187  *  @param[out] *err
188  *  @return  S16
189  *      -# ROK 
190  *      -# RFAILED 
191  **/
192 static S16 rgDUXExtSubHdr(Inst inst, RgMacPdu *pdu, Buffer *mBuf, uint8_t *lcId, uint16_t *len, RgErrInfo *err)
193 {
194    uint8_t             byte;
195    uint8_t             fmt=0;
196  
197
198    *len = 0;   
199    if(oduPackUInt8(&byte,mBuf) != ROK)
200    {
201       RLOG0(L_ERROR, "oduPackUInt8 failed");
202       err->errCause = RGERR_DUX_UNPACK_FAILURE;
203       return RFAILED;
204    }
205    /* Extract the lcid */
206    RG_EXT_LCID(*lcId, byte);
207
208    /*note: RG_EXT_PHR_LCID currently not considered */
209    if(*lcId <= RG_DEDLC_MAX_LCID)
210    {  /* variable size MAC Sub PDU */
211       RG_EXT_FORMT_BIT(fmt,byte);
212       if(oduPackUInt8(&byte, mBuf) != ROK)
213       {
214          RLOG0(L_ERROR, "oduPackUInt8 failed");
215          err->errCause = RGERR_DUX_UNPACK_FAILURE;
216          return RFAILED;
217       }
218       *len = byte;
219       if(fmt)
220       {
221          if(oduPackUInt8(&byte,mBuf) != ROK)
222          {
223             RLOG0(L_ERROR, "oduPackUInt8 failed");
224             err->errCause = RGERR_DUX_UNPACK_FAILURE;
225             return RFAILED;
226          }
227          *len = (*len << 8) | byte;
228       }
229    }
230    return ROK;
231 } /* rgDUXExtSubHdr */
232
233 /**
234  * @brief Handles extracting the CEs from the MAC PDU.
235  *
236  * @details
237  *
238  *     Function: rgDUXExtCe
239  *     
240  *     This API handles extracting the CEs from the MAC PDU.
241  *     
242  *     Processing Steps: 
243  *      - Based on the ce sub header extract the ce.
244  *
245  *  @param[in]  Inst        inst
246  *  @param[in,out]  *pdu
247  *  @param[out] *ceInfo
248  *  @param[in]  *mBuf
249  *  @param[in] lcId
250  *  @param[in] subPduLen
251  *  @param[out] *err
252  *  @return  S16
253  *      -# ROK 
254  *      -# RFAILED 
255  **/
256 static S16 rgDUXExtCe(Inst inst, RgMacPdu *pdu, RgInfCeInfo *ceInfo, Buffer *mBuf, uint8_t lcId, uint16_t subPduLen,\
257 RgErrInfo *err)
258 {
259    S16            ret;
260
261
262    switch(lcId)
263    {
264       case RG_EXT_PHR_LCID:
265          {
266             uint8_t Ci;
267             uint8_t sCellIdx;
268             uint8_t extPhrOctet;
269             uint8_t extPhrPCmax;
270             RgInfExtPhrCEInfo *extPhr;
271
272             RG_UNPACK_EXT_PHR_CI(&Ci,mBuf,ret);
273             if(ret != ROK)
274             {
275                RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
276                err->errCause = RGERR_DUX_UNPACK_FAILURE;
277                return RFAILED;
278             }
279
280             /* Not handling Type 2 PHR report as simultaneous PUSCH/PUCCH
281                is not supported as of now */
282             extPhr = &ceInfo->ces.extPhr;
283             extPhr->numServCells = 0;
284
285             /* Setting first BIT as PCELL field even though reserved is always
286                reported by UE */
287             Ci |= 0x1;
288             for (sCellIdx = 0; (Ci && sCellIdx < CM_LTE_MAX_CELLS); sCellIdx++)
289             {
290                if (Ci & 0x1)
291                {
292                   extPhr->servCellPhr[extPhr->numServCells].sCellIdx = sCellIdx;
293                   RG_UNPACK_EXT_PHR(&extPhrOctet,mBuf,ret);
294                   if(ret != ROK)
295                   {
296                      RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
297                      err->errCause = RGERR_DUX_UNPACK_FAILURE;
298                      return RFAILED;
299                   }
300
301                   /* extPhrOctet: Bits : 7 6 5 4 3 2 1 0
302                    *                     P V x x x x x x
303                    *                         <6x Bit phr>
304                    */
305                   /* P : P Back off applied or not */
306                   extPhr->servCellPhr[extPhr->numServCells].phr = (extPhrOctet & 0x3F);
307                   extPhr->servCellPhr[extPhr->numServCells].pBackOff = 
308                      ((extPhrOctet >> 7) & 0x01);
309
310                   /* V: Virtual PCMAX or Real Tx PCMAX */
311                   if (extPhrOctet & 0x40)
312                   {
313                      extPhr->servCellPhr[extPhr->numServCells].pCmax = RG_REF_PCMAX;
314                   }
315                   else
316                   {
317                      RG_UNPACK_EXT_PHR(&extPhrPCmax,mBuf,ret);
318                      if(ret != ROK)
319                      {
320                         RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
321                         err->errCause = RGERR_DUX_UNPACK_FAILURE;
322                         return RFAILED;
323                      }
324                      extPhr->servCellPhr[extPhr->numServCells].pCmax = (extPhrPCmax & 0x3F);
325                   }
326                   extPhr->numServCells++;
327                }
328                Ci >>= 1;
329             }
330
331             ceInfo->bitMask |= RG_EXT_PHR_CE_PRSNT;
332          }
333          break;
334
335       case RG_PHR_LCID:
336          {
337             RG_UNPACK_PHR(&ceInfo->ces.phr,mBuf,ret);
338             if(ret != ROK)
339             {
340                RLOG1(L_ERROR,"Unpacking of PHR failed LCID:%d",lcId);
341                err->errCause = RGERR_DUX_UNPACK_FAILURE;
342                return RFAILED;
343             }
344             ceInfo->bitMask |= RG_PHR_CE_PRSNT;
345          }
346          break;
347       case RG_TRUNC_BSR_LCID:
348          {
349             RG_UNPACK_TRUNC_BSR(&ceInfo->ces.bsr.truncBsr,mBuf,ret);
350             if(ret != ROK)
351             {
352                RLOG1(L_ERROR,"Unpacking of Trunc BSR failed LCID:%d",lcId);
353                err->errCause = RGERR_DUX_UNPACK_FAILURE;
354                return RFAILED;
355             }
356             ceInfo->bitMask |= RG_TRUNC_BSR_CE_PRSNT;
357          }
358          break;
359       case RG_SHORT_BSR_LCID:
360          {
361             RG_UNPACK_SHORT_BSR(&ceInfo->ces.bsr.shortBsr,mBuf,ret);
362             if(ret != ROK)
363             {
364                RLOG1(L_ERROR,"Unpacking of Short BSR failed LCID:%d",lcId);
365                err->errCause = RGERR_DUX_UNPACK_FAILURE;
366                return RFAILED;
367             }
368             ceInfo->bitMask |= RG_SHORT_BSR_CE_PRSNT;
369          }
370          break;
371       case RG_LONG_BSR_LCID:
372          {
373             uint8_t longBsr[3] = {0}; /* KW_FIXX */
374             RG_UNPACK_LONG_BSR(longBsr,mBuf,ret);
375             if(ret != ROK)
376             {
377                RLOG1(L_ERROR,"Unpacking of Long BSR failed LCID:%d",lcId);
378                err->errCause = RGERR_DUX_UNPACK_FAILURE;
379                return RFAILED;
380             }
381             RG_EXT_BS(longBsr, 
382                   ceInfo->ces.bsr.longBsr.bs1, 
383                   ceInfo->ces.bsr.longBsr.bs2, 
384                   ceInfo->ces.bsr.longBsr.bs3, 
385                   ceInfo->ces.bsr.longBsr.bs4);
386             ceInfo->bitMask |= RG_LONG_BSR_CE_PRSNT;
387          }
388          break;
389       case RG_CRNTI_LCID:
390          {
391             RG_UNPACK_CRNTI(&ceInfo->ces.cRnti,mBuf,ret);
392             if(ret != ROK)
393             {
394                RLOG1(L_ERROR,"Unpacking of C-RNTI failed LCID:%d",lcId);
395                err->errCause = RGERR_DUX_UNPACK_FAILURE;
396                return RFAILED;
397             }
398             ceInfo->bitMask |= RG_CRNTI_CE_PRSNT;
399          }
400          break;
401       default:
402          RLOG1(L_ERROR, "Invalid LCID:%u received",lcId); 
403          err->errCause = RGERR_DUX_INV_LCID_RX;
404          return RFAILED;
405    }
406    return ROK;
407 } /* rgDUXExtCe  */
408
409
410 /**
411  * @brief Handles extracting the SDU from the MAC PDU.
412  *
413  * @details
414  *
415  *     Function: rgDUXExtSdu
416  *     
417  *     This API handles extracting the SDU corresponding to a logical channel.
418  *     
419  *     Processing Steps: 
420  *      - Based on the length stored in the sub header extract the SDU.
421  *
422  *  @param[in]  Inst        inst
423  *  @param[in,out]  *pdu
424  *  @param[out] *ceInfo
425  *  @param[in]  *mBuf
426  *  @param[in] lcId
427  *  @param[in] subPduLen
428  *  @param[out] *err
429  *  @return  S16
430  *      -# ROK 
431  *      -# RFAILED 
432  **/
433 static S16 rgDUXExtSdu(Inst inst, RgMacPdu *pdu, RgInfCeInfo *ceInfo, Buffer **mBuf, uint8_t lcId, uint16_t subPduLen,\
434 RgErrInfo *err)
435 {
436    S16         ret;
437    Buffer      *tmpBuf1;
438    Buffer      *tmpBuf2 = NULLP;
439    RgMacSdu    *sdu;
440
441
442    if(lcId == RG_CCCH_LCID)
443    {
444       ceInfo->bitMask |= RG_CCCH_SDU_PRSNT;
445    }
446
447    if(rgDUXInsSdu(inst,pdu, &sdu,lcId, subPduLen, err) != ROK)
448    {
449       RG_FREE_MSG(*mBuf);
450       return RFAILED;
451    }
452
453    tmpBuf1 = *mBuf;
454    {
455       ret = SSegMsg(tmpBuf1,subPduLen,&tmpBuf2);
456       if((ret != ROK) && (!((ret == ROKDNA) )))
457       {
458          RG_FREE_MSG(tmpBuf1);
459          RLOG0(L_ERROR,"SSegMsg failed");
460          err->errCause = RGERR_DUX_RLC_PDU_CREAT_FAIL;
461          return RFAILED;
462       }
463       sdu->mBuf = tmpBuf1;
464       *mBuf = tmpBuf2;
465    }
466    return ROK;
467 }   /* rgDUXExtSdu */
468
469 /**
470  * @brief Handles de-multiplexing of the data recieved at MAC.
471  *
472  * @details
473  *
474  *     Function: rgDUXDemuxData
475  *     
476  *     This API handles de-multiplexing of the data recieved at MAC.
477  *     
478  *     Invoked by: rgTOMTfuDatInd of TOM 
479  *     
480  *     Processing Steps: 
481  *      - De-multiplex the mBuf
482  *
483  *  @param[in]  Inst        inst
484  *  @param[in]  *pdu 
485  *  @param[in]  *mBuf 
486  *  @param[out] *err 
487  *  @return  S16
488  *      -# ROK 
489  *      -# RFAILED 
490  **/
491 S16 rgDUXDemuxData(Inst inst, RgMacPdu  *pdu, RgInfCeInfo *ceInfo, Buffer **mBuf, RgErrInfo *err)
492 {
493    uint8_t     lcId;
494    uint16_t    subPduLen;
495    MsgLen      len;  
496
497    ceInfo->bitMask = 0x0000;
498
499    /* Initialize the sdu list */
500    cmLListInit(&pdu->sduLst);
501
502    if(*mBuf == NULLP) 
503    {
504       RLOG0(L_ERROR, "Null Buffer Recevived");
505       return RFAILED;
506    }
507    do
508    {
509       /* UL Message format  order : 
510            PduSubHdr+SubPDU,PduSubHdr+SubPDU,...CeSubHdr+Ce,CeSubPdu+Ce,...,PADSubHdr+PAD */
511       /* Extract the Sub headers */
512       if(rgDUXExtSubHdr(inst,pdu, *mBuf, &lcId, 
513                &subPduLen, err) != ROK)
514       {
515          RG_FREE_MSG(*mBuf);          
516          RLOG0(L_ERROR, "Failed to extract pad sub headers");
517          return RFAILED;
518       }
519       if(lcId == RG_PAD_LCID)
520       { /*at end of MAC PDU,  Padding started */ 
521          RG_FREE_MSG(*mBuf);          
522          return ROK;
523       }
524       if(lcId <= RG_DEDLC_MAX_LCID)
525       {
526          /* Extract the sdus */
527          if(rgDUXExtSdu(inst,pdu,ceInfo, mBuf,lcId,subPduLen, err) != ROK)
528          {
529             /* Fix : syed rgDUXExtSdu would have segmented mBuf and hence
530              * will be responsible for freeing mBuf */
531             *mBuf = NULLP;
532             RLOG0(L_ERROR, "failed to Extract the sdus");
533             return RFAILED;
534          }
535          if(*mBuf == NULLP) /* if message read completes then return */
536          {
537             return ROK;
538          }
539       }
540       else
541       {
542          /* Extract the ces */
543          if(rgDUXExtCe(inst,pdu,ceInfo,*mBuf, lcId,subPduLen, err) != ROK)
544          {
545             RG_FREE_MSG(*mBuf);       
546             RLOG0(L_ERROR, " failed to Extract the ces");
547             return RFAILED;
548          }
549       }
550       if(SFndLenMsg(*mBuf,&len) != ROK)
551       {
552          RG_FREE_MSG(*mBuf);
553          RLOG0(L_ERROR,"mBuf length check failed");
554          err->errCause = RGERR_DUX_UNPACK_FAILURE;
555          return RFAILED;
556       }
557    }while(len);
558
559    RG_FREE_MSG(*mBuf);
560    return ROK;
561 }  /* rgDUXDemuxData */
562
563 /**********************************************************************
564  
565          End of file
566 **********************************************************************/