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 *******************************************************************************/
20 /* header include files -- defines (.h) */
21 #include "common_def.h"
22 #include "lrg.h" /* Layer manager interface includes*/
23 #include "lrg.x" /* layer management typedefs for MAC */
24 #include "du_app_mac_inf.h"
25 #include "mac_sch_interface.h"
26 #include "lwr_mac_upr_inf.h"
28 #include "mac_utils.h"
30 /*******************************************************************
32 * @brief pack the bits
36 * Function : packBytes
39 * pack the bits in the corresponding byte
41 * @params[in] buffer pointer, byte and bit position, value and its size
44 * ****************************************************************/
45 void packBytes(uint8_t *buf, uint16_t *bytePos, uint8_t *bitPos, uint32_t val, uint8_t valSize)
50 uint8_t bytePart1Size;
51 uint32_t bytePart2Size;
53 if(*bitPos - valSize + 1 >= 0)
55 bytePart1 = (uint8_t)val;
56 bytePart1 = (bytePart1 << (*bitPos -valSize +1));
57 buf[*bytePos] |= bytePart1;
58 if(*bitPos - valSize < 0)
69 bytePart1Size = *bitPos +1;
70 bytePart2Size = valSize - bytePart1Size;
72 bytePart1 = (val >> bytePart2Size) << (*bitPos -bytePart1Size +1);
73 bytePart2 = (~((~temp) << bytePart2Size)) & val;
75 buf[*bytePos] |= bytePart1;
78 packBytes(buf, bytePos, bitPos, bytePart2, bytePart2Size);
82 /*******************************************************************
84 * @brief fill the RAR PDU
88 * Function : fillRarPdu
91 * The RAR PDU will be MUXed and formed
93 * @params[in] RAR info
96 * ****************************************************************/
97 void fillRarPdu(RarInfo *rarInfo)
99 uint8_t *rarPdu = rarInfo->rarPdu;
101 uint16_t bytePos= 0, bwpSize = 0, rbStart = 0, rbLen = 0;
102 uint8_t numHopInfoBitsInFreqAlloc = 0;
103 uint8_t actualFreqRsrcAllocSize = 0;
105 /* RAR subheader fields */
109 /* RAR payload fields */
111 uint16_t msg3FreqResource = 0;
112 uint8_t paddingLcid = 63;
114 /* Considering 2 bytes of padding in RAR PDU.
115 * 1st byte is MAC sub-header for padding
116 * 2nd byte contains padding bits
118 uint8_t paddingSize = 8;
120 /* Fill RAR pdu fields */
125 rarInfo->rarPduLen = RAR_PAYLOAD_SIZE;
127 /* Initialize buffer */
128 for(bytePos = 0; bytePos < rarInfo->rarPduLen; bytePos++)
134 /* Packing fields into RAR PDU */
135 packBytes(rarPdu, &bytePos, &bitPos, EBit, E_BIT_SIZE);
136 packBytes(rarPdu, &bytePos, &bitPos, TBit, T_BIT_SIZE);
137 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->RAPID, RAPID_SIZE);
138 packBytes(rarPdu, &bytePos, &bitPos, RBit, R_BIT_SIZE);
139 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ta, TIMING_ADVANCE_SIZE);
141 /* Packing MSG3 UL Grant in RAR */
142 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.freqHopFlag, FREQ_HOP_FLAG_SIZE);
144 /* Calculating freq domain resource allocation field value
145 * bwpSize = Size of BWP
146 * RBStart = Starting Resource block
147 * RBLen = length of contiguously allocted RBs
148 * Spec 38.214 Sec 6.1.2.2.2
150 bwpSize = rarInfo->ulGrant.bwpSize;
151 rbStart = rarInfo->ulGrant.msg3FreqAlloc.startPrb;
152 rbLen = rarInfo->ulGrant.msg3FreqAlloc.numPrb;
154 if((rbLen >=1) && (rbLen <= bwpSize - rbStart))
156 if((rbLen - 1) <= floor(bwpSize / 2))
157 msg3FreqResource = (bwpSize * (rbLen-1)) + rbStart;
159 msg3FreqResource = (bwpSize * (bwpSize - rbLen + 1)) \
160 + (bwpSize - 1 - rbStart);
163 /* Calculating frequency domain resource allocation field size
164 * and packing frequency domain resource allocation accordingly
165 * Spec 38.213 Sec 8.3
169 actualFreqRsrcAllocSize = ceil(log2(bwpSize * (bwpSize + 1) / 2));
170 packBytes(rarPdu, &bytePos, &bitPos, 0, FREQ_RSRC_ALLOC_SIZE - actualFreqRsrcAllocSize);
171 packBytes(rarPdu, &bytePos, &bitPos, msg3FreqResource, actualFreqRsrcAllocSize);
175 if(rarInfo->ulGrant.freqHopFlag == 0)
177 numHopInfoBitsInFreqAlloc = 1;
178 packBytes(rarPdu, &bytePos, &bitPos, 0, numHopInfoBitsInFreqAlloc);
180 actualFreqRsrcAllocSize = abs(log2(bwpSize * (bwpSize + 1) / 2));
181 packBytes(rarPdu, &bytePos, &bitPos, 0, actualFreqRsrcAllocSize - FREQ_RSRC_ALLOC_SIZE);
182 packBytes(rarPdu, &bytePos, &bitPos, msg3FreqResource, \
183 actualFreqRsrcAllocSize - numHopInfoBitsInFreqAlloc);
187 /* TODO : If frequency hopping is supported,
188 * Fetch the Number of bits to store hopping information in frequency
189 * resource allocation field and the value to be filled from Spec 38.213, Table 8.3-1.
190 * Fill the frequency resource allocation field as described in Spec 38.213 sec 8.3
195 /* Packing time domain resource allocation for UL grant */
196 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.k2Index, TIME_RSRC_ALLOC_SIZE);
198 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.mcs, MCS_SIZE);
199 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.tpc, TPC_COMMAND_SIZE);
200 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.csiReq, CSI_REQUEST_SIZE);
202 packBytes(rarPdu, &bytePos, &bitPos, rarInfo->tcrnti, T_CRNTI_SIZE);
204 /* padding of 2 bytes */
205 packBytes(rarPdu, &bytePos, &bitPos, RBit, R_BIT_SIZE*2);
206 packBytes(rarPdu, &bytePos, &bitPos, paddingLcid, LC_ID_SIZE);
207 packBytes(rarPdu, &bytePos, &bitPos, 0, paddingSize);
211 /*******************************************************************
213 * @brief Database required to form MAC PDU
217 * Function : createMacRaCb
220 * stores the required params for muxing
222 * @params[in] Pointer to cellId,
226 * ****************************************************************/
227 void createMacRaCb(RachIndInfo *rachIndInfo)
231 uint16_t cellIdx = 0;
233 GET_CELL_IDX(rachIndInfo->cellId, cellIdx);
235 ueIdx = getFreeBitFromUeBitMap(rachIndInfo->cellId);
238 DU_LOG("\nERROR --> MAC : Failed to find free UE Idx in UE bit map of cell Id [%d]", rachIndInfo->cellId);
242 /* Calculate CRNTI from UE Index */
243 GET_CRNTI(crnti, ueIdx+1);
245 /* store in rach ind structure */
246 rachIndInfo->crnti = crnti;
249 macCb.macCell[cellIdx]->macRaCb[ueIdx].cellId = rachIndInfo->cellId;
250 macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti = crnti;
253 /*************************************************
254 * @brief fill RLC DL Data
258 * Function : fillMsg4DlData
259 * This function sends Dl Data
262 * @param[in] MacDlData *dlData
264 ************************************************/
266 void fillMsg4DlData(MacDlData *dlData, uint16_t msg4PduLen, uint8_t *msg4Pdu)
268 dlData->pduInfo[dlData->numPdu].lcId = MAC_LCID_CCCH;
269 dlData->pduInfo[dlData->numPdu].pduLen = msg4PduLen;
270 memcpy(dlData->pduInfo[dlData->numPdu].dlPdu, msg4Pdu, msg4PduLen);
274 /*************************************************
275 * @brief fill Mac Ce Info
279 * Function : fillMacCe
280 * This function fills Mac ce identities
282 * @param[in] RlcMacData *dlData
284 ************************************************/
286 void fillMacCe(MacCeInfo *macCeInfo, uint8_t *msg3Pdu)
289 macCeInfo->numCes = 1;
290 for(idx = 0; idx < macCeInfo->numCes; idx++)
292 macCeInfo->macCe[idx].macCeLcid = MAC_LCID_CRI;
293 memcpy(macCeInfo->macCe[idx].macCeValue, \
294 msg3Pdu, MAX_CRI_SIZE);
298 /*******************************************************************
300 * @brief Forms MAC PDU
304 * Function : macMuxPdu
307 * The MAC PDU will be MUXed and formed
309 * @params[in] MacDlData *, MacCeInfo *, txPdu *, tbSize
311 * ****************************************************************/
313 void macMuxPdu(MacDlData *dlData, MacCeInfo *macCeData, uint8_t *txPdu, uint16_t tbSize)
315 uint16_t bytePos = 0;
318 uint8_t macPdu[tbSize];
319 memset(macPdu, 0, (tbSize * sizeof(uint8_t)));
321 /* subheader fields */
322 uint8_t RBit = 0; /* Reserved bit */
323 uint8_t FBit =0; /* Format Indicator */
324 uint8_t lcid =0; /* LCID */
325 uint16_t lenField = 0; /* Length field */
327 /* subheader field size (in bits) */
328 uint8_t RBitSize = 1;
329 uint8_t FBitSize = 1;
330 uint8_t lcidSize = 6;
331 uint8_t lenFieldSize = 0; /* 8-bit or 16-bit L field */
333 /* PACK ALL MAC CE */
334 if(macCeData != NULLP)
336 for(pduIdx = 0; pduIdx < macCeData->numCes; pduIdx++)
338 lcid = macCeData->macCe[pduIdx].macCeLcid;
343 /* Packing fields into MAC PDU R/R/LCID */
344 packBytes(macPdu, &bytePos, &bitPos, RBit, (RBitSize * 2));
345 packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
346 memcpy(&macPdu[bytePos], macCeData->macCe[pduIdx].macCeValue,\
348 bytePos += MAX_CRI_SIZE;
352 DU_LOG("\nERROR --> MAC: Invalid LCID %d in mac pdu",lcid);
358 /* PACK ALL MAC SDUs */
359 for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
361 lcid = dlData->pduInfo[pduIdx].lcId;
365 case MAC_LCID_MIN ... MAC_LCID_MAX :
367 lenField = dlData->pduInfo[pduIdx].pduLen;
368 if(dlData->pduInfo[pduIdx].pduLen > 255)
379 /* Packing fields into MAC PDU R/F/LCID/L */
380 packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
381 packBytes(macPdu, &bytePos, &bitPos, FBit, FBitSize);
382 packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
383 packBytes(macPdu, &bytePos, &bitPos, lenField, lenFieldSize);
384 memcpy(&macPdu[bytePos], dlData->pduInfo[pduIdx].dlPdu, lenField);
390 DU_LOG("\nERROR --> MAC: Invalid LCID %d in mac pdu",lcid);
394 if(bytePos < tbSize && (tbSize-bytePos >= 1))
396 /* padding remaining bytes */
398 lcid = MAC_LCID_PADDING;
399 packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
400 packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
403 /*Storing the muxed pdu */
406 memcpy(txPdu, macPdu, tbSize);
410 /**********************************************************************
412 **********************************************************************/