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