Muxing mac pdu and lower mac changes for Msg4
[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 #include <stdlib.h>
20 #include <stdint.h>
21
22 /* header include files -- defines (.h) */
23 #include "envopt.h"        /* environment options */
24 #include "envdep.h"        /* environment dependent */
25 #include "envind.h"        /* environment independent */
26 #include "gen.h"           /* general layer */
27 #include "ssi.h"           /* system service interface */
28 #include "cm_hash.h"       /* common hash list */
29 #include "cm_mblk.h"       /* common memory link list library */
30 #include "cm_llist.h"      /* common linked list library */
31 #include "cm_err.h"        /* common error */
32 #include "cm_lte.h"        /* common LTE */
33 #include "lrg.h"           /* Layer manager interface includes*/
34 #include "crg.h"           /* CRG interface includes*/
35 #include "rgu.h"           /* RGU interface includes*/
36 #include "tfu.h"           /* TFU interface includes */
37 #include "rg_sch_inf.h"    /* SCH interface includes */
38 #include "rg_prg.h"       /* PRG (MAC-MAC) interface includes*/
39 #include "rg_env.h"       /* MAC environmental includes*/
40 #include "rg.h"           /* MAC includes*/
41 #include "rg_err.h"       /* MAC error includes*/
42 #include "du_log.h"
43
44 /* header/extern include files (.x) */
45 #include "gen.x"           /* general layer typedefs */
46 #include "ssi.x"           /* system services typedefs */
47 #include "cm5.x"           /* common timers */
48 #include "cm_hash.x"       /* common hash list */
49 #include "cm_lib.x"        /* common library */
50 #include "cm_llist.x"      /* common linked list */
51 #include "cm_mblk.x"       /* memory management */
52 #include "cm_tkns.x"       /* common tokens */
53 #include "cm_lte.x"       /* common tokens */
54 #include "rgu.x"           /* RGU types */
55 #include "tfu.x"           /* RGU types */
56 #include "lrg.x"           /* layer management typedefs for MAC */
57 #include "crg.x"           /* CRG interface includes */
58 #include "rg_sch_inf.x"    /* SCH interface typedefs */
59 #include "rg_prg.x"        /* PRG (MAC-MAC) Interface typedefs */
60 #include "du_app_mac_inf.h"
61 #include "mac.h"
62 #include "rg.x"            /* typedefs for MAC */
63
64 /*******************************************************************
65  *
66  * @brief pack the bits
67  *
68  * @details
69  *
70  *    Function : packBytes
71  *
72  *    Functionality:
73  *     pack the bits in the corresponding byte
74  *
75  * @params[in] buffer pointer, byte and bit position, value and its size
76  * @return void
77  *
78  * ****************************************************************/
79 void packBytes(uint8_t *buf, uint8_t *bytePos, uint8_t *bitPos, uint32_t val, uint8_t valSize)
80 {
81    uint32_t  temp;
82    uint8_t   bytePart1;
83    uint32_t  bytePart2;
84    uint8_t   bytePart1Size;
85    uint32_t  bytePart2Size;
86   
87    if(*bitPos - valSize + 1 >= 0)
88    {
89       bytePart1 = (uint8_t)val;
90       bytePart1 = (bytePart1 << (*bitPos -valSize +1));
91       buf[*bytePos] |= bytePart1;
92       if(*bitPos - valSize < 0)
93       {
94          *bitPos = 7;
95          (*bytePos)++;
96       }
97       else
98          *bitPos -= valSize;
99    }
100    else
101    {
102       temp = 0;
103       bytePart1Size = *bitPos +1;
104       bytePart2Size = valSize - bytePart1Size;
105
106       bytePart1 = (val >> bytePart2Size) << (*bitPos -bytePart1Size +1);
107       bytePart2 =  (~((~temp) << bytePart2Size)) & val;
108  
109       buf[*bytePos] |= bytePart1;
110       (*bytePos)++;
111       *bitPos = 7;
112       packBytes(buf, bytePos, bitPos, bytePart2, bytePart2Size);
113    }  
114 }
115
116 /*******************************************************************
117  *
118  * @brief fill the RAR PDU
119  *
120  * @details
121  *
122  *    Function : fillRarPdu
123  *
124  *    Functionality:
125  *     The RAR PDU will be MUXed and formed
126  *
127  * @params[in] RAR info
128  * @return void
129  *
130  * ****************************************************************/
131 void fillRarPdu(RarInfo *rarInfo)
132 {
133    uint8_t   *rarPdu = rarInfo->rarPdu;
134    uint16_t  totalBits = 0;
135    uint8_t   numBytes = 0;
136    uint8_t   bytePos= 0;
137    uint8_t   bitPos = 0;
138
139    /* RAR subheader fields */
140    uint8_t   EBit = 0;
141    uint8_t   TBit = 0;
142    uint8_t   rapId = 0;
143
144    /* RAR payload fields */
145    uint8_t   RBit = 0;
146    uint16_t  timeAdv = 0;
147    uint32_t  ulGrant = 0;
148    uint16_t  tmpCrnti = 0; 
149         uint8_t   paddingLcid = 63;
150
151    /* Size(in bits) of RAR subheader files */
152    uint8_t   EBitSize = 1;
153    uint8_t   TBitSize = 1;
154    uint8_t   rapidSize = 6;
155         uint8_t   paddingLcidSize = 6;
156         uint8_t   paddingSize = 8;
157
158
159    /* Size(in bits) of RAR payload fields */
160    uint8_t   RBitSize = 1;
161    uint8_t   timeAdvSize = 12;
162    uint8_t   ulGrantSize = 27;
163    uint8_t   tmpCrntiSize = 16;
164
165    /* Fill RAR pdu fields */
166    EBit = 0;
167    TBit = 1;
168    rapId = rarInfo->RAPID;
169    
170    RBit = 0;
171    timeAdv = rarInfo->ta;
172    ulGrant = 0; /* this will be done when implementing msg3 */ 
173    tmpCrnti = rarInfo->tcrnti;
174
175    /* Calulating total number of bytes in buffer */
176    totalBits = EBitSize + TBitSize + rapidSize + RBitSize + timeAdvSize \
177      + ulGrantSize + tmpCrntiSize;
178
179    /* add padding size */
180         totalBits += RBitSize*2 + paddingLcidSize + paddingSize;
181    
182    /* Calulating total number of bytes in buffer */
183    numBytes = totalBits/8;
184    if(totalBits % 8)
185       numBytes += 1;
186     
187         rarInfo->rarPduLen = numBytes;
188
189    /* Initialize buffer */
190    for(bytePos = 0; bytePos < numBytes; bytePos++)
191       rarPdu[bytePos] = 0;
192    
193    bytePos = 0;
194    bitPos = 7;
195
196    /* Packing fields into RAR PDU */
197    packBytes(rarPdu, &bytePos, &bitPos, EBit, EBitSize); 
198    packBytes(rarPdu, &bytePos, &bitPos, TBit, TBitSize);
199    packBytes(rarPdu, &bytePos, &bitPos, rapId, rapidSize);
200    packBytes(rarPdu, &bytePos, &bitPos, RBit, RBitSize);
201    packBytes(rarPdu, &bytePos, &bitPos, timeAdv, timeAdvSize);
202    packBytes(rarPdu, &bytePos, &bitPos, ulGrant, ulGrantSize);
203    packBytes(rarPdu, &bytePos, &bitPos, tmpCrnti, tmpCrntiSize);
204
205         /* padding of 2 bytes */
206    packBytes(rarPdu, &bytePos, &bitPos, RBit, RBitSize*2);
207    packBytes(rarPdu, &bytePos, &bitPos, paddingLcid, paddingLcidSize);
208    packBytes(rarPdu, &bytePos, &bitPos, 0, paddingSize);
209         
210 }
211
212 /*******************************************************************
213  *
214  * @brief Database required to form MAC PDU
215  *
216  * @details
217  *
218  *    Function : createMacRaCb
219  *
220  *    Functionality:
221  *     stores the required params for muxing
222  *
223  * @params[in] Pointer to cellId,
224  *                        crnti
225  * @return void
226  *
227  * ****************************************************************/
228 void createMacRaCb(uint16_t cellId, uint16_t crnti)
229 {
230    uint8_t idx = 0; /* supporting 1 UE */
231    macCb.macCell->macRaCb[idx].cellId = cellId;
232    macCb.macCell->macRaCb[idx].crnti = crnti;
233 }
234
235 /*************************************************
236  * @brief fill RLC DL Data
237  *
238  * @details
239  *
240  * Function : fillMsg4DlData
241  *      This function is a stub which sends Dl Data
242  *      to form MAC SDUs
243  *           
244  * @param[in]  MacDlData *dlData
245  ************************************************/
246
247 void fillMsg4DlData(MacDlData *dlData)
248 {
249    uint8_t idx = 0;
250    dlData->numPdu = 1;
251    dlData->pduInfo[idx].lcId = MAC_LCID_CCCH;
252    dlData->pduInfo[idx].pduLen = macCb.macCell->macRaCb[0].msg4PduLen;
253    memcpy(dlData->pduInfo[idx].dlPdu, macCb.macCell->macRaCb[0].msg4Pdu,\
254     macCb.macCell->macRaCb[0].msg4PduLen);
255 }
256
257 /*************************************************
258  * @brief fill Mac Ce Info
259  *
260  * @details
261  *
262  * Function : fillMacCe
263  *      This function fills Mac ce identities
264  *           
265  * @param[in]  RlcMacData *dlData
266  ************************************************/
267
268 void fillMacCe(MacCeInfo *macCeInfo)
269 {
270    uint8_t idx;
271    macCeInfo->numCes = 1;
272    for(idx = 0; idx < macCeInfo->numCes; idx++)
273    {
274       macCeInfo->macCe[idx].macCeLcid = MAC_LCID_CRI;
275       memcpy(&macCeInfo->macCe[idx].macCeValue, \
276          &macCb.macCell->macRaCb[idx].msg3Pdu, MAX_CRI_SIZE);
277    }
278 }
279
280 /*******************************************************************
281  *
282  * @brief Forms MAC PDU
283  *
284  * @details
285  *
286  *    Function : buildMacPdu
287  *
288  *    Functionality:
289  *     The MAC PDU will be MUXed and formed
290  *
291  * @params[in] MacDlData *, MacCeInfo *, tbSize
292  * @return void
293  *
294  * ****************************************************************/
295
296 void macMuxPdu(MacDlData *dlData, MacCeInfo *macCeData, uint16_t tbSize)
297 {
298    uint8_t bytePos = 0;
299    uint8_t bitPos = 7;
300    uint8_t idx = 0;
301    uint8_t macPdu[tbSize];
302    memset(macPdu, 0, (tbSize * sizeof(uint8_t)));
303
304    /* subheader fields */
305    uint8_t RBit = 0;              /* Reserved bit */
306    uint8_t FBit;                  /* Format Indicator */
307    uint8_t lcid;                  /* LCID */
308    uint8_t lenField = 0;          /* Length field */
309
310    /* subheader field size (in bits) */
311    uint8_t RBitSize = 1;
312    uint8_t FBitSize = 1;
313    uint8_t lcidSize = 6;
314    uint8_t lenFieldSize = 0;          /* 8-bit or 16-bit L field  */
315    uint8_t criSize = 8;
316
317    /* PACK ALL MAC CE */
318    for(idx = 0; idx < macCeData->numCes; idx++)
319    {
320       lcid = macCeData->macCe[idx].macCeLcid;
321       switch(lcid)
322       {
323          case MAC_LCID_CRI:
324          {
325             /* Packing fields into MAC PDU R/R/LCID */
326             packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
327             packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
328             packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
329             memcpy(&macPdu[bytePos], macCeData->macCe[idx].macCeValue,\
330             MAX_CRI_SIZE);
331             break;
332          }
333          default:
334             DU_LOG("\n MAC: Invalid LCID %d in mac pdu",lcid);
335             break;
336       }
337    }
338
339    /* PACK ALL MAC SDUs */
340    for(idx = 0; idx < dlData->numPdu; idx++)
341    {
342       lcid = dlData->pduInfo[idx].lcId;
343       lenField = dlData->pduInfo[idx].pduLen;
344       switch(lcid)
345       {
346          case MAC_LCID_CCCH:
347          {
348             if(dlData->pduInfo[idx].pduLen > 255)
349             {
350                FBit = 1;
351                lenFieldSize = 16;
352
353             }
354             else
355             {
356                FBit = 0;
357                lenFieldSize = 8;
358             }
359             /* Packing fields into MAC PDU R/F/LCID/L */
360             packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
361             packBytes(macPdu, &bytePos, &bitPos, FBit, FBitSize);
362             packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
363             packBytes(macPdu, &bytePos, &bitPos, lenField, lenFieldSize);
364             memcpy(&macPdu[bytePos], dlData->pduInfo[idx].dlPdu, lenField);
365             break;
366          }
367
368          default:
369             DU_LOG("\n MAC: Invalid LCID %d in mac pdu",lcid);
370             break;
371       }
372
373    }
374    if(bytePos < tbSize && (tbSize-bytePos >= 1))
375    {
376       /* padding remaining bytes */
377       RBitSize = 2;
378       lcid = MAC_LCID_PADDING;
379       packBytes(macPdu, &bytePos, &bitPos, RBit, RBitSize);
380       packBytes(macPdu, &bytePos, &bitPos, lcid, lcidSize);
381    }
382
383    MAC_ALLOC(macCb.macCell->macRaCb[0].msg4TxPdu, macCb.macCell->macRaCb[0].msg4TbSize);
384    if(macCb.macCell->macRaCb[0].msg4TxPdu != NULLP)
385    {
386       memcpy(macCb.macCell->macRaCb[0].msg4TxPdu, macPdu,\
387          macCb.macCell->macRaCb[0].msg4TbSize);
388    }
389 }
390
391 /**********************************************************************
392   End of file
393  **********************************************************************/