Cell down alarm notification [Issue-Id: ODUHIGH-430]
[o-du/l2.git] / src / 5gnrmac / mac_mux.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 /* 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"
27 #include "mac.h"
28 #include "mac_utils.h"
29
30 /*******************************************************************
31  *
32  * @brief pack the bits
33  *
34  * @details
35  *
36  *    Function : packBytes
37  *
38  *    Functionality:
39  *     pack the bits in the corresponding byte
40  *
41  * @params[in] buffer pointer, byte and bit position, value and its size
42  * @return void
43  *
44  * ****************************************************************/
45 void packBytes(uint8_t *buf, uint16_t *bytePos, uint8_t *bitPos, uint32_t val, uint8_t valSize)
46 {
47    uint32_t  temp;
48    uint8_t   bytePart1;
49    uint32_t  bytePart2;
50    uint8_t   bytePart1Size;
51    uint32_t  bytePart2Size;
52
53    if(*bitPos - valSize + 1 >= 0)
54    {
55       bytePart1 = (uint8_t)val;
56       bytePart1 = (bytePart1 << (*bitPos -valSize +1));
57       buf[*bytePos] |= bytePart1;
58       if(*bitPos - valSize < 0)
59       {
60          *bitPos = 7;
61          (*bytePos)++;
62       }
63       else
64          *bitPos -= valSize;
65    }
66    else
67    {
68       temp = 0;
69       bytePart1Size = *bitPos +1;
70       bytePart2Size = valSize - bytePart1Size;
71
72       bytePart1 = (val >> bytePart2Size) << (*bitPos -bytePart1Size +1);
73       bytePart2 =  (~((~temp) << bytePart2Size)) & val;
74
75       buf[*bytePos] |= bytePart1;
76       (*bytePos)++;
77       *bitPos = 7;
78       packBytes(buf, bytePos, bitPos, bytePart2, bytePart2Size);
79    }  
80 }
81
82 /*******************************************************************
83  *
84  * @brief fill the RAR PDU
85  *
86  * @details
87  *
88  *    Function : fillRarPdu
89  *
90  *    Functionality:
91  *     The RAR PDU will be MUXed and formed
92  *
93  * @params[in] RAR info
94  * @return void
95  *
96  * ****************************************************************/
97 void fillRarPdu(RarInfo *rarInfo)
98 {
99    uint8_t   *rarPdu = rarInfo->rarPdu;
100    uint8_t   bitPos = 0;
101    uint16_t  bytePos= 0, bwpSize = 0, rbStart = 0, rbLen = 0;
102    uint8_t   numHopInfoBitsInFreqAlloc = 0;
103    uint8_t   actualFreqRsrcAllocSize = 0;
104
105    /* RAR subheader fields */
106    uint8_t   EBit = 0;
107    uint8_t   TBit = 0;
108
109    /* RAR payload fields */
110    uint8_t   RBit = 0;
111    uint16_t  msg3FreqResource = 0;
112    uint8_t   paddingLcid = 63;
113
114    /* Considering 2 bytes of padding in RAR PDU. 
115     * 1st byte is MAC sub-header for padding
116     * 2nd byte contains padding bits
117     */
118    uint8_t   paddingSize = 8;
119
120    /* Fill RAR pdu fields */
121    EBit = 0;
122    TBit = 1;
123    RBit = 0;
124
125    rarInfo->rarPduLen = RAR_PAYLOAD_SIZE;
126
127    /* Initialize buffer */
128    for(bytePos = 0; bytePos < rarInfo->rarPduLen; bytePos++)
129       rarPdu[bytePos] = 0;
130
131    bytePos = 0;
132    bitPos = 7;
133
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);
140  
141    /* Packing MSG3 UL Grant in RAR */
142    packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.freqHopFlag, FREQ_HOP_FLAG_SIZE);
143
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
149     */
150    bwpSize = rarInfo->ulGrant.bwpSize;
151    rbStart = rarInfo->ulGrant.msg3FreqAlloc.startPrb;
152    rbLen = rarInfo->ulGrant.msg3FreqAlloc.numPrb;
153
154    if((rbLen >=1) && (rbLen <= bwpSize - rbStart))
155    {
156       if((rbLen - 1) <= floor(bwpSize / 2))
157          msg3FreqResource = (bwpSize * (rbLen-1)) + rbStart;
158       else
159          msg3FreqResource = (bwpSize * (bwpSize - rbLen + 1)) \
160                             + (bwpSize - 1 - rbStart);
161    }
162
163    /* Calculating frequency domain resource allocation field size 
164     * and packing frequency domain resource allocation accordingly 
165     * Spec 38.213 Sec 8.3 
166     */
167    if(bwpSize < 180)
168    {
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);
172    }
173    else
174    {
175       if(rarInfo->ulGrant.freqHopFlag == 0)
176       {
177          numHopInfoBitsInFreqAlloc = 1;
178          packBytes(rarPdu, &bytePos, &bitPos, 0, numHopInfoBitsInFreqAlloc);
179          
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);
184       }
185       else
186       {
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
191           */
192       }
193    }
194
195    /* Packing time domain resource allocation for UL grant */
196    packBytes(rarPdu, &bytePos, &bitPos, rarInfo->ulGrant.k2Index, TIME_RSRC_ALLOC_SIZE);
197
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);
201
202    packBytes(rarPdu, &bytePos, &bitPos, rarInfo->tcrnti, T_CRNTI_SIZE);
203
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);
208
209 }
210
211 /*******************************************************************
212  *
213  * @brief Database required to form MAC PDU
214  *
215  * @details
216  *
217  *    Function : createMacRaCb
218  *
219  *    Functionality:
220  *     stores the required params for muxing
221  *
222  * @params[in] Pointer to cellId,
223  *                        crnti
224  * @return void
225  *
226  * ****************************************************************/
227 void createMacRaCb(RachIndInfo *rachIndInfo)
228 {
229    int8_t ueIdx = -1;
230    uint16_t crnti = 0;
231    uint16_t cellIdx = 0;
232
233    GET_CELL_IDX(rachIndInfo->cellId, cellIdx);
234    
235    ueIdx = getFreeBitFromUeBitMap(rachIndInfo->cellId);
236    if(ueIdx == -1)
237    {
238       DU_LOG("\nERROR  -->  MAC : Failed to find free UE Idx in UE bit map of cell Id [%d]", rachIndInfo->cellId);
239       return;
240    }
241
242    /* Calculate CRNTI from UE Index */
243    GET_CRNTI(crnti, ueIdx+1);
244
245    /* store in rach ind structure */
246    rachIndInfo->crnti  = crnti;
247
248    /* store in raCb */
249    macCb.macCell[cellIdx]->macRaCb[ueIdx].cellId = rachIndInfo->cellId;
250    macCb.macCell[cellIdx]->macRaCb[ueIdx].crnti  = crnti;
251 }
252
253 /*************************************************
254  * @brief fill RLC DL Data
255  *
256  * @details
257  *
258  * Function : fillMsg4DlData
259  *      This function sends Dl Data
260  *      to form MAC SDUs
261  *           
262  * @param[in]  MacDlData *dlData
263  *             msg4Pdu pointer
264  ************************************************/
265
266 void fillMsg4DlData(MacDlData *dlData, uint16_t msg4PduLen, uint8_t *msg4Pdu)
267 {
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);
271    dlData->numPdu++;
272 }
273
274 /*************************************************
275  * @brief fill Mac Ce Info
276  *
277  * @details
278  *
279  * Function : fillMacCe
280  *      This function fills Mac ce identities
281  *           
282  * @param[in]  RlcMacData *dlData
283  *             Msg3Pdu Data
284  ************************************************/
285
286 void fillMacCe(MacCeInfo *macCeInfo, uint8_t *msg3Pdu)
287 {
288    uint8_t idx;
289    macCeInfo->numCes = 1;
290    for(idx = 0; idx < macCeInfo->numCes; idx++)
291    {
292       macCeInfo->macCe[idx].macCeLcid = MAC_LCID_CRI;
293       memcpy(macCeInfo->macCe[idx].macCeValue, \
294             msg3Pdu, MAX_CRI_SIZE);
295    }
296 }
297
298 /*******************************************************************
299  *
300  * @brief Forms MAC PDU
301  *
302  * @details
303  *
304  *    Function : macMuxPdu
305  *
306  *    Functionality:
307  *     The MAC PDU will be MUXed and formed
308  *
309  * @params[in] MacDlData *, MacCeInfo *, txPdu *, tbSize
310  * @return void
311  * ****************************************************************/
312
313 void macMuxPdu(MacDlData *dlData, MacCeInfo *macCeData, uint8_t *txPdu, uint16_t tbSize)
314 {
315    uint16_t bytePos = 0;
316    uint8_t bitPos = 7;
317    uint8_t pduIdx = 0;
318    uint8_t macPdu[tbSize];
319    memset(macPdu, 0, (tbSize * sizeof(uint8_t)));
320
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 */
326
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  */
332
333    /* PACK ALL MAC CE */
334    if(macCeData != NULLP)
335    {
336       for(pduIdx = 0; pduIdx < macCeData->numCes; pduIdx++)
337       {
338          lcid = macCeData->macCe[pduIdx].macCeLcid;
339          switch(lcid)
340          {
341             case MAC_LCID_CRI:
342                {
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,\
347                         MAX_CRI_SIZE);
348                   bytePos += MAX_CRI_SIZE;
349                   break;
350                }
351             default:
352                DU_LOG("\nERROR  -->  MAC: Invalid LCID %d in mac pdu",lcid);
353                break;
354          }
355       }
356    }
357
358    /* PACK ALL MAC SDUs */
359    for(pduIdx = 0; pduIdx < dlData->numPdu; pduIdx++)
360    {
361       lcid = dlData->pduInfo[pduIdx].lcId;
362       switch(lcid)
363       {
364          case MAC_LCID_CCCH:
365          case MAC_LCID_MIN ... MAC_LCID_MAX :
366             {
367                lenField = dlData->pduInfo[pduIdx].pduLen;
368                if(dlData->pduInfo[pduIdx].pduLen > 255)
369                {
370                   FBit = 1;
371                   lenFieldSize = 16;
372
373                }
374                else
375                {
376                   FBit = 0;
377                   lenFieldSize = 8;
378                }
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);
385                bytePos += lenField;
386                break;
387             }
388
389          default:
390             DU_LOG("\nERROR  -->  MAC: Invalid LCID %d in mac pdu",lcid);
391             break;
392       }
393    }
394    if(bytePos < tbSize && (tbSize-bytePos >= 1))
395    {
396       /* padding remaining bytes */
397       RBitSize = 2;
398       lcid = MAC_LCID_PADDING;
399       packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
400       packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
401    }
402
403    /*Storing the muxed pdu */
404    if(txPdu != NULLP)
405    {
406       memcpy(txPdu, macPdu, tbSize);
407    }
408 }
409
410 /**********************************************************************
411   End of file
412  **********************************************************************/