1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
19 #include "common_def.h"
22 #define CM_MEMORY_ALLOC_SIZE_LOG(_line, _func, _size) \
24 DU_LOG("\nRLC line = %d, func = %s, _size= %d ", _line, _func, _size); \
27 #define CM_MEMORY_ALLOC_SIZE_LOG(_line, _func, _size) {}
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*/
39 * @brief frequency domain allocation function.
43 * Function: fillCoresetFeqDomAllocMap
45 * This function does allocation in frequency domain resource.
46 * This is a bitmap defining non-overlapping groups of 6 PRBs in ascending order.
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.
53 void fillCoresetFeqDomAllocMap(uint16_t startPrbGrp, uint16_t numPrbGrp, uint8_t *freqDomain)
56 uint8_t prbGrpStartBit = 0;
57 uint8_t numBitsToRightShift = 0;
59 uint64_t freqAllocBitMap = 0;
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.
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
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
78 mask = mask << (prbGrpStartBit - startPrbGrp);
79 freqAllocBitMap = freqAllocBitMap | mask;
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
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.
94 numBitsToRightShift = 40;
95 mask = 0x0000FF0000000000;
96 for(idx=0; idx<FREQ_DOM_RSRC_SIZE; idx++)
98 freqDomain[idx] = (freqAllocBitMap & mask) >> numBitsToRightShift;
99 numBitsToRightShift -= 8;
104 /*******************************************************************
106 * @brief Reverse and copy fixed buffer to mBuf
110 * Function : oduCpyFixBufToMsg
112 * Functionality: Reverse and copy fixed buffer to mBuf
114 * @params[in] Fixed buffer, msg buffer, length of message
115 * @return ROK - success
118 * ****************************************************************/
119 void oduCpyFixBufToMsg(uint8_t *fixBuf, Buffer *mBuf, uint16_t len)
121 uint16_t idx = 0, revIdx = 0, temp = 0, copyLen = 0;
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--)
129 fixBuf[idx] = fixBuf[revIdx];
130 fixBuf[revIdx] = temp;
132 ODU_COPY_FIX_BUF_TO_MSG(fixBuf, mBuf, 0, len, (MsgLen *)©Len);
135 /*******************************************************************
137 * @brief Builds PLMN ID
141 * Function : plmnBuildId
143 * Functionality: Building the PLMN ID
145 * @params[in] PLMNID plmn
146 * @params[out] PLMNID in string format
147 * @return ROK - success
150 * ****************************************************************/
151 uint8_t buildPlmnId(Plmn plmn, uint8_t *buf)
155 buf[0] = ((plmn.mcc[1] << 4) | (plmn.mcc[0]));
158 buf[1] = ((0xf0) | (plmn.mcc[2]));
159 buf[2] = ((plmn.mnc[1] << 4) | (plmn.mnc[0]));
163 buf[1] = ((plmn.mnc[0] << 4) | (plmn.mcc[2]));
164 buf[2] = ((plmn.mnc[2] << 4) | (plmn.mnc[1]));
169 /*******************************************************************
171 * @brief Function to map Sub carrier spacing enum value to value in kHz
175 * Function : convertScsEnumValToScsVal
178 * Function to map Sub carrier spacing enum value to value in kHz
180 * @params[in] sub-carrier spacing enum value
181 * @return sub-carrier spacing value in kHz
183 * ****************************************************************/
184 uint16_t convertScsEnumValToScsVal(uint8_t scsEnumValue)
193 return (15 * pow(2,scsEnumValue));
199 /*******************************************************************
200 * @brief convert scs offset value into the enum value received from O1
204 * Function : convertScsValToScsEnum
207 * - convert scs periodicity value
209 * @params[in] uint32_t num
210 * @return ROK - success
213 * ****************************************************************/
215 uint8_t convertScsValToScsEnum(uint32_t num)
239 /*******************************************************************
240 * @brief convert SSB periodicity value into the enum value received from O1
244 * Function : convertSSBPeriodicityToEnum
247 * - convert scs periodicity value
249 * @params[in] uint32_t num
250 * @return ROK - success
253 * ****************************************************************/
254 uint8_t convertSSBPeriodicityToEnum(uint32_t num)
280 /*******************************************************************
282 * @brief SGetSBuf with debug logs
286 * Function : SGetSBufNewForDebug
288 * Functionality: SGetSBuf with debug logs
290 * @params[in] file name, fun name, region, pool, data ptr, size
292 * @return ROK - success
295 * ****************************************************************/
296 uint8_t SGetSBufNewForDebug(char *file, const char *func, int line, Region region, Pool pool, Data **ptr, Size size)
298 CM_MEMORY_ALLOC_SIZE_LOG(line, func, size);
299 if(SGetSBuf(region, pool, ptr, size) == ROK)
301 #ifdef ODU_MEMORY_DEBUG_LOG
302 if (strncmp(func,"cmInetRecvMsg",sizeof("cmInetRecvMsg")))
304 printf("\nCM,ALLOC,=== SGetSBufNewForDebug %s +%d, %s, %d, %p \n",\
305 file, line, func, size, *ptr);
314 /*******************************************************************
316 * @brief SPutSBuf with debug logs
320 * Function : SPutSBufNewForDebug
322 * Functionality: SPutSBuf with debug logs
324 * @params[in] file name, fun name, region, pool, data ptr, size
326 * @return ROK - success
329 * ****************************************************************/
330 uint8_t SPutSBufNewForDebug(char *file, const char *func, int line, Region region, Pool pool, Data *ptr, Size size)
332 if(SPutSBuf(region, pool, ptr, size) == ROK)
334 #ifdef ODU_MEMORY_DEBUG_LOG
335 if (strncmp(func,"cmInetRecvMsg",sizeof("cmInetRecvMsg")))
337 printf("\nCM,FREE,=== SPutSBufNewForDebug %s +%d, %s, %d, %p \n",\
338 file, line, func, size, ptr);
348 /*******************************************************************
350 * @brief SGetStaticBuf with debug logs
354 * Function : SGetStaticBufNewForDebug
356 * Functionality: SGetStaticBuf with debug logs
358 * @params[in] file name, fun name, region, pool, data ptr, size, memType
360 * @return ROK - success
363 * ****************************************************************/
364 uint8_t SGetStaticBufNewForDebug(char *file, const char *func, int line, \
365 Region region, Pool pool, Data **ptr, Size size, uint8_t memType)
367 CM_MEMORY_ALLOC_SIZE_LOG(line, func, size);
368 if(SGetStaticBuffer(region, pool, ptr, size, memType) == ROK)
370 #ifdef ODU_MEMORY_DEBUG_LOG
371 printf("\nCM,ALLOC,=== SGetStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
372 file, line, func, size, *ptr);
380 /*******************************************************************
382 * @brief SPutStaticBuf with debug logs
386 * Function : SPutStaticBufNewForDebug
388 * Functionality: SPutStaticBuf with debug logs
390 * @params[in] file name, fun name, region, pool, data ptr, size, memType
392 * @return ROK - success
395 * ****************************************************************/
396 uint8_t SPutStaticBufNewForDebug(char *file, const char *func, int line, \
397 Region region, Pool pool, Data *ptr, Size size, uint8_t memType)
399 if(SPutStaticBuffer(region, pool, ptr, size, memType) == ROK)
401 #ifdef ODU_MEMORY_DEBUG_LOG
402 printf("\nCM,FREE,=== SPutStaticBufNewForDebug %s +%d, %s, %d, %p \n",\
403 file, line, func, size, ptr);
412 /*******************************************************************
414 * @brief countSetBits in an integer
418 * Function : countSetBits
420 * Functionality: countSetBits in unsigned integer
422 * @params[in] uint32_t number/Bitmask
424 * @return [out] uint8_t count of Set Bits
426 * ****************************************************************/
427 uint8_t countSetBits(uint32_t num)
439 /*******************************************************************
441 * @brief convert ARFCN to freq in kHZ
445 * Function : convertArfcnToFreqKhz
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)
451 * @params[in] uint32_t number
453 * @return [out] uint32_t Freq in kHZ
455 * ****************************************************************/
456 uint32_t convertArfcnToFreqKhz(uint32_t arfcn)
458 uint8_t indexTable = 0;
461 for(indexTable = 0; indexTable < 3; indexTable++)
463 if(arfcn <= arfcnFreqTable[indexTable][4])
465 freq = (arfcnFreqTable[indexTable][2] * 1000) + (arfcnFreqTable[indexTable][1] * (arfcn - arfcnFreqTable[indexTable][3]));
469 DU_LOG("ERROR --> DUAPP: ARFCN vaid range is between 0 and 3279165");
474 /*******************************************************************
476 * @brief convert Freq(MHZ) to ARFCN
480 * Function : convertFreqToArfcn
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
486 * @params[in] uint32_t Freq(kHZ)
488 * @return [out] uint32_t ARFCN(number)
490 * ****************************************************************/
491 uint32_t convertFreqToArfcn(uint32_t freq)
493 uint8_t indexTable = 0;
496 for(indexTable = 0; indexTable < 3; indexTable++)
498 if(freq < (arfcnFreqTable[indexTable][0] * 1000))
500 arfcn = arfcnFreqTable[indexTable][3] + ((freq - (arfcnFreqTable[indexTable][2] * 1000)) / (arfcnFreqTable[indexTable][1]));
504 DU_LOG("ERROR --> DUAPP: FREQ vaid range is between 0 and 100000 MHz");
508 /**********************************************************************
510 **********************************************************************/