################################################################################
*******************************************************************************/
-#include <stdlib.h>
-#include <stdint.h>
/* header include files -- defines (.h) */
-#include "envopt.h" /* environment options */
-#include "envdep.h" /* environment dependent */
-#include "envind.h" /* environment independent */
-#include "gen.h" /* general layer */
-#include "ssi.h" /* system service interface */
-#include "cm_hash.h" /* common hash list */
-#include "cm_mblk.h" /* common memory link list library */
-#include "cm_llist.h" /* common linked list library */
-#include "cm_err.h" /* common error */
-#include "cm_lte.h" /* common LTE */
+#include "common_def.h"
#include "lrg.h" /* Layer manager interface includes*/
-#include "crg.h" /* CRG interface includes*/
-#include "rgu.h" /* RGU interface includes*/
-#include "tfu.h" /* TFU interface includes */
-#include "rg_sch_inf.h" /* SCH interface includes */
-#include "rg_prg.h" /* PRG (MAC-MAC) interface includes*/
-#include "rg_env.h" /* MAC environmental includes*/
-#include "rg.h" /* MAC includes*/
-#include "rg_err.h" /* MAC error includes*/
-#include "du_log.h"
-
-/* header/extern include files (.x) */
-#include "gen.x" /* general layer typedefs */
-#include "ssi.x" /* system services typedefs */
-#include "cm5.x" /* common timers */
-#include "cm_hash.x" /* common hash list */
-#include "cm_lib.x" /* common library */
-#include "cm_llist.x" /* common linked list */
-#include "cm_mblk.x" /* memory management */
-#include "cm_tkns.x" /* common tokens */
-#include "cm_lte.x" /* common tokens */
-#include "rgu.x" /* RGU types */
-#include "tfu.x" /* RGU types */
#include "lrg.x" /* layer management typedefs for MAC */
-#include "crg.x" /* CRG interface includes */
-#include "rg_sch_inf.x" /* SCH interface typedefs */
-#include "rg_prg.x" /* PRG (MAC-MAC) Interface typedefs */
#include "du_app_mac_inf.h"
+#include "mac_sch_interface.h"
+#include "lwr_mac_upr_inf.h"
#include "mac.h"
-#include "rg.x" /* typedefs for MAC */
+#include "mac_utils.h"
-void packBytes(uint8_t *buf, uint8_t *bytePos, uint8_t *bitPos, uint32_t val, uint8_t valSize)
+/*******************************************************************
+ *
+ * @brief pack the bits
+ *
+ * @details
+ *
+ * Function : packBytes
+ *
+ * Functionality:
+ * pack the bits in the corresponding byte
+ *
+ * @params[in] buffer pointer, byte and bit position, value and its size
+ * @return void
+ *
+ * ****************************************************************/
+void packBytes(uint8_t *buf, uint16_t *bytePos, uint8_t *bitPos, uint32_t val, uint8_t valSize)
{
uint32_t temp;
uint8_t bytePart1;
uint32_t bytePart2;
uint8_t bytePart1Size;
uint32_t bytePart2Size;
-
+
if(*bitPos - valSize + 1 >= 0)
{
bytePart1 = (uint8_t)val;
buf[*bytePos] |= bytePart1;
if(*bitPos - valSize < 0)
{
- *bitPos = 7;
- (*bytePos)++;
+ *bitPos = 7;
+ (*bytePos)++;
}
else
- *bitPos -= valSize;
+ *bitPos -= valSize;
}
else
{
bytePart1 = (val >> bytePart2Size) << (*bitPos -bytePart1Size +1);
bytePart2 = (~((~temp) << bytePart2Size)) & val;
-
+
buf[*bytePos] |= bytePart1;
(*bytePos)++;
*bitPos = 7;
}
}
+/*******************************************************************
+ *
+ * @brief fill the RAR PDU
+ *
+ * @details
+ *
+ * Function : fillRarPdu
+ *
+ * Functionality:
+ * The RAR PDU will be MUXed and formed
+ *
+ * @params[in] RAR info
+ * @return void
+ *
+ * ****************************************************************/
void fillRarPdu(RarInfo *rarInfo)
{
uint8_t *rarPdu = rarInfo->rarPdu;
- uint16_t totalBits;
- uint8_t numBytes;
- uint8_t bytePos;
- uint8_t bitPos;
+ uint8_t bitPos = 0;
+ uint16_t bytePos= 0, bwpSize = 0, rbStart = 0, rbLen = 0;
+ uint8_t numHopInfoBitsInFreqAlloc = 0;
+ uint8_t actualFreqRsrcAllocSize = 0;
/* RAR subheader fields */
- uint8_t EBit;
- uint8_t TBit;
- uint8_t rapId;
+ uint8_t EBit = 0;
+ uint8_t TBit = 0;
/* RAR payload fields */
- uint8_t RBit;
- uint16_t timeAdv;
- uint32_t ulGrant;
- uint16_t tmpCrnti;
-
- /* Size(in bits) of RAR subheader files */
- uint8_t EBitSize = 1;
- uint8_t TBitSize = 1;
- uint8_t rapidSize = 6;
-
- /* Size(in bits) of RAR payload fields */
- uint8_t RBitSize = 1;
- uint8_t timeAdvSize = 12;
- uint8_t ulGrantSize = 27;
- uint8_t tmpCrntiSize = 16;
+ uint8_t RBit = 0;
+ uint16_t msg3FreqResource = 0;
+ uint8_t paddingLcid = 63;
+
+ /* Considering 2 bytes of padding in RAR PDU.
+ * 1st byte is MAC sub-header for padding
+ * 2nd byte contains padding bits
+ */
+ uint8_t paddingSize = 8;
/* Fill RAR pdu fields */
EBit = 0;
TBit = 1;
- rapId = rarInfo->RAPID;
-
RBit = 0;
- timeAdv = rarInfo->ta;
- ulGrant = 0; /* this will be done when implementing msg3 */
- tmpCrnti = rarInfo->tcrnti;
-
- /* Calulating total number of bytes in buffer */
- totalBits = EBitSize + TBitSize + rapidSize + RBitSize + timeAdvSize \
- + ulGrantSize + tmpCrntiSize;
-
- /* Calulating total number of bytes in buffer */
- numBytes = totalBits/8;
- if(totalBits % 8)
- numBytes += 1;
-
- rarInfo->rarPduLen = numBytes;
+
+ rarInfo->rarPduLen = RAR_PAYLOAD_SIZE;
/* Initialize buffer */
- for(bytePos = 0; bytePos < numBytes; bytePos++)
+ for(bytePos = 0; bytePos < rarInfo->rarPduLen; bytePos++)
rarPdu[bytePos] = 0;
-
+
bytePos = 0;
bitPos = 7;
/* Packing fields into RAR PDU */
- packBytes(rarPdu, &bytePos, &bitPos, EBit, EBitSize);
- packBytes(rarPdu, &bytePos, &bitPos, TBit, TBitSize);
- packBytes(rarPdu, &bytePos, &bitPos, rapId, rapidSize);
- packBytes(rarPdu, &bytePos, &bitPos, RBit, RBitSize);
- packBytes(rarPdu, &bytePos, &bitPos, timeAdv, timeAdvSize);
- packBytes(rarPdu, &bytePos, &bitPos, ulGrant, ulGrantSize);
- packBytes(rarPdu, &bytePos, &bitPos, tmpCrnti, tmpCrntiSize);
+ packBytes(rarPdu, &bytePos, &bitPos, EBit, E_BIT_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, TBit, T_BIT_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->RAPID, RAPID_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, RBit, R_BIT_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ta, TIMING_ADVANCE_SIZE);
+
+ /* Packing MSG3 UL Grant in RAR */
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.freqHopFlag, FREQ_HOP_FLAG_SIZE);
+
+ /* Calculating freq domain resource allocation field value
+ * bwpSize = Size of BWP
+ * RBStart = Starting Resource block
+ * RBLen = length of contiguously allocted RBs
+ * Spec 38.214 Sec 6.1.2.2.2
+ */
+ bwpSize = rarInfo->ulGrant.bwpSize;
+ rbStart = rarInfo->ulGrant.msg3FreqAlloc.startPrb;
+ rbLen = rarInfo->ulGrant.msg3FreqAlloc.numPrb;
+
+ if((rbLen >=1) && (rbLen <= bwpSize - rbStart))
+ {
+ if((rbLen - 1) <= floor(bwpSize / 2))
+ msg3FreqResource = (bwpSize * (rbLen-1)) + rbStart;
+ else
+ msg3FreqResource = (bwpSize * (bwpSize - rbLen + 1)) \
+ + (bwpSize - 1 - rbStart);
+ }
+
+ /* Calculating frequency domain resource allocation field size
+ * and packing frequency domain resource allocation accordingly
+ * Spec 38.213 Sec 8.3
+ */
+ if(bwpSize < 180)
+ {
+ actualFreqRsrcAllocSize = ceil(log2(bwpSize * (bwpSize + 1) / 2));
+ packBytes(rarPdu, &bytePos, &bitPos, 0, FREQ_RSRC_ALLOC_SIZE - actualFreqRsrcAllocSize);
+ packBytes(rarPdu, &bytePos, &bitPos, msg3FreqResource, actualFreqRsrcAllocSize);
+ }
+ else
+ {
+ if(rarInfo->ulGrant.freqHopFlag == 0)
+ {
+ numHopInfoBitsInFreqAlloc = 1;
+ packBytes(rarPdu, &bytePos, &bitPos, 0, numHopInfoBitsInFreqAlloc);
+
+ actualFreqRsrcAllocSize = abs(log2(bwpSize * (bwpSize + 1) / 2));
+ packBytes(rarPdu, &bytePos, &bitPos, 0, actualFreqRsrcAllocSize - FREQ_RSRC_ALLOC_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, msg3FreqResource, \
+ actualFreqRsrcAllocSize - numHopInfoBitsInFreqAlloc);
+ }
+ else
+ {
+ /* TODO : If frequency hopping is supported,
+ * Fetch the Number of bits to store hopping information in frequency
+ * resource allocation field and the value to be filled from Spec 38.213, Table 8.3-1.
+ * Fill the frequency resource allocation field as described in Spec 38.213 sec 8.3
+ */
+ }
+ }
+
+ /* Packing time domain resource allocation for UL grant */
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.k2Index, TIME_RSRC_ALLOC_SIZE);
+
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.mcs, MCS_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.tpc, TPC_COMMAND_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.csiReq, CSI_REQUEST_SIZE);
+
+ packBytes(rarPdu, &bytePos, &bitPos, rarInfo->tcrnti, T_CRNTI_SIZE);
+
+ /* padding of 2 bytes */
+ packBytes(rarPdu, &bytePos, &bitPos, RBit, R_BIT_SIZE*2);
+ packBytes(rarPdu, &bytePos, &bitPos, paddingLcid, LC_ID_SIZE);
+ packBytes(rarPdu, &bytePos, &bitPos, 0, paddingSize);
+
+}
+
+/*************************************************
+ * @brief fill RLC DL Data
+ *
+ * @details
+ *
+ * Function : fillMsg4DlData
+ * This function sends Dl Data
+ * to form MAC SDUs
+ *
+ * @param[in] MacDlData *dlData
+ * msg4Pdu pointer
+ ************************************************/
+
+void fillMsg4DlData(MacDlData *dlData, uint16_t msg4PduLen, uint8_t *msg4Pdu)
+{
+ dlData->pduInfo[dlData->numPdu].lcId = MAC_LCID_CCCH;
+ dlData->pduInfo[dlData->numPdu].pduLen = msg4PduLen;
+ memcpy(dlData->pduInfo[dlData->numPdu].dlPdu, msg4Pdu, msg4PduLen);
+ dlData->numPdu++;
+}
+
+/*************************************************
+ * @brief fill Mac Ce Info
+ *
+ * @details
+ *
+ * Function : fillMacCe
+ * This function fills Mac ce identities
+ *
+ * @param[in] RlcMacData *dlData
+ * Msg3Pdu Data
+ ************************************************/
+
+void fillMacCe(MacCeInfo *macCeInfo, uint8_t *msg3Pdu)
+{
+ uint8_t idx;
+ macCeInfo->numCes = 1;
+ for(idx = 0; idx < macCeInfo->numCes; idx++)
+ {
+ macCeInfo->macCe[idx].macCeLcid = MAC_LCID_CRI;
+ memcpy(macCeInfo->macCe[idx].macCeValue, \
+ msg3Pdu, MAX_CRI_SIZE);
+ }
+}
+
+/*******************************************************************
+ *
+ * @brief Forms MAC PDU
+ *
+ * @details
+ *
+ * Function : macMuxPdu
+ *
+ * Functionality:
+ * The MAC PDU will be MUXed and formed
+ *
+ * @params[in] MacDlData *, MacCeInfo *, txPdu *, tbSize
+ * @return void
+ * ****************************************************************/
+
+void macMuxPdu(MacDlData *dlData, MacCeInfo *macCeData, uint8_t *txPdu, uint16_t tbSize)
+{
+ uint16_t bytePos = 0;
+ uint8_t bitPos = 7;
+ uint8_t pduIdx = 0;
+ uint8_t macPdu[tbSize];
+ memset(macPdu, 0, (tbSize * sizeof(uint8_t)));
+
+ /* subheader fields */
+ uint8_t RBit = 0; /* Reserved bit */
+ uint8_t FBit =0; /* Format Indicator */
+ uint8_t lcid =0; /* LCID */
+ uint16_t lenField = 0; /* Length field */
+
+ /* subheader field size (in bits) */
+ uint8_t RBitSize = 1;
+ uint8_t FBitSize = 1;
+ uint8_t lcidSize = 6;
+ uint8_t lenFieldSize = 0; /* 8-bit or 16-bit L field */
+
+ /* PACK ALL MAC CE */
+ if(macCeData != NULLP)
+ {
+ for(pduIdx = 0; pduIdx < macCeData->numCes; pduIdx++)
+ {
+ lcid = macCeData->macCe[pduIdx].macCeLcid;
+ switch(lcid)
+ {
+ case MAC_LCID_CRI:
+ {
+ /* Packing fields into MAC PDU R/R/LCID */
+ packBytes(macPdu, &bytePos, &bitPos, RBit, (RBitSize * 2));
+ packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
+ memcpy(&macPdu[bytePos], macCeData->macCe[pduIdx].macCeValue,\
+ MAX_CRI_SIZE);
+ bytePos += MAX_CRI_SIZE;
+ break;
+ }
+ default:
+ DU_LOG("\nERROR --> MAC: Invalid LCID %d in mac pdu",lcid);
+ break;
+ }
+ }
+ }
+
+ /* PACK ALL MAC SDUs */
+ for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
+ {
+ lcid = dlData->pduInfo[pduIdx].lcId;
+ switch(lcid)
+ {
+ case MAC_LCID_CCCH:
+ case MAC_LCID_MIN ... MAC_LCID_MAX :
+ {
+ lenField = dlData->pduInfo[pduIdx].pduLen;
+ if(dlData->pduInfo[pduIdx].pduLen > 255)
+ {
+ FBit = 1;
+ lenFieldSize = 16;
+
+ }
+ else
+ {
+ FBit = 0;
+ lenFieldSize = 8;
+ }
+ /* Packing fields into MAC PDU R/F/LCID/L */
+ packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
+ packBytes(macPdu, &bytePos, &bitPos, FBit, FBitSize);
+ packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
+ packBytes(macPdu, &bytePos, &bitPos, lenField, lenFieldSize);
+ memcpy(&macPdu[bytePos], dlData->pduInfo[pduIdx].dlPdu, lenField);
+ bytePos += lenField;
+ break;
+ }
+
+ default:
+ DU_LOG("\nERROR --> MAC: Invalid LCID %d in mac pdu",lcid);
+ break;
+ }
+ }
+ if(bytePos < tbSize && (tbSize-bytePos >= 1))
+ {
+ /* padding remaining bytes */
+ RBitSize = 2;
+ lcid = MAC_LCID_PADDING;
+ packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
+ packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
+ }
+
+ /*Storing the muxed pdu */
+ if(txPdu != NULLP)
+ {
+ memcpy(txPdu, macPdu, tbSize);
+ }
}
/**********************************************************************