1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 /************************************************************************
25 Desc: C source code for Entry point fucntions
29 **********************************************************************/
32 @brief This module handles de-multiplexing of the data recieved at MAC.
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 "envopt.h" /* environment options */
40 #include "envdep.h" /* environment dependent */
41 #include "envind.h" /* environment independent */
43 #include "gen.h" /* general */
44 #include "ssi.h" /* system services */
46 #include "cm_lte.h" /* Common LTE */
47 #include "cm_tkns.h" /* Common Token Defines */
48 #include "cm_llist.h" /* Common Link List Defines */
49 #include "cm_hash.h" /* Common Hash List Defines */
50 #include "cm_mblk.h" /* common memory link list library */
52 #include "rg_env.h" /* MAC Environment Defines */
53 #include "tfu.h" /* CRG Interface defines */
54 #include "crg.h" /* CRG Interface defines */
55 #include "rg_sch_inf.h" /* RGR Interface defines */
56 #include "rgu.h" /* RGU Interface defines */
57 #include "lrg.h" /* LRG Interface defines */
59 #include "rg.h" /* MAC defines */
60 #include "rg_err.h" /* MAC error defines */
62 /* header/extern include files (.x) */
63 #include "gen.x" /* general */
64 #include "ssi.x" /* system services */
65 #include "cm5.x" /* common timers */
66 #include "cm_lib.x" /* common library */
67 #include "cm_lte.x" /* Common LTE */
68 #include "cm_tkns.x" /* Common Token Definitions */
69 #include "cm_llist.x" /* Common Link List Definitions */
70 #include "cm_lib.x" /* Common Library Definitions */
71 #include "cm_hash.x" /* Common Hash List Definitions */
72 #include "cm_mblk.x" /* common memory link list library */
74 #include "rgu.x" /* RGU types */
75 #include "tfu.x" /* CRG Interface includes */
76 #include "crg.x" /* CRG Interface includes */
77 #include "rg_sch_inf.x" /* SCH Interface includes */
78 #include "rg_prg.x" /* PRG interface includes */
79 #include "rgu.x" /* RGU Interface includes */
80 #include "lrg.x" /* LRG Interface includes */
82 #include "du_app_mac_inf.h"
83 #include "rg.x" /* MAC includes */
91 /* forward references */
93 #define RG_DUX_ALLOC(_pdu, _size, _dataPtr, _ret) {\
94 _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
97 #define RG_INIT_SDU(_sdu, _lcId, _len) {\
98 (_sdu)->lcId = (_lcId); \
99 (_sdu)->len = (_len); \
100 (_sdu)->mBuf = NULLP; \
101 (_sdu)->sduLstEnt.next = NULLP; \
102 (_sdu)->sduLstEnt.prev = NULLP; \
103 (_sdu)->sduLstEnt.node = (PTR)(_sdu); \
106 #define RG_EXT_BS(_bsr, _bs1, _bs2, _bs3, _bs4) {\
107 _bs1 = _bsr[0] >> 2; \
108 _bs2 = (((_bsr[0] & 0x3) << 4) | (_bsr[1] >> 4)); \
109 _bs3 = (((_bsr[1] & 0x0F) << 2) | (_bsr[2] >> 6)); \
110 _bs4 = _bsr[2] & 0x3F; \
113 #define RG_UNPACK_LONG_BSR(_bsr, _mBuf, _ret) {\
114 _ret = SRemPreMsgMult((_bsr), 3, (_mBuf)); \
117 #define RG_UNPACK_SHORT_BSR(_bsr, _mBuf, _ret) {\
118 _ret = SUnpkU8((_bsr), (_mBuf)); \
121 #define RG_UNPACK_TRUNC_BSR(_bsr, _mBuf, _ret) {\
122 _ret = SUnpkU8((_bsr), (_mBuf)); \
125 #define RG_UNPACK_PHR(_phr, _mBuf, _ret) {\
126 _ret = SUnpkU8((_phr), (_mBuf)); \
129 #define RG_UNPACK_CRNTI(_rnti, _mBuf, _ret) {\
132 _ret = SRemPreMsgMult(_unpkArray, (MsgLen) 2, _mBuf);\
135 *_rnti = (U16) PutHiByte(*_rnti, (U8) _unpkArray[0]);\
136 *_rnti = (U16) PutLoByte(*_rnti, (U8) _unpkArray[1]);\
140 /* For EXT PHR DEMUX */
141 #define RG_UNPACK_EXT_PHR_CI(_ci, _mBuf, _ret) {\
142 _ret = SUnpkU8((_ci), (_mBuf)); \
145 #define RG_UNPACK_EXT_PHR(_extPhr, _mBuf, _ret) {\
146 _ret = SUnpkU8((_extPhr), (_mBuf)); \
152 * @brief Handles the insertion of SDU in to PDU.
156 * Function: rgDUXInsSdu
158 * This API handles the insertion of SDU in to PDU.
161 * - Append the sdu to the sduLst of pdu.
163 * @param[in] Inst inst
173 PRIVATE S16 rgDUXInsSdu
183 PRIVATE S16 rgDUXInsSdu(inst,pdu, sdu, lcId, sduLen, err)
193 RgMacSdu *sduAloc = NULLP;
197 RG_DUX_ALLOC(pdu, sizeof(RgMacSdu), sduAloc, ret);
200 RLOG1(L_ERROR, "Allocation of RgSubHdr failed for LCID:%d",lcId);
201 err->errCause = RGERR_DUX_MEM_EXHAUST;
205 RG_INIT_SDU(sduAloc, lcId, sduLen);
206 cmLListAdd2Tail(&pdu->sduLst, &sduAloc->sduLstEnt);
211 * @brief Handles extracting the CE sub headers from the MAC PDU.
215 * Function: rgDUXExtSubHdr
217 * This API handles extracting the sub headers from the MAC PDU.
220 * - Extract the each sub header.
222 * @param[in] Inst inst
233 PRIVATE S16 rgDUXExtSubHdr
243 PRIVATE S16 rgDUXExtSubHdr(inst,pdu, mBuf, lcId,
259 if(SUnpkU8(&byte,mBuf) != ROK)
261 RLOG0(L_ERROR, "SUnpkU8 failed");
262 err->errCause = RGERR_DUX_UNPACK_FAILURE;
265 /* Extract the lcid */
266 RG_EXT_LCID(*lcId, byte);
268 /*note: RG_EXT_PHR_LCID currently not considered */
269 if(*lcId <= RG_DEDLC_MAX_LCID)
270 { /* variable size MAC Sub PDU */
271 RG_EXT_FORMT_BIT(fmt,byte);
272 if(SUnpkU8(&byte, mBuf) != ROK)
274 RLOG0(L_ERROR, "SUnpkU8 failed");
275 err->errCause = RGERR_DUX_UNPACK_FAILURE;
281 if(SUnpkU8(&byte,mBuf) != ROK)
283 RLOG0(L_ERROR, "SUnpkU8 failed");
284 err->errCause = RGERR_DUX_UNPACK_FAILURE;
287 *len = (*len << 8) | byte;
291 } /* rgDUXExtSubHdr */
294 * @brief Handles extracting the CEs from the MAC PDU.
298 * Function: rgDUXExtCe
300 * This API handles extracting the CEs from the MAC PDU.
303 * - Based on the ce sub header extract the ce.
305 * @param[in] Inst inst
306 * @param[in,out] *pdu
307 * @param[out] *ceInfo
310 * @param[in] subPduLen
317 PRIVATE S16 rgDUXExtCe
328 PRIVATE S16 rgDUXExtCe(inst,pdu, ceInfo, mBuf,lcId,subPduLen, err)
344 case RG_EXT_PHR_LCID:
350 RgInfExtPhrCEInfo *extPhr;
352 RG_UNPACK_EXT_PHR_CI(&Ci,mBuf,ret);
355 RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
356 err->errCause = RGERR_DUX_UNPACK_FAILURE;
360 /* Not handling Type 2 PHR report as simultaneous PUSCH/PUCCH
361 is not supported as of now */
362 extPhr = &ceInfo->ces.extPhr;
363 extPhr->numServCells = 0;
365 /* Setting first BIT as PCELL field even though reserved is always
368 for (sCellIdx = 0; (Ci && sCellIdx < CM_LTE_MAX_CELLS); sCellIdx++)
372 extPhr->servCellPhr[extPhr->numServCells].sCellIdx = sCellIdx;
373 RG_UNPACK_EXT_PHR(&extPhrOctet,mBuf,ret);
376 RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
377 err->errCause = RGERR_DUX_UNPACK_FAILURE;
381 /* extPhrOctet: Bits : 7 6 5 4 3 2 1 0
385 /* P : P Back off applied or not */
386 extPhr->servCellPhr[extPhr->numServCells].phr = (extPhrOctet & 0x3F);
387 extPhr->servCellPhr[extPhr->numServCells].pBackOff =
388 ((extPhrOctet >> 7) & 0x01);
390 /* V: Virtual PCMAX or Real Tx PCMAX */
391 if (extPhrOctet & 0x40)
393 extPhr->servCellPhr[extPhr->numServCells].pCmax = RG_REF_PCMAX;
397 RG_UNPACK_EXT_PHR(&extPhrPCmax,mBuf,ret);
400 RLOG1(L_ERROR,"Unpacking of EXT PHR failed LCID:%d",lcId);
401 err->errCause = RGERR_DUX_UNPACK_FAILURE;
404 extPhr->servCellPhr[extPhr->numServCells].pCmax = (extPhrPCmax & 0x3F);
406 extPhr->numServCells++;
411 ceInfo->bitMask |= RG_EXT_PHR_CE_PRSNT;
417 RG_UNPACK_PHR(&ceInfo->ces.phr,mBuf,ret);
420 RLOG1(L_ERROR,"Unpacking of PHR failed LCID:%d",lcId);
421 err->errCause = RGERR_DUX_UNPACK_FAILURE;
424 ceInfo->bitMask |= RG_PHR_CE_PRSNT;
427 case RG_TRUNC_BSR_LCID:
429 RG_UNPACK_TRUNC_BSR(&ceInfo->ces.bsr.truncBsr,mBuf,ret);
432 RLOG1(L_ERROR,"Unpacking of Trunc BSR failed LCID:%d",lcId);
433 err->errCause = RGERR_DUX_UNPACK_FAILURE;
436 ceInfo->bitMask |= RG_TRUNC_BSR_CE_PRSNT;
439 case RG_SHORT_BSR_LCID:
441 RG_UNPACK_SHORT_BSR(&ceInfo->ces.bsr.shortBsr,mBuf,ret);
444 RLOG1(L_ERROR,"Unpacking of Short BSR failed LCID:%d",lcId);
445 err->errCause = RGERR_DUX_UNPACK_FAILURE;
448 ceInfo->bitMask |= RG_SHORT_BSR_CE_PRSNT;
451 case RG_LONG_BSR_LCID:
453 U8 longBsr[3] = {0}; /* KW_FIXX */
454 RG_UNPACK_LONG_BSR(longBsr,mBuf,ret);
457 RLOG1(L_ERROR,"Unpacking of Long BSR failed LCID:%d",lcId);
458 err->errCause = RGERR_DUX_UNPACK_FAILURE;
462 ceInfo->ces.bsr.longBsr.bs1,
463 ceInfo->ces.bsr.longBsr.bs2,
464 ceInfo->ces.bsr.longBsr.bs3,
465 ceInfo->ces.bsr.longBsr.bs4);
466 ceInfo->bitMask |= RG_LONG_BSR_CE_PRSNT;
471 RG_UNPACK_CRNTI(&ceInfo->ces.cRnti,mBuf,ret);
474 RLOG1(L_ERROR,"Unpacking of C-RNTI failed LCID:%d",lcId);
475 err->errCause = RGERR_DUX_UNPACK_FAILURE;
478 ceInfo->bitMask |= RG_CRNTI_CE_PRSNT;
482 RLOG1(L_ERROR, "Invalid LCID:%u received",lcId);
483 err->errCause = RGERR_DUX_INV_LCID_RX;
491 * @brief Handles extracting the SDU from the MAC PDU.
495 * Function: rgDUXExtSdu
497 * This API handles extracting the SDU corresponding to a logical channel.
500 * - Based on the length stored in the sub header extract the SDU.
502 * @param[in] Inst inst
503 * @param[in,out] *pdu
504 * @param[out] *ceInfo
507 * @param[in] subPduLen
514 PRIVATE S16 rgDUXExtSdu
525 PRIVATE S16 rgDUXExtSdu(inst,pdu, ceInfo,mBuf,lcId,subPduLen,err)
537 Buffer *tmpBuf2 = NULLP;
542 if(lcId == RG_CCCH_LCID)
544 ceInfo->bitMask |= RG_CCCH_SDU_PRSNT;
547 if(rgDUXInsSdu(inst,pdu, &sdu,lcId, subPduLen, err) != ROK)
555 ret = SSegMsg(tmpBuf1,subPduLen,&tmpBuf2);
556 if((ret != ROK) && (!((ret == ROKDNA) )))
558 RG_FREE_MSG(tmpBuf1);
559 RLOG0(L_ERROR,"SSegMsg failed");
560 err->errCause = RGERR_DUX_RLC_PDU_CREAT_FAIL;
570 * @brief Handles de-multiplexing of the data recieved at MAC.
574 * Function: rgDUXDemuxData
576 * This API handles de-multiplexing of the data recieved at MAC.
578 * Invoked by: rgTOMTfuDatInd of TOM
581 * - De-multiplex the mBuf
583 * @param[in] Inst inst
592 PUBLIC S16 rgDUXDemuxData
601 PUBLIC S16 rgDUXDemuxData(inst,pdu, ceInfo, mBuf, err)
614 ceInfo->bitMask = 0x0000;
616 /* Initialize the sdu list */
617 cmLListInit(&pdu->sduLst);
621 RLOG0(L_ERROR, "Null Buffer Recevived");
626 /* UL Message format order :
627 PduSubHdr+SubPDU,PduSubHdr+SubPDU,...CeSubHdr+Ce,CeSubPdu+Ce,...,PADSubHdr+PAD */
628 /* Extract the Sub headers */
629 if(rgDUXExtSubHdr(inst,pdu, *mBuf, &lcId,
630 &subPduLen, err) != ROK)
633 RLOG0(L_ERROR, "Failed to extract pad sub headers");
636 if(lcId == RG_PAD_LCID)
637 { /*at end of MAC PDU, Padding started */
641 if(lcId <= RG_DEDLC_MAX_LCID)
643 /* Extract the sdus */
644 if(rgDUXExtSdu(inst,pdu,ceInfo, mBuf,lcId,subPduLen, err) != ROK)
646 /* Fix : syed rgDUXExtSdu would have segmented mBuf and hence
647 * will be responsible for freeing mBuf */
649 RLOG0(L_ERROR, "failed to Extract the sdus");
652 if(*mBuf == NULLP) /* if message read completes then return */
659 /* Extract the ces */
660 if(rgDUXExtCe(inst,pdu,ceInfo,*mBuf, lcId,subPduLen, err) != ROK)
663 RLOG0(L_ERROR, " failed to Extract the ces");
667 if(SFndLenMsg(*mBuf,&len) != ROK)
670 RLOG0(L_ERROR,"mBuf length check failed");
671 err->errCause = RGERR_DUX_UNPACK_FAILURE;
678 } /* rgDUXDemuxData */
680 /**********************************************************************
683 **********************************************************************/