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 /* header include files -- defines (.h) */
36 #include "common_def.h"
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 */
45 #include "rg.h" /* MAC defines */
46 #include "rg_err.h" /* MAC error defines */
48 /* header/extern include files (.x) */
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 */
58 #include "du_app_mac_inf.h"
59 #include "rg.x" /* MAC includes */
67 /* forward references */
69 #define RG_DUX_ALLOC(_pdu, _size, _dataPtr, _ret) {\
70 _ret = cmGetMem((Ptr)&_pdu->memCp, _size, (Ptr *)&_dataPtr); \
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); \
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; \
89 #define RG_UNPACK_LONG_BSR(_bsr, _mBuf, _ret) {\
90 _ret = SRemPreMsgMult((_bsr), 3, (_mBuf)); \
93 #define RG_UNPACK_SHORT_BSR(_bsr, _mBuf, _ret) {\
94 _ret = oduPackUInt8((_bsr), (_mBuf)); \
97 #define RG_UNPACK_TRUNC_BSR(_bsr, _mBuf, _ret) {\
98 _ret = oduPackUInt8((_bsr), (_mBuf)); \
101 #define RG_UNPACK_PHR(_phr, _mBuf, _ret) {\
102 _ret = oduPackUInt8((_phr), (_mBuf)); \
105 #define RG_UNPACK_CRNTI(_rnti, _mBuf, _ret) {\
108 _ret = SRemPreMsgMult(_unpkArray, (MsgLen) 2, _mBuf);\
111 *_rnti = (uint16_t) PutHiByte(*_rnti, (uint8_t) _unpkArray[0]);\
112 *_rnti = (uint16_t) PutLoByte(*_rnti, (uint8_t) _unpkArray[1]);\
116 /* For EXT PHR DEMUX */
117 #define RG_UNPACK_EXT_PHR_CI(_ci, _mBuf, _ret) {\
118 _ret = oduPackUInt8((_ci), (_mBuf)); \
121 #define RG_UNPACK_EXT_PHR(_extPhr, _mBuf, _ret) {\
122 _ret = oduPackUInt8((_extPhr), (_mBuf)); \
128 * @brief Handles the insertion of SDU in to PDU.
132 * Function: rgDUXInsSdu
134 * This API handles the insertion of SDU in to PDU.
137 * - Append the sdu to the sduLst of pdu.
139 * @param[in] Inst inst
148 static S16 rgDUXInsSdu(Inst inst, RgMacPdu *pdu, RgMacSdu **sdu, uint8_t lcId, uint16_t sduLen, RgErrInfo *err)
151 RgMacSdu *sduAloc = NULLP;
154 RG_DUX_ALLOC(pdu, sizeof(RgMacSdu), sduAloc, ret);
157 DU_LOG("\nERROR --> MAC : Allocation of RgSubHdr failed for LCID:%d",lcId);
158 err->errCause = RGERR_DUX_MEM_EXHAUST;
162 RG_INIT_SDU(sduAloc, lcId, sduLen);
163 cmLListAdd2Tail(&pdu->sduLst, &sduAloc->sduLstEnt);
168 * @brief Handles extracting the CE sub headers from the MAC PDU.
172 * Function: rgDUXExtSubHdr
174 * This API handles extracting the sub headers from the MAC PDU.
177 * - Extract the each sub header.
179 * @param[in] Inst inst
189 static S16 rgDUXExtSubHdr(Inst inst, RgMacPdu *pdu, Buffer *mBuf, uint8_t *lcId, uint16_t *len, RgErrInfo *err)
196 if(oduPackUInt8(&byte,mBuf) != ROK)
198 DU_LOG("\nERROR --> MAC : oduPackUInt8 failed");
199 err->errCause = RGERR_DUX_UNPACK_FAILURE;
202 /* Extract the lcid */
203 RG_EXT_LCID(*lcId, byte);
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)
211 DU_LOG("\nERROR --> MAC : oduPackUInt8 failed");
212 err->errCause = RGERR_DUX_UNPACK_FAILURE;
218 if(oduPackUInt8(&byte,mBuf) != ROK)
220 DU_LOG("\nERROR --> MAC : oduPackUInt8 failed");
221 err->errCause = RGERR_DUX_UNPACK_FAILURE;
224 *len = (*len << 8) | byte;
228 } /* rgDUXExtSubHdr */
231 * @brief Handles extracting the CEs from the MAC PDU.
235 * Function: rgDUXExtCe
237 * This API handles extracting the CEs from the MAC PDU.
240 * - Based on the ce sub header extract the ce.
242 * @param[in] Inst inst
243 * @param[in,out] *pdu
244 * @param[out] *ceInfo
247 * @param[in] subPduLen
253 static S16 rgDUXExtCe(Inst inst, RgMacPdu *pdu, RgInfCeInfo *ceInfo, Buffer *mBuf, uint8_t lcId, uint16_t subPduLen,\
261 case RG_EXT_PHR_LCID:
267 RgInfExtPhrCEInfo *extPhr;
269 RG_UNPACK_EXT_PHR_CI(&Ci,mBuf,ret);
272 DU_LOG("\nERROR --> MAC : Unpacking of EXT PHR failed LCID:%d",lcId);
273 err->errCause = RGERR_DUX_UNPACK_FAILURE;
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;
282 /* Setting first BIT as PCELL field even though reserved is always
285 for (sCellIdx = 0; (Ci && sCellIdx < CM_LTE_MAX_CELLS); sCellIdx++)
289 extPhr->servCellPhr[extPhr->numServCells].sCellIdx = sCellIdx;
290 RG_UNPACK_EXT_PHR(&extPhrOctet,mBuf,ret);
293 DU_LOG("\nERROR --> MAC : Unpacking of EXT PHR failed LCID:%d",lcId);
294 err->errCause = RGERR_DUX_UNPACK_FAILURE;
298 /* extPhrOctet: Bits : 7 6 5 4 3 2 1 0
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);
307 /* V: Virtual PCMAX or Real Tx PCMAX */
308 if (extPhrOctet & 0x40)
310 extPhr->servCellPhr[extPhr->numServCells].pCmax = RG_REF_PCMAX;
314 RG_UNPACK_EXT_PHR(&extPhrPCmax,mBuf,ret);
317 DU_LOG("\nERROR --> MAC : Unpacking of EXT PHR failed LCID:%d",lcId);
318 err->errCause = RGERR_DUX_UNPACK_FAILURE;
321 extPhr->servCellPhr[extPhr->numServCells].pCmax = (extPhrPCmax & 0x3F);
323 extPhr->numServCells++;
328 ceInfo->bitMask |= RG_EXT_PHR_CE_PRSNT;
334 RG_UNPACK_PHR(&ceInfo->ces.phr,mBuf,ret);
337 DU_LOG("\nERROR --> MAC : Unpacking of PHR failed LCID:%d",lcId);
338 err->errCause = RGERR_DUX_UNPACK_FAILURE;
341 ceInfo->bitMask |= RG_PHR_CE_PRSNT;
344 case RG_TRUNC_BSR_LCID:
346 RG_UNPACK_TRUNC_BSR(&ceInfo->ces.bsr.truncBsr,mBuf,ret);
349 DU_LOG("\nERROR --> MAC : Unpacking of Trunc BSR failed LCID:%d",lcId);
350 err->errCause = RGERR_DUX_UNPACK_FAILURE;
353 ceInfo->bitMask |= RG_TRUNC_BSR_CE_PRSNT;
356 case RG_SHORT_BSR_LCID:
358 RG_UNPACK_SHORT_BSR(&ceInfo->ces.bsr.shortBsr,mBuf,ret);
361 DU_LOG("\nERROR --> MAC : Unpacking of Short BSR failed LCID:%d",lcId);
362 err->errCause = RGERR_DUX_UNPACK_FAILURE;
365 ceInfo->bitMask |= RG_SHORT_BSR_CE_PRSNT;
368 case RG_LONG_BSR_LCID:
370 uint8_t longBsr[3] = {0}; /* KW_FIXX */
371 RG_UNPACK_LONG_BSR(longBsr,mBuf,ret);
374 DU_LOG("\nERROR --> MAC : Unpacking of Long BSR failed LCID:%d",lcId);
375 err->errCause = RGERR_DUX_UNPACK_FAILURE;
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;
388 RG_UNPACK_CRNTI(&ceInfo->ces.cRnti,mBuf,ret);
391 DU_LOG("\nERROR --> MAC : Unpacking of C-RNTI failed LCID:%d",lcId);
392 err->errCause = RGERR_DUX_UNPACK_FAILURE;
395 ceInfo->bitMask |= RG_CRNTI_CE_PRSNT;
399 DU_LOG("\nERROR --> MAC : Invalid LCID:%u received",lcId);
400 err->errCause = RGERR_DUX_INV_LCID_RX;
408 * @brief Handles extracting the SDU from the MAC PDU.
412 * Function: rgDUXExtSdu
414 * This API handles extracting the SDU corresponding to a logical channel.
417 * - Based on the length stored in the sub header extract the SDU.
419 * @param[in] Inst inst
420 * @param[in,out] *pdu
421 * @param[out] *ceInfo
424 * @param[in] subPduLen
430 static S16 rgDUXExtSdu(Inst inst, RgMacPdu *pdu, RgInfCeInfo *ceInfo, Buffer **mBuf, uint8_t lcId, uint16_t subPduLen,\
435 Buffer *tmpBuf2 = NULLP;
439 if(lcId == RG_CCCH_LCID)
441 ceInfo->bitMask |= RG_CCCH_SDU_PRSNT;
444 if(rgDUXInsSdu(inst,pdu, &sdu,lcId, subPduLen, err) != ROK)
452 ret = SSegMsg(tmpBuf1,subPduLen,&tmpBuf2);
453 if((ret != ROK) && (!((ret == ROKDNA) )))
455 RG_FREE_MSG(tmpBuf1);
456 DU_LOG("\nERROR --> MAC : SSegMsg failed");
457 err->errCause = RGERR_DUX_RLC_PDU_CREAT_FAIL;
467 * @brief Handles de-multiplexing of the data recieved at MAC.
471 * Function: rgDUXDemuxData
473 * This API handles de-multiplexing of the data recieved at MAC.
475 * Invoked by: rgTOMTfuDatInd of TOM
478 * - De-multiplex the mBuf
480 * @param[in] Inst inst
488 S16 rgDUXDemuxData(Inst inst, RgMacPdu *pdu, RgInfCeInfo *ceInfo, Buffer **mBuf, RgErrInfo *err)
494 ceInfo->bitMask = 0x0000;
496 /* Initialize the sdu list */
497 cmLListInit(&pdu->sduLst);
501 DU_LOG("\nERROR --> MAC : Null Buffer Recevived");
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)
513 DU_LOG("\nERROR --> MAC : Failed to extract pad sub headers");
516 if(lcId == RG_PAD_LCID)
517 { /*at end of MAC PDU, Padding started */
521 if(lcId <= RG_DEDLC_MAX_LCID)
523 /* Extract the sdus */
524 if(rgDUXExtSdu(inst,pdu,ceInfo, mBuf,lcId,subPduLen, err) != ROK)
526 /* Fix : syed rgDUXExtSdu would have segmented mBuf and hence
527 * will be responsible for freeing mBuf */
529 DU_LOG("\nERROR --> MAC : failed to Extract the sdus");
532 if(*mBuf == NULLP) /* if message read completes then return */
539 /* Extract the ces */
540 if(rgDUXExtCe(inst,pdu,ceInfo,*mBuf, lcId,subPduLen, err) != ROK)
543 DU_LOG("\nERROR --> MAC : failed to Extract the ces");
547 if(SFndLenMsg(*mBuf,&len) != ROK)
550 DU_LOG("\nERROR --> MAC : mBuf length check failed");
551 err->errCause = RGERR_DUX_UNPACK_FAILURE;
558 } /* rgDUXDemuxData */
560 /**********************************************************************
563 **********************************************************************/