Jira id - ODUHIGH-227
[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 = (U16) PutHiByte(*_rnti, (U8) _unpkArray[0]);\
115       *_rnti = (U16) PutLoByte(*_rnti, (U8) _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 #ifdef ANSI
152 PRIVATE S16 rgDUXInsSdu
153 (
154 Inst        inst,
155 RgMacPdu    *pdu,
156 RgMacSdu    **sdu,
157 U8          lcId,
158 U16         sduLen,
159 RgErrInfo   *err
160 )
161 #else
162 PRIVATE S16 rgDUXInsSdu(inst,pdu, sdu, lcId, sduLen, err)
163 Inst        inst;
164 RgMacPdu    *pdu;
165 RgMacSdu    **sdu,
166 U8          lcId;
167 U16         sduLen;
168 RgErrInfo   *err;
169 #endif
170 {
171    S16         ret;
172    RgMacSdu    *sduAloc = NULLP;
173
174    TRC2(rgDUXInsSdu)
175
176    RG_DUX_ALLOC(pdu, sizeof(RgMacSdu), sduAloc, ret);
177    if(ret != ROK)
178    {
179       RLOG1(L_ERROR, "Allocation of RgSubHdr failed for LCID:%d",lcId);
180       err->errCause = RGERR_DUX_MEM_EXHAUST;
181       return RFAILED;
182    }
183    *sdu = sduAloc; 
184    RG_INIT_SDU(sduAloc, lcId, sduLen);
185    cmLListAdd2Tail(&pdu->sduLst, &sduAloc->sduLstEnt);
186    return ROK;
187 }
188
189 /**
190  * @brief Handles extracting the CE sub headers from the MAC PDU.
191  *
192  * @details
193  *
194  *     Function: rgDUXExtSubHdr
195  *     
196  *     This API handles extracting the  sub headers from the MAC PDU.
197  *     
198  *     Processing Steps: 
199  *      - Extract the each sub header.
200  *
201  *  @param[in]  Inst        inst
202  *  @param[out]  *pdu
203  *  @param[in]  *mBuf
204  *  @param[out] *lcId
205  *  @param[out] *len
206  *  @param[out] *err
207  *  @return  S16
208  *      -# ROK 
209  *      -# RFAILED 
210  **/
211 #ifdef ANSI
212 PRIVATE S16 rgDUXExtSubHdr
213 (
214 Inst        inst,
215 RgMacPdu    *pdu,
216 Buffer      *mBuf,
217 U8          *lcId,
218 U16         *len,
219 RgErrInfo   *err
220 )
221 #else
222 PRIVATE S16 rgDUXExtSubHdr(inst,pdu, mBuf, lcId,
223 len, err)
224 Inst        inst;
225 RgMacPdu    *pdu;
226 Buffer      *mBuf;
227 U8          *lcId;
228 U16         *len;
229 RgErrInfo   *err;
230 #endif
231 {
232    U8             byte;
233    U8             fmt=0;
234  
235    TRC2(rgDUXExtSubHdr)
236
237    *len = 0;   
238    if(oduPackUInt8(&byte,mBuf) != ROK)
239    {
240       RLOG0(L_ERROR, "oduPackUInt8 failed");
241       err->errCause = RGERR_DUX_UNPACK_FAILURE;
242       return RFAILED;
243    }
244    /* Extract the lcid */
245    RG_EXT_LCID(*lcId, byte);
246
247    /*note: RG_EXT_PHR_LCID currently not considered */
248    if(*lcId <= RG_DEDLC_MAX_LCID)
249    {  /* variable size MAC Sub PDU */
250       RG_EXT_FORMT_BIT(fmt,byte);
251       if(oduPackUInt8(&byte, mBuf) != ROK)
252       {
253          RLOG0(L_ERROR, "oduPackUInt8 failed");
254          err->errCause = RGERR_DUX_UNPACK_FAILURE;
255          return RFAILED;
256       }
257       *len = byte;
258       if(fmt)
259       {
260          if(oduPackUInt8(&byte,mBuf) != ROK)
261          {
262             RLOG0(L_ERROR, "oduPackUInt8 failed");
263             err->errCause = RGERR_DUX_UNPACK_FAILURE;
264             return RFAILED;
265          }
266          *len = (*len << 8) | byte;
267       }
268    }
269    return ROK;
270 } /* rgDUXExtSubHdr */
271
272 /**
273  * @brief Handles extracting the CEs from the MAC PDU.
274  *
275  * @details
276  *
277  *     Function: rgDUXExtCe
278  *     
279  *     This API handles extracting the CEs from the MAC PDU.
280  *     
281  *     Processing Steps: 
282  *      - Based on the ce sub header extract the ce.
283  *
284  *  @param[in]  Inst        inst
285  *  @param[in,out]  *pdu
286  *  @param[out] *ceInfo
287  *  @param[in]  *mBuf
288  *  @param[in] lcId
289  *  @param[in] subPduLen
290  *  @param[out] *err
291  *  @return  S16
292  *      -# ROK 
293  *      -# RFAILED 
294  **/
295 #ifdef ANSI
296 PRIVATE S16 rgDUXExtCe
297 (
298 Inst        inst,
299 RgMacPdu    *pdu,
300 RgInfCeInfo  *ceInfo,
301 Buffer       *mBuf,
302 U8          lcId,
303 U16         subPduLen,
304 RgErrInfo    *err
305 )
306 #else
307 PRIVATE S16 rgDUXExtCe(inst,pdu, ceInfo, mBuf,lcId,subPduLen, err)
308 Inst        inst;
309 RgMacPdu    *pdu;
310 RgInfCeInfo  *ceInfo;
311 Buffer       *mBuf;
312 U8          lcId;
313 U16         subPduLen;
314 RgErrInfo    *err;
315 #endif
316 {
317    S16            ret;
318
319    TRC2(rgDUXExtCe);
320
321    switch(lcId)
322    {
323       case RG_EXT_PHR_LCID:
324          {
325             U8 Ci;
326             U8 sCellIdx;
327             U8 extPhrOctet;
328             U8 extPhrPCmax;
329             RgInfExtPhrCEInfo *extPhr;
330
331             RG_UNPACK_EXT_PHR_CI(&Ci,mBuf,ret);
332             if(ret != ROK)
333             {
334                RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
335                err->errCause = RGERR_DUX_UNPACK_FAILURE;
336                return RFAILED;
337             }
338
339             /* Not handling Type 2 PHR report as simultaneous PUSCH/PUCCH
340                is not supported as of now */
341             extPhr = &ceInfo->ces.extPhr;
342             extPhr->numServCells = 0;
343
344             /* Setting first BIT as PCELL field even though reserved is always
345                reported by UE */
346             Ci |= 0x1;
347             for (sCellIdx = 0; (Ci && sCellIdx < CM_LTE_MAX_CELLS); sCellIdx++)
348             {
349                if (Ci & 0x1)
350                {
351                   extPhr->servCellPhr[extPhr->numServCells].sCellIdx = sCellIdx;
352                   RG_UNPACK_EXT_PHR(&extPhrOctet,mBuf,ret);
353                   if(ret != ROK)
354                   {
355                      RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
356                      err->errCause = RGERR_DUX_UNPACK_FAILURE;
357                      return RFAILED;
358                   }
359
360                   /* extPhrOctet: Bits : 7 6 5 4 3 2 1 0
361                    *                     P V x x x x x x
362                    *                         <6x Bit phr>
363                    */
364                   /* P : P Back off applied or not */
365                   extPhr->servCellPhr[extPhr->numServCells].phr = (extPhrOctet & 0x3F);
366                   extPhr->servCellPhr[extPhr->numServCells].pBackOff = 
367                      ((extPhrOctet >> 7) & 0x01);
368
369                   /* V: Virtual PCMAX or Real Tx PCMAX */
370                   if (extPhrOctet & 0x40)
371                   {
372                      extPhr->servCellPhr[extPhr->numServCells].pCmax = RG_REF_PCMAX;
373                   }
374                   else
375                   {
376                      RG_UNPACK_EXT_PHR(&extPhrPCmax,mBuf,ret);
377                      if(ret != ROK)
378                      {
379                         RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
380                         err->errCause = RGERR_DUX_UNPACK_FAILURE;
381                         return RFAILED;
382                      }
383                      extPhr->servCellPhr[extPhr->numServCells].pCmax = (extPhrPCmax & 0x3F);
384                   }
385                   extPhr->numServCells++;
386                }
387                Ci >>= 1;
388             }
389
390             ceInfo->bitMask |= RG_EXT_PHR_CE_PRSNT;
391          }
392          break;
393
394       case RG_PHR_LCID:
395          {
396             RG_UNPACK_PHR(&ceInfo->ces.phr,mBuf,ret);
397             if(ret != ROK)
398             {
399                RLOG1(L_ERROR,"Unpacking of PHR failed LCID:%d",lcId);
400                err->errCause = RGERR_DUX_UNPACK_FAILURE;
401                return RFAILED;
402             }
403             ceInfo->bitMask |= RG_PHR_CE_PRSNT;
404          }
405          break;
406       case RG_TRUNC_BSR_LCID:
407          {
408             RG_UNPACK_TRUNC_BSR(&ceInfo->ces.bsr.truncBsr,mBuf,ret);
409             if(ret != ROK)
410             {
411                RLOG1(L_ERROR,"Unpacking of Trunc BSR failed LCID:%d",lcId);
412                err->errCause = RGERR_DUX_UNPACK_FAILURE;
413                return RFAILED;
414             }
415             ceInfo->bitMask |= RG_TRUNC_BSR_CE_PRSNT;
416          }
417          break;
418       case RG_SHORT_BSR_LCID:
419          {
420             RG_UNPACK_SHORT_BSR(&ceInfo->ces.bsr.shortBsr,mBuf,ret);
421             if(ret != ROK)
422             {
423                RLOG1(L_ERROR,"Unpacking of Short BSR failed LCID:%d",lcId);
424                err->errCause = RGERR_DUX_UNPACK_FAILURE;
425                return RFAILED;
426             }
427             ceInfo->bitMask |= RG_SHORT_BSR_CE_PRSNT;
428          }
429          break;
430       case RG_LONG_BSR_LCID:
431          {
432             U8 longBsr[3] = {0}; /* KW_FIXX */
433             RG_UNPACK_LONG_BSR(longBsr,mBuf,ret);
434             if(ret != ROK)
435             {
436                RLOG1(L_ERROR,"Unpacking of Long BSR failed LCID:%d",lcId);
437                err->errCause = RGERR_DUX_UNPACK_FAILURE;
438                return RFAILED;
439             }
440             RG_EXT_BS(longBsr, 
441                   ceInfo->ces.bsr.longBsr.bs1, 
442                   ceInfo->ces.bsr.longBsr.bs2, 
443                   ceInfo->ces.bsr.longBsr.bs3, 
444                   ceInfo->ces.bsr.longBsr.bs4);
445             ceInfo->bitMask |= RG_LONG_BSR_CE_PRSNT;
446          }
447          break;
448       case RG_CRNTI_LCID:
449          {
450             RG_UNPACK_CRNTI(&ceInfo->ces.cRnti,mBuf,ret);
451             if(ret != ROK)
452             {
453                RLOG1(L_ERROR,"Unpacking of C-RNTI failed LCID:%d",lcId);
454                err->errCause = RGERR_DUX_UNPACK_FAILURE;
455                return RFAILED;
456             }
457             ceInfo->bitMask |= RG_CRNTI_CE_PRSNT;
458          }
459          break;
460       default:
461          RLOG1(L_ERROR, "Invalid LCID:%u received",lcId); 
462          err->errCause = RGERR_DUX_INV_LCID_RX;
463          return RFAILED;
464    }
465    return ROK;
466 } /* rgDUXExtCe  */
467
468
469 /**
470  * @brief Handles extracting the SDU from the MAC PDU.
471  *
472  * @details
473  *
474  *     Function: rgDUXExtSdu
475  *     
476  *     This API handles extracting the SDU corresponding to a logical channel.
477  *     
478  *     Processing Steps: 
479  *      - Based on the length stored in the sub header extract the SDU.
480  *
481  *  @param[in]  Inst        inst
482  *  @param[in,out]  *pdu
483  *  @param[out] *ceInfo
484  *  @param[in]  *mBuf
485  *  @param[in] lcId
486  *  @param[in] subPduLen
487  *  @param[out] *err
488  *  @return  S16
489  *      -# ROK 
490  *      -# RFAILED 
491  **/
492 #ifdef ANSI
493 PRIVATE S16 rgDUXExtSdu
494 (
495 Inst        inst,
496 RgMacPdu    *pdu,
497 RgInfCeInfo  *ceInfo,
498 Buffer      **mBuf,
499 U8          lcId,
500 U16         subPduLen,
501 RgErrInfo   *err
502 )
503 #else
504 PRIVATE S16 rgDUXExtSdu(inst,pdu, ceInfo,mBuf,lcId,subPduLen,err)
505 Inst        inst;
506 RgMacPdu    *pdu;
507 RgInfCeInfo  *ceInfo;
508 Buffer      **mBuf;
509 U8          lcId;
510 U16         subPduLen;
511 RgErrInfo   *err;
512 #endif
513 {
514    S16         ret;
515    Buffer      *tmpBuf1;
516    Buffer      *tmpBuf2 = NULLP;
517    RgMacSdu    *sdu;
518
519    TRC2(rgDUXExtSdu)
520
521    if(lcId == RG_CCCH_LCID)
522    {
523       ceInfo->bitMask |= RG_CCCH_SDU_PRSNT;
524    }
525
526    if(rgDUXInsSdu(inst,pdu, &sdu,lcId, subPduLen, err) != ROK)
527    {
528       RG_FREE_MSG(*mBuf);
529       return RFAILED;
530    }
531
532    tmpBuf1 = *mBuf;
533    {
534       ret = SSegMsg(tmpBuf1,subPduLen,&tmpBuf2);
535       if((ret != ROK) && (!((ret == ROKDNA) )))
536       {
537          RG_FREE_MSG(tmpBuf1);
538          RLOG0(L_ERROR,"SSegMsg failed");
539          err->errCause = RGERR_DUX_RLC_PDU_CREAT_FAIL;
540          return RFAILED;
541       }
542       sdu->mBuf = tmpBuf1;
543       *mBuf = tmpBuf2;
544    }
545    return ROK;
546 }   /* rgDUXExtSdu */
547
548 /**
549  * @brief Handles de-multiplexing of the data recieved at MAC.
550  *
551  * @details
552  *
553  *     Function: rgDUXDemuxData
554  *     
555  *     This API handles de-multiplexing of the data recieved at MAC.
556  *     
557  *     Invoked by: rgTOMTfuDatInd of TOM 
558  *     
559  *     Processing Steps: 
560  *      - De-multiplex the mBuf
561  *
562  *  @param[in]  Inst        inst
563  *  @param[in]  *pdu 
564  *  @param[in]  *mBuf 
565  *  @param[out] *err 
566  *  @return  S16
567  *      -# ROK 
568  *      -# RFAILED 
569  **/
570 #ifdef ANSI
571 S16 rgDUXDemuxData
572 (
573 Inst          inst,
574 RgMacPdu      *pdu,
575 RgInfCeInfo   *ceInfo,
576 Buffer        **mBuf,
577 RgErrInfo     *err
578 )
579 #else
580 S16 rgDUXDemuxData(inst,pdu, ceInfo, mBuf, err)
581 Inst          inst;
582 RgMacPdu      *pdu;
583 RgInfCeInfo   *ceInfo;
584 Buffer        **mBuf;
585 RgErrInfo     *err;
586 #endif
587 {
588    U8          lcId;
589    U16          subPduLen;
590    MsgLen      len;  
591    TRC2(rgDUXDemuxData)
592
593    ceInfo->bitMask = 0x0000;
594
595    /* Initialize the sdu list */
596    cmLListInit(&pdu->sduLst);
597
598    if(*mBuf == NULLP) 
599    {
600       RLOG0(L_ERROR, "Null Buffer Recevived");
601       return RFAILED;
602    }
603    do
604    {
605       /* UL Message format  order : 
606            PduSubHdr+SubPDU,PduSubHdr+SubPDU,...CeSubHdr+Ce,CeSubPdu+Ce,...,PADSubHdr+PAD */
607       /* Extract the Sub headers */
608       if(rgDUXExtSubHdr(inst,pdu, *mBuf, &lcId, 
609                &subPduLen, err) != ROK)
610       {
611          RG_FREE_MSG(*mBuf);          
612          RLOG0(L_ERROR, "Failed to extract pad sub headers");
613          return RFAILED;
614       }
615       if(lcId == RG_PAD_LCID)
616       { /*at end of MAC PDU,  Padding started */ 
617          RG_FREE_MSG(*mBuf);          
618          return ROK;
619       }
620       if(lcId <= RG_DEDLC_MAX_LCID)
621       {
622          /* Extract the sdus */
623          if(rgDUXExtSdu(inst,pdu,ceInfo, mBuf,lcId,subPduLen, err) != ROK)
624          {
625             /* Fix : syed rgDUXExtSdu would have segmented mBuf and hence
626              * will be responsible for freeing mBuf */
627             *mBuf = NULLP;
628             RLOG0(L_ERROR, "failed to Extract the sdus");
629             return RFAILED;
630          }
631          if(*mBuf == NULLP) /* if message read completes then return */
632          {
633             return ROK;
634          }
635       }
636       else
637       {
638          /* Extract the ces */
639          if(rgDUXExtCe(inst,pdu,ceInfo,*mBuf, lcId,subPduLen, err) != ROK)
640          {
641             RG_FREE_MSG(*mBuf);       
642             RLOG0(L_ERROR, " failed to Extract the ces");
643             return RFAILED;
644          }
645       }
646       if(SFndLenMsg(*mBuf,&len) != ROK)
647       {
648          RG_FREE_MSG(*mBuf);
649          RLOG0(L_ERROR,"mBuf length check failed");
650          err->errCause = RGERR_DUX_UNPACK_FAILURE;
651          return RFAILED;
652       }
653    }while(len);
654
655    RG_FREE_MSG(*mBuf);
656    return ROK;
657 }  /* rgDUXDemuxData */
658
659 /**********************************************************************
660  
661          End of file
662 **********************************************************************/