/* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The OpenAirInterface Software Alliance licenses this file to You under * the OAI Public License, Version 1.1 (the "License"); you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://www.openairinterface.org/?page_id=698 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *------------------------------------------------------------------------------- * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ #include "assertions.h" #ifndef CONVERSIONS_H_ #define CONVERSIONS_H_ /* Endianness conversions for 16 and 32 bits integers from host to network order */ #if (BYTE_ORDER == LITTLE_ENDIAN) # define hton_int32(x) \ (((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | \ ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24)) # define hton_int16(x) \ (((x & 0x00FF) << 8) | ((x & 0xFF00) >> 8) # define ntoh_int32_buf(bUF) \ ((*(bUF)) << 24) | ((*((bUF) + 1)) << 16) | ((*((bUF) + 2)) << 8) \ | (*((bUF) + 3)) #else # define hton_int32(x) (x) # define hton_int16(x) (x) #endif #define IN_ADDR_TO_BUFFER(X,bUFF) INT32_TO_BUFFER((X).s_addr,(char*)bUFF) #define IN6_ADDR_TO_BUFFER(X,bUFF) \ do { \ ((uint8_t*)(bUFF))[0] = (X).s6_addr[0]; \ ((uint8_t*)(bUFF))[1] = (X).s6_addr[1]; \ ((uint8_t*)(bUFF))[2] = (X).s6_addr[2]; \ ((uint8_t*)(bUFF))[3] = (X).s6_addr[3]; \ ((uint8_t*)(bUFF))[4] = (X).s6_addr[4]; \ ((uint8_t*)(bUFF))[5] = (X).s6_addr[5]; \ ((uint8_t*)(bUFF))[6] = (X).s6_addr[6]; \ ((uint8_t*)(bUFF))[7] = (X).s6_addr[7]; \ ((uint8_t*)(bUFF))[8] = (X).s6_addr[8]; \ ((uint8_t*)(bUFF))[9] = (X).s6_addr[9]; \ ((uint8_t*)(bUFF))[10] = (X).s6_addr[10]; \ ((uint8_t*)(bUFF))[11] = (X).s6_addr[11]; \ ((uint8_t*)(bUFF))[12] = (X).s6_addr[12]; \ ((uint8_t*)(bUFF))[13] = (X).s6_addr[13]; \ ((uint8_t*)(bUFF))[14] = (X).s6_addr[14]; \ ((uint8_t*)(bUFF))[15] = (X).s6_addr[15]; \ } while(0) #define BUFFER_TO_INT8(buf, x) (x = ((buf)[0])) #define INT8_TO_BUFFER(x, buf) ((buf)[0] = (x)) /* Convert an integer on 16 bits to the given bUFFER */ #define INT16_TO_BUFFER(x, buf) \ do { \ (buf)[0] = (x) >> 8; \ (buf)[1] = (x); \ } while(0) /* Convert an array of char containing vALUE to x */ #define BUFFER_TO_INT16(buf, x) \ do { \ x = ((buf)[0] << 8) | \ ((buf)[1]); \ } while(0) /* Convert an integer on 24 bits to the given bUFFER */ #define INT24_TO_BUFFER(x, buf) \ do { \ (buf)[0] = (x) >> 16; \ (buf)[1] = (x) >> 8; \ (buf)[2] = (x); \ } while(0) /* Convert an array of char containing vALUE to x */ #define BUFFER_TO_INT24(buf, x) \ do { \ x = ((buf)[0] << 16) | \ ((buf)[1] << 8 ) | \ ((buf)[2]); \ } while(0) /* Convert an integer on 32 bits to the given bUFFER */ #define INT32_TO_BUFFER(x, buf) \ do { \ (buf)[0] = (x) >> 24; \ (buf)[1] = (x) >> 16; \ (buf)[2] = (x) >> 8; \ (buf)[3] = (x); \ } while(0) /* Convert an array of char containing vALUE to x */ #define BUFFER_TO_INT32(buf, x) \ do { \ x = ((buf)[0] << 24) | \ ((buf)[1] << 16) | \ ((buf)[2] << 8) | \ ((buf)[3]); \ } while(0) /* Convert an integer on 32 bits to an octet string from aSN1c tool */ #define INT32_TO_OCTET_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(4, sizeof(uint8_t)); \ INT32_TO_BUFFER(x, ((aSN)->buf)); \ (aSN)->size = 4; \ } while(0) #define INT32_TO_BIT_STRING(x, aSN) \ do { \ INT32_TO_OCTET_STRING(x, aSN); \ (aSN)->bits_unused = 0; \ } while(0) #define INT16_TO_OCTET_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(2, sizeof(uint8_t)); \ INT16_TO_BUFFER(x, ((aSN)->buf)); \ (aSN)->size = 2; \ } while(0) #define INT16_TO_BIT_STRING(x, aSN) \ do { \ INT16_TO_OCTET_STRING(x, aSN); \ (aSN)->bits_unused = 0; \ } while(0) #define INT24_TO_OCTET_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(3, sizeof(uint8_t)); \ INT24_TO_BUFFER(x, ((aSN)->buf)); \ (aSN)->size = 3; \ } while(0) #define INT24_TO_BIT_STRING(x, aSN) \ do { \ INT24_TO_OCTET_STRING(x, aSN); \ (aSN)->bits_unused = 0; \ } while(0) #define INT8_TO_OCTET_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(1, sizeof(uint8_t)); \ (aSN)->size = 1; \ INT8_TO_BUFFER(x, (aSN)->buf); \ } while(0) #define MME_CODE_TO_OCTET_STRING INT8_TO_OCTET_STRING #define M_TMSI_TO_OCTET_STRING INT32_TO_OCTET_STRING #define MME_GID_TO_OCTET_STRING INT16_TO_OCTET_STRING #define AMF_REGION_TO_BIT_STRING(x, aSN) \ do { \ INT8_TO_OCTET_STRING(x, aSN); \ (aSN)->bits_unused = 0; \ } while(0) #define AMF_SETID_TO_BIT_STRING(x, aSN) \ do { \ INT16_TO_OCTET_STRING(x, aSN); \ (aSN)->bits_unused = 6; \ } while(0) #define AMF_POINTER_TO_BIT_STRING(x, aSN) \ do { \ INT8_TO_OCTET_STRING(x, aSN); \ (aSN)->bits_unused = 2; \ } while(0) #define ENCRALG_TO_BIT_STRING(encralg, bitstring) \ do { \ (bitstring)->size=2; \ (bitstring)->bits_unused=0; \ (bitstring)->buf=calloc (2, sizeof (uint8_t)); \ (bitstring)->buf[0] = (encralg) >> 8; \ (bitstring)->buf[1] = (encralg); \ }while(0) #define INTPROTALG_TO_BIT_STRING(intprotalg, bitstring) \ do { \ (bitstring)->size=2; \ (bitstring)->bits_unused=0; \ (bitstring)->buf=calloc (2, sizeof (uint8_t)); \ (bitstring)->buf[0] = (intprotalg) >> 8; \ (bitstring)->buf[1] = (intprotalg); \ }while(0) #define KENB_STAR_TO_BIT_STRING(kenbstar, bitstring) \ do { \ (bitstring)->size=32; \ (bitstring)->bits_unused=0; \ (bitstring)->buf= calloc (32, sizeof (uint8_t));\ memcpy((bitstring)->buf, kenbstar, 32*sizeof(uint8_t)); \ }while(0) #define UEAGMAXBITRTD_TO_ASN_PRIMITIVES(uegmaxbitrtd, asnprimitives) \ do { \ (asnprimitives)->size=5; \ (asnprimitives)->buf=calloc (5, sizeof (uint8_t)); \ (asnprimitives)->buf[0] = (uegmaxbitrtd) >> 32; \ (asnprimitives)->buf[1] = (uegmaxbitrtd) >> 24; \ (asnprimitives)->buf[2] = (uegmaxbitrtd) >> 16; \ (asnprimitives)->buf[3] = (uegmaxbitrtd) >> 8; \ (asnprimitives)->buf[4] = (uegmaxbitrtd); \ }while(0) #define UEAGMAXBITRTU_TO_ASN_PRIMITIVES(uegmaxbitrtu, asnprimitives) \ do { \ (asnprimitives)->size=5; \ (asnprimitives)->buf=calloc (5, sizeof (uint8_t)); \ (asnprimitives)->buf[0] = (uegmaxbitrtu) >> 32; \ (asnprimitives)->buf[1] = (uegmaxbitrtu) >> 24; \ (asnprimitives)->buf[2] = (uegmaxbitrtu) >> 16; \ (asnprimitives)->buf[3] = (uegmaxbitrtu) >> 8; \ (asnprimitives)->buf[4] = (uegmaxbitrtu); \ }while(0) #define OCTET_STRING_TO_INT8(aSN, x) \ do { \ DevCheck((aSN)->size == 1, (aSN)->size, 0, 0); \ BUFFER_TO_INT8((aSN)->buf, x); \ } while(0) #define OCTET_STRING_TO_INT16(aSN, x) \ do { \ DevCheck((aSN)->size == 2 || (aSN)->size == 3, (aSN)->size, 0, 0); \ BUFFER_TO_INT16((aSN)->buf, x); \ } while(0) #define OCTET_STRING_TO_INT24(aSN, x) \ do { \ DevCheck((aSN)->size == 2 || (aSN)->size == 3, (aSN)->size, 0, 0); \ BUFFER_TO_INT24((aSN)->buf, x); \ } while(0) #define OCTET_STRING_TO_INT32(aSN, x) \ do { \ DevCheck((aSN)->size == 4, (aSN)->size, 0, 0); \ BUFFER_TO_INT32((aSN)->buf, x); \ } while(0) #define BIT_STRING_TO_INT32(aSN, x) \ do { \ DevCheck((aSN)->bits_unused == 0, (aSN)->bits_unused, 0, 0); \ OCTET_STRING_TO_INT32(aSN, x); \ } while(0) #define BIT_STRING_TO_CELL_IDENTITY(aSN, vALUE) \ do { \ DevCheck((aSN)->bits_unused == 4, (aSN)->bits_unused, 4, 0); \ vALUE = ((aSN)->buf[0] << 20) | ((aSN)->buf[1] << 12) | \ ((aSN)->buf[2] << 4) | (aSN)->buf[3]; \ } while(0) #define BIT_STRING_TO_NR_CELL_IDENTITY(aSN, vALUE) \ do { \ DevCheck((aSN)->bits_unused == 4, (aSN)->bits_unused, 4, 0); \ vALUE = ((aSN)->buf[0] << 28) | ((aSN)->buf[1] << 20) | \ ((aSN)->buf[2] << 12) | ((aSN)->buf[3]<<4) | ((aSN)->buf[4]>>4); \ } while(0) #define MCC_HUNDREDS(vALUE) \ ((vALUE) / 100) /* When MNC is only composed of 2 digits, set the hundreds unit to 0xf */ #define MNC_HUNDREDS(vALUE, mNCdIGITlENGTH) \ ( mNCdIGITlENGTH == 2 ? 15 : (vALUE) / 100) #define MCC_MNC_DECIMAL(vALUE) \ (((vALUE) / 10) % 10) #define MCC_MNC_DIGIT(vALUE) \ ((vALUE) % 10) #define MCC_TO_BUFFER(mCC, bUFFER) \ do { \ DevAssert(bUFFER != NULL); \ (bUFFER)[0] = MCC_HUNDREDS(mCC); \ (bUFFER)[1] = MCC_MNC_DECIMAL(mCC); \ (bUFFER)[2] = MCC_MNC_DIGIT(mCC); \ } while(0) #define MCC_MNC_TO_PLMNID(mCC, mNC, mNCdIGITlENGTH, oCTETsTRING) \ do { \ (oCTETsTRING)->buf = calloc(3, sizeof(uint8_t)); \ (oCTETsTRING)->buf[0] = (MCC_MNC_DECIMAL(mCC) << 4) | MCC_HUNDREDS(mCC); \ (oCTETsTRING)->buf[1] = (MNC_HUNDREDS(mNC,mNCdIGITlENGTH) << 4) | MCC_MNC_DIGIT(mCC); \ (oCTETsTRING)->buf[2] = (MCC_MNC_DIGIT(mNC) << 4) | MCC_MNC_DECIMAL(mNC); \ (oCTETsTRING)->size = 3; \ } while(0) #define PLMNID_TO_MCC_MNC(oCTETsTRING, mCC, mNC, mNCdIGITlENGTH) \ do { \ mCC = ((oCTETsTRING)->buf[0] & 0x0F) * 100 + \ ((oCTETsTRING)->buf[0] >> 4 & 0x0F) * 10 + \ ((oCTETsTRING)->buf[1] & 0x0F); \ mNCdIGITlENGTH = ((oCTETsTRING)->buf[1] >> 4 & 0x0F) == 0xF ? 2 : 3; \ mNC = (mNCdIGITlENGTH == 2 ? 0 : ((oCTETsTRING)->buf[1] >> 4 & 0x0F) * 100) + \ ((oCTETsTRING)->buf[2] & 0x0F) * 10 + \ ((oCTETsTRING)->buf[2] >> 4 & 0x0F); \ } while (0) #define MCC_MNC_TO_TBCD(mCC, mNC, mNCdIGITlENGTH, tBCDsTRING) \ do { \ char _buf[3]; \ DevAssert((mNCdIGITlENGTH == 3) || (mNCdIGITlENGTH == 2)); \ _buf[0] = (MCC_MNC_DECIMAL(mCC) << 4) | MCC_HUNDREDS(mCC); \ _buf[1] = (MNC_HUNDREDS(mNC,mNCdIGITlENGTH) << 4) | MCC_MNC_DIGIT(mCC);\ _buf[2] = (MCC_MNC_DIGIT(mNC) << 4) | MCC_MNC_DECIMAL(mNC); \ OCTET_STRING_fromBuf(tBCDsTRING, _buf, 3); \ } while(0) #define TBCD_TO_MCC_MNC(tBCDsTRING, mCC, mNC, mNCdIGITlENGTH) \ do { \ int mNC_hundred; \ DevAssert((tBCDsTRING)->size == 3); \ mNC_hundred = (((tBCDsTRING)->buf[1] & 0xf0) >> 4); \ if (mNC_hundred == 0xf) { \ mNC_hundred = 0; \ mNCdIGITlENGTH = 2; \ } else { \ mNCdIGITlENGTH = 3; \ } \ mCC = (((((tBCDsTRING)->buf[0]) & 0xf0) >> 4) * 10) + \ ((((tBCDsTRING)->buf[0]) & 0x0f) * 100) + \ (((tBCDsTRING)->buf[1]) & 0x0f); \ mNC = (mNC_hundred * 100) + \ ((((tBCDsTRING)->buf[2]) & 0xf0) >> 4) + \ ((((tBCDsTRING)->buf[2]) & 0x0f) * 10); \ } while(0) #define TBCD_TO_PLMN_T(tBCDsTRING, pLMN) \ do { \ DevAssert((tBCDsTRING)->size == 3); \ (pLMN)->MCCdigit2 = (((tBCDsTRING)->buf[0] & 0xf0) >> 4); \ (pLMN)->MCCdigit3 = ((tBCDsTRING)->buf[0] & 0x0f); \ (pLMN)->MCCdigit1 = (tBCDsTRING)->buf[1] & 0x0f; \ (pLMN)->MNCdigit3 = (((tBCDsTRING)->buf[1] & 0xf0) >> 4) == 0xF \ ? 0 : (((tBCDsTRING)->buf[1] & 0xf0) >> 4); \ (pLMN)->MNCdigit2 = (((tBCDsTRING)->buf[2] & 0xf0) >> 4); \ (pLMN)->MNCdigit1 = ((tBCDsTRING)->buf[2] & 0x0f); \ } while(0) #define PLMN_T_TO_TBCD(pLMN, tBCDsTRING, mNClENGTH) \ do { \ tBCDsTRING[0] = (pLMN.MCCdigit2 << 4) | pLMN.MCCdigit1; \ /* ambiguous (think about len 2) */ \ if (mNClENGTH == 2) { \ tBCDsTRING[1] = (0x0F << 4) | pLMN.MCCdigit3; \ tBCDsTRING[2] = (pLMN.MNCdigit2 << 4) | pLMN.MNCdigit1; \ } else { \ tBCDsTRING[1] = (pLMN.MNCdigit3 << 4) | pLMN.MCCdigit3; \ tBCDsTRING[2] = (pLMN.MNCdigit2 << 4) | pLMN.MNCdigit1; \ } \ } while(0) #define PLMN_T_TO_MCC_MNC(pLMN, mCC, mNC, mNCdIGITlENGTH) \ do { \ mCC = pLMN.MCCdigit3 * 100 + pLMN.MCCdigit2 * 10 + pLMN.MCCdigit1; \ mNCdIGITlENGTH = (pLMN.MNCdigit3 == 0xF ? 2 : 3); \ mNC = (mNCdIGITlENGTH == 2 ? 0 : pLMN.MNCdigit3 * 100) \ + pLMN.MNCdigit2 * 10 + pLMN.MNCdigit1; \ } while(0) /* TS 38.473 v15.2.1 section 9.3.1.32: * C RNTI is BIT_STRING(16) */ #define C_RNTI_TO_BIT_STRING(mACRO, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(2, sizeof(uint8_t)); \ (bITsTRING)->buf[0] = (mACRO) >> 8; \ (bITsTRING)->buf[1] = ((mACRO) & 0x0ff); \ (bITsTRING)->size = 2; \ (bITsTRING)->bits_unused = 0; \ } while(0) /* TS 38.473 v15.2.1 section 9.3.2.3: * TRANSPORT LAYER ADDRESS for IPv4 is 32bit (TS 38.414) */ #define TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(mACRO, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \ (bITsTRING)->buf[3] = (mACRO) >> 24 & 0xFF; \ (bITsTRING)->buf[2] = (mACRO) >> 16 & 0xFF; \ (bITsTRING)->buf[1] = (mACRO) >> 8 & 0xFF; \ (bITsTRING)->buf[0] = (mACRO) & 0xFF; \ (bITsTRING)->size = 4; \ (bITsTRING)->bits_unused = 0; \ } while(0) #define BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(bITsTRING, mACRO) \ do { \ DevCheck((bITsTRING)->size == 4, (bITsTRING)->size, 4, 0); \ DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \ mACRO = ((bITsTRING)->buf[3] << 24) + \ ((bITsTRING)->buf[2] << 16) + \ ((bITsTRING)->buf[1] << 8) + \ ((bITsTRING)->buf[0]); \ } while (0) /* TS 38.473 v15.1.1 section 9.3.1.12: * NR CELL ID */ #define NR_CELL_ID_TO_BIT_STRING(mACRO, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(5, sizeof(uint8_t)); \ (bITsTRING)->buf[0] = ((mACRO) >> 28) & 0xff; \ (bITsTRING)->buf[1] = ((mACRO) >> 20) & 0xff; \ (bITsTRING)->buf[2] = ((mACRO) >> 12) & 0xff; \ (bITsTRING)->buf[3] = ((mACRO) >> 4) & 0xff; \ (bITsTRING)->buf[4] = ((mACRO) & 0x0f) << 4; \ (bITsTRING)->size = 5; \ (bITsTRING)->bits_unused = 4; \ } while(0) /* #define INT16_TO_3_BYTE_BUFFER(x, buf) \ do { \ (buf)[0] = 0x00; \ (buf)[1] = (x) >> 8; \ (buf)[2] = (x); \ } while(0) */ #define NR_FIVEGS_TAC_ID_TO_BIT_STRING(x, aSN) \ do { \ (aSN)->buf = calloc(3, sizeof(uint8_t)); \ (aSN)->size = 3; \ (aSN)->buf[0] = 0x00; \ (aSN)->buf[1] = (x) >> 8; \ (aSN)->buf[2] = (x); \ } while(0) /* TS 38.473 v15.2.1 section 9.3.1.55: * MaskedIMEISV is BIT_STRING(64) */ #define MaskedIMEISV_TO_BIT_STRING(mACRO, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(8, sizeof(uint8_t)); \ (bITsTRING)->buf[0] = (mACRO) >> 56 & 0xFF; \ (bITsTRING)->buf[1] = (mACRO) >> 48 & 0xFF; \ (bITsTRING)->buf[2] = (mACRO) >> 40 & 0xFF; \ (bITsTRING)->buf[3] = (mACRO) >> 32 & 0xFF; \ (bITsTRING)->buf[4] = (mACRO) >> 24 & 0xFF; \ (bITsTRING)->buf[5] = (mACRO) >> 16 & 0xFF; \ (bITsTRING)->buf[6] = (mACRO) >> 8 & 0xFF; \ (bITsTRING)->buf[7] = (mACRO) >> 4 & 0xFF; \ (bITsTRING)->size = 8; \ (bITsTRING)->bits_unused = 0; \ } while(0) #define BIT_STRING_TO_MaskedIMEISV(bITsTRING, mACRO) \ do { \ DevCheck((bITsTRING)->size == 8, (bITsTRING)->size, 8, 0); \ DevCheck((bITsTRING)->bits_unused == 0, (bITsTRING)->bits_unused, 0, 0); \ mACRO = ((bITsTRING)->buf[0] << 56) + \ ((bITsTRING)->buf[1] << 48) + \ ((bITsTRING)->buf[2] << 40) + \ ((bITsTRING)->buf[3] << 32) + \ ((bITsTRING)->buf[4] << 24) + \ ((bITsTRING)->buf[5] << 16) + \ ((bITsTRING)->buf[6] << 8) + \ ((bITsTRING)->buf[7]); \ } while (0) /* TS 36.413 v10.9.0 section 9.2.1.37: * Macro eNB ID: * Equal to the 20 leftmost bits of the Cell * Identity IE contained in the E-UTRAN CGI * IE (see subclause 9.2.1.38) of each cell * served by the eNB. */ #define MACRO_ENB_ID_TO_BIT_STRING(mACRO, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(3, sizeof(uint8_t)); \ (bITsTRING)->buf[0] = ((mACRO) >> 12); \ (bITsTRING)->buf[1] = (mACRO) >> 4; \ (bITsTRING)->buf[2] = ((mACRO) & 0x0f) << 4; \ (bITsTRING)->size = 3; \ (bITsTRING)->bits_unused = 4; \ } while(0) #define MACRO_GNB_ID_TO_BIT_STRING(mACRO, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \ (bITsTRING)->buf[0] = ((mACRO) >> 20); \ (bITsTRING)->buf[1] = (mACRO) >> 12; \ (bITsTRING)->buf[2] = (mACRO) >> 4; \ (bITsTRING)->buf[3] = ((mACRO) & 0x0f) << 4; \ (bITsTRING)->size = 4; \ (bITsTRING)->bits_unused = 4; \ } while(0) /* TS 36.413 v10.9.0 section 9.2.1.38: * E-UTRAN CGI/Cell Identity * The leftmost bits of the Cell * Identity correspond to the eNB * ID (defined in subclause 9.2.1.37). */ #define MACRO_ENB_ID_TO_CELL_IDENTITY(mACRO, cELL_iD, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(4, sizeof(uint8_t)); \ (bITsTRING)->buf[0] = ((mACRO) >> 12); \ (bITsTRING)->buf[1] = (mACRO) >> 4; \ (bITsTRING)->buf[2] = (((mACRO) & 0x0f) << 4) | ((cELL_iD) >> 4); \ (bITsTRING)->buf[3] = ((cELL_iD) & 0x0f) << 4; \ (bITsTRING)->size = 4; \ (bITsTRING)->bits_unused = 4; \ } while(0) #define MACRO_GNB_ID_TO_CELL_IDENTITY(mACRO, cELL_iD, bITsTRING) \ do { \ (bITsTRING)->buf = calloc(5, sizeof(uint8_t)); \ (bITsTRING)->buf[0] = ((mACRO) >> 20); \ (bITsTRING)->buf[1] = (mACRO) >> 12; \ (bITsTRING)->buf[2] = (mACRO) >> 4; \ (bITsTRING)->buf[3] = (((mACRO) & 0x0f) << 4) | ((cELL_iD) >> 4); \ (bITsTRING)->buf[4] = ((cELL_iD) & 0x0f) << 4; \ (bITsTRING)->size = 5; \ (bITsTRING)->bits_unused = 4; \ } while(0) /* Used to format an uint32_t containing an ipv4 address */ #define IPV4_ADDR "%u.%u.%u.%u" #define IPV4_ADDR_FORMAT(aDDRESS) \ (uint8_t)((aDDRESS) & 0x000000ff), \ (uint8_t)(((aDDRESS) & 0x0000ff00) >> 8 ), \ (uint8_t)(((aDDRESS) & 0x00ff0000) >> 16), \ (uint8_t)(((aDDRESS) & 0xff000000) >> 24) #define IPV4_ADDR_DISPLAY_8(aDDRESS) \ (aDDRESS)[0], (aDDRESS)[1], (aDDRESS)[2], (aDDRESS)[3] #define TAC_TO_ASN1 INT16_TO_OCTET_STRING #define GTP_TEID_TO_ASN1 INT32_TO_OCTET_STRING #define OCTET_STRING_TO_TAC OCTET_STRING_TO_INT16 void hexa_to_ascii(uint8_t *from, char *to, size_t length); int ascii_to_hex(uint8_t *dst, const char *h); #endif /* CONVERSIONS_H_ */