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