renamed openair-cn to openair3
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7886 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -0,0 +1,315 @@
|
||||
/*
|
||||
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those
|
||||
* of the authors and should not be interpreted as representing official policies,
|
||||
* either expressed or implied, of the FreeBSD Project.
|
||||
*/
|
||||
|
||||
#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 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)); \
|
||||
(aSN)->size = 2; \
|
||||
INT16_TO_BUFFER(x, (aSN)->buf); \
|
||||
} 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 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, 0, 0); \
|
||||
BUFFER_TO_INT16((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 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 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 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)
|
||||
/*
|
||||
/* 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)
|
||||
|
||||
/* 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_ */
|
||||
Reference in New Issue
Block a user