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