[Epic-ID: ODUHIGH-488][Task-ID: ODUHIGH-501] Ue Create and Rsp correction in DUAPP...
[o-du/l2.git] / src / cm / common_def.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 "common_def.h"
20
21 /*Spec 38.104, Table 5.4.2.1-1 ARFCN - FREQ mapping*/
22 /*{  F_REF(Mhz), ΔF_Global, F_REF-Offs, N_REF-offs, Range of N_REF }*/
23 uint32_t arfcnFreqTable[3][5] = {
24   {   3000,   5,         0,        0,   599999 }, /*index 0*/
25   {  24250,  15,      3000,   600000,  2016666 }, /*index 1*/
26   { 100000,  60,  24250.08,  2016667,  3279165 }, /*index 2*/
27 };
28
29 /**
30  * @brief frequency domain allocation function. 
31  *
32  * @details
33  *
34  *     Function: fillCoresetFeqDomAllocMap
35  *     
36  *     This function does allocation in frequency domain resource.
37  *     This is a bitmap defining  non-overlapping groups of 6 PRBs in ascending order.
38  *     
39  *  @param[in]  startPrb - start PRB from where the freq alloc starts.  
40  *  @param[in]  prbSize - number of PRBs to be allocted.
41  *  @param[in]  freqDomain - 6 bytes of info, each bit represents a group of 6 PRB.
42  *  @return   void
43  **/
44 void fillCoresetFeqDomAllocMap(uint16_t startPrbGrp, uint16_t numPrbGrp, uint8_t *freqDomain)
45 {
46    uint8_t  idx;
47    uint8_t  prbGrpStartBit = 0;
48    uint8_t  numBitsToRightShift = 0;
49    uint64_t mask = 0;
50    uint64_t freqAllocBitMap = 0;
51
52    /* 
53     * Frequency allocation bit string is 45 bits long. Hence using 6 bytes (i.e. 48 bits) to represent it.
54     * Each bit corresponds to a group of 6 RBs.
55     *
56     * For example if a coreset includes PRB 24 to 47, then on dividing the PRBs into group of 6, 
57     * startPrbGrp = 24/6 = 4
58     * numPrbGrp = 24/6 = 4
59     * 
60     * Frequency allocation bit string is 48 bits long i.e. Bit 47...0
61     * Here, Bit 47 represents RB group 0, Bit 46 represent RB group 45 and so on.
62     * Since startPrbGrp = 4 and numPrbGrp = 4, it means RB group 4,5,6 and 7 are used in coreset.
63     * i.e. Bits 43, 42, 42 and 40 are masked to 1 and rest all bits are 0 in bitstring    
64     */
65    prbGrpStartBit = 47; 
66    while(numPrbGrp)
67    {
68       mask = 1;
69       mask = mask << (prbGrpStartBit - startPrbGrp);
70       freqAllocBitMap = freqAllocBitMap | mask;
71       startPrbGrp++;
72       numPrbGrp--;
73    }
74
75    /* Copying 48 LSBs from 64-bit integer to the 45 MSBS in 6-byte array 
76     * The first (left-most / most significant) bit corresponds to the first RB
77     * group in the BWP, and so on
78     */
79    /* On right shifting freqAllocBitMap by 40 bits, the bits 47 to 40 of freqAllocBitMap 
80     * will now become 8-LSB. Copying these 8-bits into freqDomain[].
81     * Now shifting freqAllocBitMap by 32 bits, the bit 39 to 32 of freqAllocBitMap will
82     * now become 8-LSB. Copying these 8-bits into next index of freqDomain.
83     * and so on.
84     */
85    numBitsToRightShift = 40; 
86    mask = 0x0000FF0000000000;
87    for(idx=0; idx<FREQ_DOM_RSRC_SIZE; idx++)
88    {
89       freqDomain[idx] = (freqAllocBitMap & mask) >> numBitsToRightShift;
90       numBitsToRightShift -= 8;
91       mask = mask >> 8;
92    }
93 }
94
95 /*******************************************************************
96  *
97  * @brief Reverse and copy fixed buffer to mBuf 
98  *
99  * @details
100  *
101  *    Function : oduCpyFixBufToMsg
102  *
103  *    Functionality: Reverse and copy fixed buffer to mBuf
104  *
105  * @params[in] Fixed buffer, msg buffer, length of message
106  * @return ROK     - success
107  *         RFAILED - failure
108  *
109  * ****************************************************************/
110 void oduCpyFixBufToMsg(uint8_t *fixBuf, Buffer *mBuf, uint16_t len)                            
111 {
112    uint16_t idx = 0, revIdx = 0, temp = 0, copyLen = 0;
113
114    /* ODU_COPY_FIX_BUF_TO_MSG copies fixed buffer in reverse order. \
115     * Hence reversing the fixed buffer before copying in order to \
116     * maintain the actual order*/
117    for(idx = 0, revIdx = len-1; idx < len/2; idx++, revIdx--)   
118    {                                                            
119         temp = fixBuf[idx];                                          
120         fixBuf[idx] = fixBuf[revIdx];                                   
121         fixBuf[revIdx] = temp;                                       
122    }                                                            
123    ODU_COPY_FIX_BUF_TO_MSG(fixBuf, mBuf, 0, len, (MsgLen *)&copyLen);
124 }
125
126 /*******************************************************************
127  *
128  * @brief Builds PLMN ID 
129  *
130  * @details
131  *
132  *    Function : plmnBuildId
133  *
134  *    Functionality: Building the PLMN ID
135  *
136  * @params[in] PLMNID plmn
137  * @params[out] PLMNID in string format
138  * @return ROK     - success
139  *         RFAILED - failure
140  *
141  * ****************************************************************/
142 uint8_t buildPlmnId(Plmn plmn, uint8_t *buf)
143 {
144    uint8_t mncCnt;
145    mncCnt = 2;
146    buf[0] = ((plmn.mcc[1] << 4) | (plmn.mcc[0]));
147    if(mncCnt == 2)
148    {
149       buf[1]  = ((0xf0) | (plmn.mcc[2]));
150       buf[2] = ((plmn.mnc[1] << 4) | (plmn.mnc[0]));
151    }
152    else
153    {
154       buf[1] = ((plmn.mnc[0] << 4) | (plmn.mcc[2]));
155       buf[2] = ((plmn.mnc[2] << 4) | (plmn.mnc[1]));
156    }
157    return ROK;
158 }
159
160 /*******************************************************************
161  *
162  * @brief Function to map Sub carrier spacing enum value to value in kHz
163  *
164  * @details
165  *
166  *    Function : convertScsEnumValToScsVal
167  *
168  *    Functionality:
169  *       Function to map Sub carrier spacing enum value to value in kHz
170  *
171  * @params[in] sub-carrier spacing enum value
172  * @return sub-carrier spacing value in kHz
173  *
174  * ****************************************************************/
175 uint16_t convertScsEnumValToScsVal(uint8_t scsEnumValue)
176 {
177    switch(scsEnumValue)
178    {
179       case SCS_15KHZ:
180       case SCS_30KHZ:
181       case SCS_60KHZ:
182       case SCS_120KHZ:
183       case SCS_240KHZ:
184          return (15 * pow(2,scsEnumValue));
185       default:
186          return 15;
187    }
188 }
189
190 /*******************************************************************
191  * @brief convert scs offset value into the enum value received from O1 
192  *
193  * @details
194  *
195  *    Function : convertScsValToScsEnum
196  *
197  *    Functionality:
198  *       - convert scs periodicity value 
199  *
200  * @params[in] uint32_t num
201  * @return ROK     - success
202  *         RFAILED - failure
203  *
204  * ****************************************************************/
205
206 uint8_t convertScsValToScsEnum(uint32_t num)
207 {
208    switch(num)
209    {
210       case 15:
211          return SCS_15KHZ;
212
213       case 30:
214          return SCS_30KHZ;
215
216       case 60:
217          return SCS_60KHZ;
218
219       case 120:
220          return SCS_120KHZ;
221       
222       case 240:
223          return SCS_240KHZ;
224       
225       default:
226          return SCS_15KHZ;
227    }
228 }
229
230 /*******************************************************************
231  * @brief convert scs periodicity value into the enum value received from O1 
232  *
233  * @details
234  *
235  *    Function : convertScsPeriodicityToEnum
236  *
237  *    Functionality:
238  *       - convert scs periodicity value 
239  *
240  * @params[in] uint32_t num
241  * @return ROK     - success
242  *         RFAILED - failure
243  *
244  * ****************************************************************/
245 uint8_t convertScsPeriodicityToEnum(uint32_t num)
246 {
247    switch(num)
248    {
249       case 5:
250          return SCS_5MS;
251
252       case 10:
253          return SCS_10MS;
254
255       case 20:
256          return SCS_20MS;
257
258       case 40:
259          return SCS_40MS;
260
261       case 80:
262          return SCS_80MS;
263
264       case 160:
265          return SCS_160MS;
266
267       default:
268          return SCS_5MS;
269    }
270 }
271 /*******************************************************************
272 *
273 * @brief  SGetSBuf with debug logs
274 *
275 * @details
276 *
277 *    Function : SGetSBufNewForDebug
278 *
279 *    Functionality: SGetSBuf with debug logs
280 *
281 * @params[in] file name, fun name, region, pool, data ptr, size
282 *
283 * @return ROK     - success
284 *         RFAILED - failure
285 *
286 * ****************************************************************/
287 uint8_t SGetSBufNewForDebug(char *file, const char *func, int line, Region region, Pool pool, Data **ptr, Size size)
288 {
289    if(SGetSBuf(region, pool, ptr, size) == ROK)
290    {
291 #ifdef ODU_MEMORY_DEBUG_LOG
292       if (strncmp(func,"cmInetRecvMsg",sizeof("cmInetRecvMsg")))
293       {
294          printf("\nCM,ALLOC,=== SGetSBufNewForDebug %s +%d, %s, %d, %p \n",\
295          file, line, func, size, *ptr);
296       }
297 #endif
298       return ROK;
299    }
300    else
301       return RFAILED;
302 }
303
304 /*******************************************************************
305 *
306 * @brief  SPutSBuf with debug logs
307 *
308 * @details
309 *
310 *    Function : SPutSBufNewForDebug
311 *
312 *    Functionality: SPutSBuf with debug logs
313 *
314 * @params[in] file name, fun name, region, pool, data ptr, size
315 *
316 * @return ROK     - success
317 *         RFAILED - failure
318 *
319 * ****************************************************************/
320 uint8_t SPutSBufNewForDebug(char *file, const char *func, int line, Region region, Pool pool, Data *ptr, Size size)
321 {
322    if(SPutSBuf(region, pool, ptr, size) == ROK)
323    {
324 #ifdef ODU_MEMORY_DEBUG_LOG
325       if (strncmp(func,"cmInetRecvMsg",sizeof("cmInetRecvMsg")))
326       {
327          printf("\nCM,FREE,=== SPutSBufNewForDebug %s +%d, %s, %d, %p \n",\
328          file, line, func, size, ptr);
329       }
330 #endif
331       return ROK;
332    }
333    else
334       return RFAILED;
335 }
336
337
338 /*******************************************************************
339 *
340 * @brief  SGetStaticBuf with debug logs
341 *
342 * @details
343 *
344 *    Function : SGetStaticBufNewForDebug
345 *
346 *    Functionality: SGetStaticBuf with debug logs
347 *
348 * @params[in] file name, fun name, region, pool, data ptr, size, memType
349 *
350 * @return ROK     - success
351 *         RFAILED - failure
352 *
353 * ****************************************************************/
354 uint8_t SGetStaticBufNewForDebug(char *file, const char *func, int line, \
355 Region region, Pool pool, Data **ptr, Size size, uint8_t memType)
356 {
357    if(SGetStaticBuffer(region, pool, ptr, size, memType) == ROK)
358    {
359 #ifdef ODU_MEMORY_DEBUG_LOG
360       printf("\nCM,ALLOC,=== SGetStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
361          file, line, func, size, *ptr);
362 #endif
363       return ROK;
364    }
365    else
366       return RFAILED;
367 }
368
369 /*******************************************************************
370 *
371 * @brief  SPutStaticBuf with debug logs
372 *
373 * @details
374 *
375 *    Function : SPutStaticBufNewForDebug 
376 *
377 *    Functionality: SPutStaticBuf with debug logs
378 *
379 * @params[in] file name, fun name, region, pool, data ptr, size, memType
380 *
381 * @return ROK     - success
382 *         RFAILED - failure
383 *
384 * ****************************************************************/
385 uint8_t SPutStaticBufNewForDebug(char *file, const char *func, int line, \
386 Region region, Pool pool, Data *ptr, Size size, uint8_t memType)
387 {
388    if(SPutStaticBuffer(region, pool, ptr, size, memType) == ROK)
389    {
390 #ifdef ODU_MEMORY_DEBUG_LOG
391       printf("\nCM,FREE,=== SPutStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
392          file, line, func, size, ptr);
393 #endif
394       return ROK;
395    }
396    else
397       return RFAILED;
398 }
399
400
401 /*******************************************************************
402 *
403 * @brief  countSetBits in an integer
404 *
405 * @details
406 *
407 *    Function : countSetBits 
408 *
409 *    Functionality: countSetBits in unsigned integer
410 *
411 * @params[in] uint32_t number/Bitmask
412 *
413 * @return [out] uint8_t count of Set Bits
414 *
415 * ****************************************************************/
416 uint8_t countSetBits(uint32_t num)
417 {
418    uint8_t count = 0;
419
420    while(num)
421    {
422       count += num & 1;
423       num >>= 1;
424    }
425    return(count);
426 }
427
428 /*******************************************************************
429 *
430 * @brief  convert ARFCN to freq in kHZ
431 *
432 * @details
433 *
434 *    Function : convertArfcnToFreqKhz
435 *
436 *    Functionality: convert ARFCN to freq in kHZ as per Table below
437 *                  3GPP TS 38.104, Table 5.4.2.1-1
438 *       Formula: F_REF = F_REF-Offs + ΔF_Global (N_REF – N_REF-Offs)
439 *
440 * @params[in] uint32_t number
441 *
442 * @return [out] uint32_t Freq in kHZ
443 *
444 * ****************************************************************/
445 uint32_t convertArfcnToFreqKhz(uint32_t arfcn)
446 {
447    uint8_t indexTable = 0;
448    uint32_t freq = 0;
449
450    for(indexTable = 0; indexTable < 3; indexTable++)
451    {
452       if(arfcn <= arfcnFreqTable[indexTable][4])
453       {
454          freq = (arfcnFreqTable[indexTable][2] * 1000) + (arfcnFreqTable[indexTable][1] * (arfcn - arfcnFreqTable[indexTable][3]));
455          return (freq);
456       }
457    }
458    DU_LOG("ERROR  -->  DUAPP: ARFCN vaid range is between 0 and 3279165");
459    return (freq);
460 }
461
462
463 /*******************************************************************
464 *
465 * @brief  convert Freq(MHZ) to ARFCN
466 *
467 * @details
468 *
469 *    Function : convertFreqToArfcn
470 *
471 *    Functionality: convert freq to ARFCN as per Table below
472 *                  3GPP TS 38.104, Table 5.4.2.1-1
473 *       Formula: NREF = NREF-Offs +  (FREF – FREF-Offs) / ΔFGlobal
474 *
475 * @params[in] uint32_t Freq(kHZ)
476 *
477 * @return [out] uint32_t ARFCN(number)
478 *
479 * ****************************************************************/
480 uint32_t convertFreqToArfcn(uint32_t freq)
481 {
482    uint8_t indexTable = 0;
483    uint32_t arfcn = 0;
484
485    for(indexTable = 0; indexTable < 3; indexTable++)
486    {
487       if(freq < arfcnFreqTable[indexTable][0])
488       {
489          arfcn = arfcnFreqTable[indexTable][3] + ((freq - (arfcnFreqTable[indexTable][2] * 1000)) / (arfcnFreqTable[indexTable][1]));
490          return (arfcn);
491       }
492    }
493    DU_LOG("ERROR  -->  DUAPP: FREQ vaid range is between 0 and 100000 MHz");
494    return (arfcn);
495 }
496
497 /**********************************************************************
498          End of file
499 **********************************************************************/