summaryrefslogtreecommitdiffstats
path: root/src/shared/libosmocore/src/gsm
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/libosmocore/src/gsm')
-rw-r--r--src/shared/libosmocore/src/gsm/Makefile.am27
-rw-r--r--src/shared/libosmocore/src/gsm/a5.c367
-rw-r--r--src/shared/libosmocore/src/gsm/abis_nm.c455
-rw-r--r--src/shared/libosmocore/src/gsm/auth_comp128v1.c47
-rw-r--r--src/shared/libosmocore/src/gsm/auth_core.c172
-rw-r--r--src/shared/libosmocore/src/gsm/auth_milenage.c120
-rw-r--r--src/shared/libosmocore/src/gsm/comp128.c230
-rw-r--r--src/shared/libosmocore/src/gsm/gan.c77
-rw-r--r--src/shared/libosmocore/src/gsm/gprs_cipher_core.c99
-rw-r--r--src/shared/libosmocore/src/gsm/gsm0411_smc.c541
-rw-r--r--src/shared/libosmocore/src/gsm/gsm0411_smr.c451
-rw-r--r--src/shared/libosmocore/src/gsm/gsm0411_utils.c314
-rw-r--r--src/shared/libosmocore/src/gsm/gsm0480.c461
-rw-r--r--src/shared/libosmocore/src/gsm/gsm0502.c43
-rw-r--r--src/shared/libosmocore/src/gsm/gsm0808.c402
-rw-r--r--src/shared/libosmocore/src/gsm/gsm48.c451
-rw-r--r--src/shared/libosmocore/src/gsm/gsm48_ie.c1192
-rw-r--r--src/shared/libosmocore/src/gsm/gsm_utils.c606
-rw-r--r--src/shared/libosmocore/src/gsm/lapd_core.c2169
-rw-r--r--src/shared/libosmocore/src/gsm/lapdm.c1249
-rw-r--r--src/shared/libosmocore/src/gsm/libosmogsm.map236
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/aes-encblock.c38
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c121
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/aes-internal.c805
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/aes.h27
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/aes_i.h122
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/aes_wrap.h48
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/common.h20
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/crypto.h0
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/includes.h0
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/milenage.c344
-rw-r--r--src/shared/libosmocore/src/gsm/milenage/milenage.h35
-rw-r--r--src/shared/libosmocore/src/gsm/rsl.c507
-rw-r--r--src/shared/libosmocore/src/gsm/rxlev_stat.c82
-rw-r--r--src/shared/libosmocore/src/gsm/sysinfo.c136
-rw-r--r--src/shared/libosmocore/src/gsm/tlv_parser.c209
36 files changed, 0 insertions, 12203 deletions
diff --git a/src/shared/libosmocore/src/gsm/Makefile.am b/src/shared/libosmocore/src/gsm/Makefile.am
deleted file mode 100644
index 0544e0a1..00000000
--- a/src/shared/libosmocore/src/gsm/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-# This is _NOT_ the library release version, it's an API version.
-# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
-LIBVERSION=3:0:0
-
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS = -Wall ${GCC_FVISIBILITY_HIDDEN}
-
-# FIXME: this should eventually go into a milenage/Makefile.am
-noinst_HEADERS = milenage/aes.h milenage/aes_i.h milenage/aes_wrap.h \
- milenage/common.h milenage/crypto.h milenage/includes.h \
- milenage/milenage.h
-
-lib_LTLIBRARIES = libosmogsm.la
-
-libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c gsm_utils.c \
- rsl.c gsm48.c gsm48_ie.c gsm0808.c sysinfo.c \
- gprs_cipher_core.c gsm0480.c abis_nm.c gsm0502.c \
- gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \
- lapd_core.c lapdm.c \
- auth_core.c auth_comp128v1.c auth_milenage.c \
- milenage/aes-encblock.c milenage/aes-internal.c \
- milenage/aes-internal-enc.c milenage/milenage.c gan.c
-
-libosmogsm_la_LDFLAGS = $(LTLDFLAGS_OSMOGSM) -version-info $(LIBVERSION)
-libosmogsm_la_LIBADD = $(top_builddir)/src/libosmocore.la
-
-EXTRA_DIST = libosmogsm.map
diff --git a/src/shared/libosmocore/src/gsm/a5.c b/src/shared/libosmocore/src/gsm/a5.c
deleted file mode 100644
index 356060ab..00000000
--- a/src/shared/libosmocore/src/gsm/a5.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * a5.c
- *
- * Full reimplementation of A5/1,2 (split and threadsafe)
- *
- * The logic behind the algorithm is taken from "A pedagogical implementation
- * of the GSM A5/1 and A5/2 "voice privacy" encryption algorithms." by
- * Marc Briceno, Ian Goldberg, and David Wagner.
- *
- * Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/*! \addtogroup a5
- * @{
- */
-
-/*! \file gsm/a5.c
- * \brief Osmocom GSM A5 ciphering algorithm implementation
- */
-
-#include <string.h>
-
-#include <osmocom/gsm/a5.h>
-
-/*! \brief Main method to generate a A5/x cipher stream
- * \param[in] n Which A5/x method to use
- * \param[in] key 8 byte array for the key (as received from the SIM)
- * \param[in] fn Frame number
- * \param[out] dl Pointer to array of ubits to return Downlink cipher stream
- * \param[out] ul Pointer to array of ubits to return Uplink cipher stream
- *
- * Currently A5/[0-2] are supported.
- * Either (or both) of dl/ul can be NULL if not needed.
- */
-void
-osmo_a5(int n, const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
-{
- switch (n)
- {
- case 0:
- if (dl)
- memset(dl, 0x00, 114);
- if (ul)
- memset(ul, 0x00, 114);
- break;
-
- case 1:
- osmo_a5_1(key, fn, dl, ul);
- break;
-
- case 2:
- osmo_a5_2(key, fn, dl, ul);
- break;
-
- default:
- /* a5/[3..7] not supported here/yet */
- break;
- }
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* A5/1&2 common stuff */
-/* ------------------------------------------------------------------------ */
-
-#define A5_R1_LEN 19
-#define A5_R2_LEN 22
-#define A5_R3_LEN 23
-#define A5_R4_LEN 17 /* A5/2 only */
-
-#define A5_R1_MASK ((1<<A5_R1_LEN)-1)
-#define A5_R2_MASK ((1<<A5_R2_LEN)-1)
-#define A5_R3_MASK ((1<<A5_R3_LEN)-1)
-#define A5_R4_MASK ((1<<A5_R4_LEN)-1)
-
-#define A5_R1_TAPS 0x072000 /* x^19 + x^18 + x^17 + x^14 + 1 */
-#define A5_R2_TAPS 0x300000 /* x^22 + x^21 + 1 */
-#define A5_R3_TAPS 0x700080 /* x^23 + x^22 + x^21 + x^8 + 1 */
-#define A5_R4_TAPS 0x010800 /* x^17 + x^12 + 1 */
-
-/*! \brief Computes parity of a 32-bit word
- * \param[in] x 32 bit word
- * \return Parity bit (xor of all bits) as 0 or 1
- */
-static inline uint32_t
-_a5_12_parity(uint32_t x)
-{
- x ^= x >> 16;
- x ^= x >> 8;
- x ^= x >> 4;
- x &= 0xf;
- return (0x6996 >> x) & 1;
-}
-
-/*! \brief Compute majority bit from 3 taps
- * \param[in] v1 LFSR state ANDed with tap-bit
- * \param[in] v2 LFSR state ANDed with tap-bit
- * \param[in] v3 LFSR state ANDed with tap-bit
- * \return The majority bit (0 or 1)
- */
-static inline uint32_t
-_a5_12_majority(uint32_t v1, uint32_t v2, uint32_t v3)
-{
- return (!!v1 + !!v2 + !!v3) >= 2;
-}
-
-/*! \brief Compute the next LFSR state
- * \param[in] r Current state
- * \param[in] mask LFSR mask
- * \param[in] taps LFSR taps
- * \return Next state
- */
-static inline uint32_t
-_a5_12_clock(uint32_t r, uint32_t mask, uint32_t taps)
-{
- return ((r << 1) & mask) | _a5_12_parity(r & taps);
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* A5/1 */
-/* ------------------------------------------------------------------------ */
-
-#define A51_R1_CLKBIT 0x000100
-#define A51_R2_CLKBIT 0x000400
-#define A51_R3_CLKBIT 0x000400
-
-/*! \brief GSM A5/1 Clocking function
- * \param[in] r Register state
- * \param[in] force Non-zero value disable conditional clocking
- */
-static inline void
-_a5_1_clock(uint32_t r[], int force)
-{
- int cb[3], maj;
-
- cb[0] = !!(r[0] & A51_R1_CLKBIT);
- cb[1] = !!(r[1] & A51_R2_CLKBIT);
- cb[2] = !!(r[2] & A51_R3_CLKBIT);
-
- maj = _a5_12_majority(cb[0], cb[1], cb[2]);
-
- if (force || (maj == cb[0]))
- r[0] = _a5_12_clock(r[0], A5_R1_MASK, A5_R1_TAPS);
-
- if (force || (maj == cb[1]))
- r[1] = _a5_12_clock(r[1], A5_R2_MASK, A5_R2_TAPS);
-
- if (force || (maj == cb[2]))
- r[2] = _a5_12_clock(r[2], A5_R3_MASK, A5_R3_TAPS);
-}
-
-/*! \brief GSM A5/1 Output function
- * \param[in] r Register state
- * \return The A5/1 output function bit
- */
-static inline uint8_t
-_a5_1_get_output(uint32_t r[])
-{
- return (r[0] >> (A5_R1_LEN-1)) ^
- (r[1] >> (A5_R2_LEN-1)) ^
- (r[2] >> (A5_R3_LEN-1));
-}
-
-/*! \brief Generate a GSM A5/1 cipher stream
- * \param[in] key 8 byte array for the key (as received from the SIM)
- * \param[in] fn Frame number
- * \param[out] dl Pointer to array of ubits to return Downlink cipher stream
- * \param[out] ul Pointer to array of ubits to return Uplink cipher stream
- *
- * Either (or both) of dl/ul can be NULL if not needed.
- */
-void
-osmo_a5_1(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
-{
- uint32_t r[3] = {0, 0, 0};
- uint32_t fn_count;
- uint32_t b;
- int i;
-
- /* Key load */
- for (i=0; i<64; i++)
- {
- b = ( key[7 - (i>>3)] >> (i&7) ) & 1;
-
- _a5_1_clock(r, 1);
-
- r[0] ^= b;
- r[1] ^= b;
- r[2] ^= b;
- }
-
- /* Frame count load */
- fn_count = osmo_a5_fn_count(fn);
-
- for (i=0; i<22; i++)
- {
- b = (fn_count >> i) & 1;
-
- _a5_1_clock(r, 1);
-
- r[0] ^= b;
- r[1] ^= b;
- r[2] ^= b;
- }
-
- /* Mix */
- for (i=0; i<100; i++)
- {
- _a5_1_clock(r, 0);
- }
-
- /* Output */
- for (i=0; i<114; i++) {
- _a5_1_clock(r, 0);
- if (dl)
- dl[i] = _a5_1_get_output(r);
- }
-
- for (i=0; i<114; i++) {
- _a5_1_clock(r, 0);
- if (ul)
- ul[i] = _a5_1_get_output(r);
- }
-}
-
-
-/* ------------------------------------------------------------------------ */
-/* A5/2 */
-/* ------------------------------------------------------------------------ */
-
-#define A52_R4_CLKBIT0 0x000400
-#define A52_R4_CLKBIT1 0x000008
-#define A52_R4_CLKBIT2 0x000080
-
-/*! \brief GSM A5/2 Clocking function
- * \param[in] r Register state
- * \param[in] force Non-zero value disable conditional clocking
- */
-static inline void
-_a5_2_clock(uint32_t r[], int force)
-{
- int cb[3], maj;
-
- cb[0] = !!(r[3] & A52_R4_CLKBIT0);
- cb[1] = !!(r[3] & A52_R4_CLKBIT1);
- cb[2] = !!(r[3] & A52_R4_CLKBIT2);
-
- maj = (cb[0] + cb[1] + cb[2]) >= 2;
-
- if (force || (maj == cb[0]))
- r[0] = _a5_12_clock(r[0], A5_R1_MASK, A5_R1_TAPS);
-
- if (force || (maj == cb[1]))
- r[1] = _a5_12_clock(r[1], A5_R2_MASK, A5_R2_TAPS);
-
- if (force || (maj == cb[2]))
- r[2] = _a5_12_clock(r[2], A5_R3_MASK, A5_R3_TAPS);
-
- r[3] = _a5_12_clock(r[3], A5_R4_MASK, A5_R4_TAPS);
-}
-
-/*! \brief GSM A5/2 Output function
- * \param[in] r Register state
- * \return The A5/2 output function bit
- */
-static inline uint8_t
-_a5_2_get_output(uint32_t r[])
-{
- uint8_t b;
-
- b = (r[0] >> (A5_R1_LEN-1)) ^
- (r[1] >> (A5_R2_LEN-1)) ^
- (r[2] >> (A5_R3_LEN-1)) ^
- _a5_12_majority( r[0] & 0x08000, ~r[0] & 0x04000, r[0] & 0x1000) ^
- _a5_12_majority(~r[1] & 0x10000, r[1] & 0x02000, r[1] & 0x0200) ^
- _a5_12_majority( r[2] & 0x40000, r[2] & 0x10000, ~r[2] & 0x2000);
-
- return b;
-}
-
-/*! \brief Generate a GSM A5/1 cipher stream
- * \param[in] key 8 byte array for the key (as received from the SIM)
- * \param[in] fn Frame number
- * \param[out] dl Pointer to array of ubits to return Downlink cipher stream
- * \param[out] ul Pointer to array of ubits to return Uplink cipher stream
- *
- * Either (or both) of dl/ul can be NULL if not needed.
- */
-void
-osmo_a5_2(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul)
-{
- uint32_t r[4] = {0, 0, 0, 0};
- uint32_t fn_count;
- uint32_t b;
- int i;
-
- /* Key load */
- for (i=0; i<64; i++)
- {
- b = ( key[7 - (i>>3)] >> (i&7) ) & 1;
-
- _a5_2_clock(r, 1);
-
- r[0] ^= b;
- r[1] ^= b;
- r[2] ^= b;
- r[3] ^= b;
- }
-
- /* Frame count load */
- fn_count = osmo_a5_fn_count(fn);
-
- for (i=0; i<22; i++)
- {
- b = (fn_count >> i) & 1;
-
- _a5_2_clock(r, 1);
-
- r[0] ^= b;
- r[1] ^= b;
- r[2] ^= b;
- r[3] ^= b;
- }
-
- r[0] |= 1 << 15;
- r[1] |= 1 << 16;
- r[2] |= 1 << 18;
- r[3] |= 1 << 10;
-
- /* Mix */
- for (i=0; i<99; i++)
- {
- _a5_2_clock(r, 0);
- }
-
- /* Output */
- for (i=0; i<114; i++) {
- _a5_2_clock(r, 0);
- if (dl)
- dl[i] = _a5_2_get_output(r);
- }
-
- for (i=0; i<114; i++) {
- _a5_2_clock(r, 0);
- if (ul)
- ul[i] = _a5_2_get_output(r);
- }
-}
-
-/*! @} */
diff --git a/src/shared/libosmocore/src/gsm/abis_nm.c b/src/shared/libosmocore/src/gsm/abis_nm.c
deleted file mode 100644
index f6d4003e..00000000
--- a/src/shared/libosmocore/src/gsm/abis_nm.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/* GSM Network Management (OML) messages on the A-bis interface
- * 3GPP TS 12.21 version 8.0.0 Release 1999 / ETSI TS 100 623 V8.0.0 */
-
-/* (C) 2008-2011 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/*! \addtogroup oml
- * @{
- */
-
-/*! \file abis_nm.c */
-
-#include <stdint.h>
-#include <errno.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/protocol/gsm_12_21.h>
-#include <osmocom/gsm/abis_nm.h>
-
-/*! \brief unidirectional messages from BTS to BSC */
-const enum abis_nm_msgtype abis_nm_reports[4] = {
- NM_MT_SW_ACTIVATED_REP,
- NM_MT_TEST_REP,
- NM_MT_STATECHG_EVENT_REP,
- NM_MT_FAILURE_EVENT_REP,
-};
-
-/*! \brief messages without ACK/NACK */
-const enum abis_nm_msgtype abis_nm_no_ack_nack[3] = {
- NM_MT_MEAS_RES_REQ,
- NM_MT_STOP_MEAS,
- NM_MT_START_MEAS,
-};
-
-/*! \brief messages related to software load */
-const enum abis_nm_msgtype abis_nm_sw_load_msgs[9] = {
- NM_MT_LOAD_INIT_ACK,
- NM_MT_LOAD_INIT_NACK,
- NM_MT_LOAD_SEG_ACK,
- NM_MT_LOAD_ABORT,
- NM_MT_LOAD_END_ACK,
- NM_MT_LOAD_END_NACK,
- //NM_MT_SW_ACT_REQ,
- NM_MT_ACTIVATE_SW_ACK,
- NM_MT_ACTIVATE_SW_NACK,
- NM_MT_SW_ACTIVATED_REP,
-};
-
-/*! \brief All NACKs (negative acknowledgements */
-const enum abis_nm_msgtype abis_nm_nacks[33] = {
- NM_MT_LOAD_INIT_NACK,
- NM_MT_LOAD_END_NACK,
- NM_MT_SW_ACT_REQ_NACK,
- NM_MT_ACTIVATE_SW_NACK,
- NM_MT_ESTABLISH_TEI_NACK,
- NM_MT_CONN_TERR_SIGN_NACK,
- NM_MT_DISC_TERR_SIGN_NACK,
- NM_MT_CONN_TERR_TRAF_NACK,
- NM_MT_DISC_TERR_TRAF_NACK,
- NM_MT_CONN_MDROP_LINK_NACK,
- NM_MT_DISC_MDROP_LINK_NACK,
- NM_MT_SET_BTS_ATTR_NACK,
- NM_MT_SET_RADIO_ATTR_NACK,
- NM_MT_SET_CHAN_ATTR_NACK,
- NM_MT_PERF_TEST_NACK,
- NM_MT_SEND_TEST_REP_NACK,
- NM_MT_STOP_TEST_NACK,
- NM_MT_STOP_EVENT_REP_NACK,
- NM_MT_REST_EVENT_REP_NACK,
- NM_MT_CHG_ADM_STATE_NACK,
- NM_MT_CHG_ADM_STATE_REQ_NACK,
- NM_MT_REP_OUTST_ALARMS_NACK,
- NM_MT_CHANGEOVER_NACK,
- NM_MT_OPSTART_NACK,
- NM_MT_REINIT_NACK,
- NM_MT_SET_SITE_OUT_NACK,
- NM_MT_CHG_HW_CONF_NACK,
- NM_MT_GET_ATTR_NACK,
- NM_MT_SET_ALARM_THRES_NACK,
- NM_MT_BS11_BEGIN_DB_TX_NACK,
- NM_MT_BS11_END_DB_TX_NACK,
- NM_MT_BS11_CREATE_OBJ_NACK,
- NM_MT_BS11_DELETE_OBJ_NACK,
-};
-
-static const struct value_string nack_names[] = {
- { NM_MT_LOAD_INIT_NACK, "SOFTWARE LOAD INIT" },
- { NM_MT_LOAD_END_NACK, "SOFTWARE LOAD END" },
- { NM_MT_SW_ACT_REQ_NACK, "SOFTWARE ACTIVATE REQUEST" },
- { NM_MT_ACTIVATE_SW_NACK, "ACTIVATE SOFTWARE" },
- { NM_MT_ESTABLISH_TEI_NACK, "ESTABLISH TEI" },
- { NM_MT_CONN_TERR_SIGN_NACK, "CONNECT TERRESTRIAL SIGNALLING" },
- { NM_MT_DISC_TERR_SIGN_NACK, "DISCONNECT TERRESTRIAL SIGNALLING" },
- { NM_MT_CONN_TERR_TRAF_NACK, "CONNECT TERRESTRIAL TRAFFIC" },
- { NM_MT_DISC_TERR_TRAF_NACK, "DISCONNECT TERRESTRIAL TRAFFIC" },
- { NM_MT_CONN_MDROP_LINK_NACK, "CONNECT MULTI-DROP LINK" },
- { NM_MT_DISC_MDROP_LINK_NACK, "DISCONNECT MULTI-DROP LINK" },
- { NM_MT_SET_BTS_ATTR_NACK, "SET BTS ATTRIBUTE" },
- { NM_MT_SET_RADIO_ATTR_NACK, "SET RADIO ATTRIBUTE" },
- { NM_MT_SET_CHAN_ATTR_NACK, "SET CHANNEL ATTRIBUTE" },
- { NM_MT_PERF_TEST_NACK, "PERFORM TEST" },
- { NM_MT_SEND_TEST_REP_NACK, "SEND TEST REPORT" },
- { NM_MT_STOP_TEST_NACK, "STOP TEST" },
- { NM_MT_STOP_EVENT_REP_NACK, "STOP EVENT REPORT" },
- { NM_MT_REST_EVENT_REP_NACK, "RESET EVENT REPORT" },
- { NM_MT_CHG_ADM_STATE_NACK, "CHANGE ADMINISTRATIVE STATE" },
- { NM_MT_CHG_ADM_STATE_REQ_NACK,
- "CHANGE ADMINISTRATIVE STATE REQUEST" },
- { NM_MT_REP_OUTST_ALARMS_NACK, "REPORT OUTSTANDING ALARMS" },
- { NM_MT_CHANGEOVER_NACK, "CHANGEOVER" },
- { NM_MT_OPSTART_NACK, "OPSTART" },
- { NM_MT_REINIT_NACK, "REINIT" },
- { NM_MT_SET_SITE_OUT_NACK, "SET SITE OUTPUT" },
- { NM_MT_CHG_HW_CONF_NACK, "CHANGE HARDWARE CONFIGURATION" },
- { NM_MT_GET_ATTR_NACK, "GET ATTRIBUTE" },
- { NM_MT_SET_ALARM_THRES_NACK, "SET ALARM THRESHOLD" },
- { NM_MT_BS11_BEGIN_DB_TX_NACK, "BS11 BEGIN DATABASE TRANSMISSION" },
- { NM_MT_BS11_END_DB_TX_NACK, "BS11 END DATABASE TRANSMISSION" },
- { NM_MT_BS11_CREATE_OBJ_NACK, "BS11 CREATE OBJECT" },
- { NM_MT_BS11_DELETE_OBJ_NACK, "BS11 DELETE OBJECT" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable string for OML NACK message type */
-const char *abis_nm_nack_name(uint8_t nack)
-{
- return get_value_string(nack_names, nack);
-}
-
-/* Chapter 9.4.36 */
-static const struct value_string nack_cause_names[] = {
- /* General Nack Causes */
- { NM_NACK_INCORR_STRUCT, "Incorrect message structure" },
- { NM_NACK_MSGTYPE_INVAL, "Invalid message type value" },
- { NM_NACK_OBJCLASS_INVAL, "Invalid Object class value" },
- { NM_NACK_OBJCLASS_NOTSUPP, "Object class not supported" },
- { NM_NACK_BTSNR_UNKN, "BTS no. unknown" },
- { NM_NACK_TRXNR_UNKN, "Baseband Transceiver no. unknown" },
- { NM_NACK_OBJINST_UNKN, "Object Instance unknown" },
- { NM_NACK_ATTRID_INVAL, "Invalid attribute identifier value" },
- { NM_NACK_ATTRID_NOTSUPP, "Attribute identifier not supported" },
- { NM_NACK_PARAM_RANGE, "Parameter value outside permitted range" },
- { NM_NACK_ATTRLIST_INCONSISTENT,"Inconsistency in attribute list" },
- { NM_NACK_SPEC_IMPL_NOTSUPP, "Specified implementation not supported" },
- { NM_NACK_CANT_PERFORM, "Message cannot be performed" },
- /* Specific Nack Causes */
- { NM_NACK_RES_NOTIMPL, "Resource not implemented" },
- { NM_NACK_RES_NOTAVAIL, "Resource not available" },
- { NM_NACK_FREQ_NOTAVAIL, "Frequency not available" },
- { NM_NACK_TEST_NOTSUPP, "Test not supported" },
- { NM_NACK_CAPACITY_RESTR, "Capacity restrictions" },
- { NM_NACK_PHYSCFG_NOTPERFORM, "Physical configuration cannot be performed" },
- { NM_NACK_TEST_NOTINIT, "Test not initiated" },
- { NM_NACK_PHYSCFG_NOTRESTORE, "Physical configuration cannot be restored" },
- { NM_NACK_TEST_NOSUCH, "No such test" },
- { NM_NACK_TEST_NOSTOP, "Test cannot be stopped" },
- { NM_NACK_MSGINCONSIST_PHYSCFG, "Message inconsistent with physical configuration" },
- { NM_NACK_FILE_INCOMPLETE, "Complete file notreceived" },
- { NM_NACK_FILE_NOTAVAIL, "File not available at destination" },
- { NM_NACK_FILE_NOTACTIVATE, "File cannot be activate" },
- { NM_NACK_REQ_NOT_GRANT, "Request not granted" },
- { NM_NACK_WAIT, "Wait" },
- { NM_NACK_NOTH_REPORT_EXIST, "Nothing reportable existing" },
- { NM_NACK_MEAS_NOTSUPP, "Measurement not supported" },
- { NM_NACK_MEAS_NOTSTART, "Measurement not started" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable string for NACK cause */
-const char *abis_nm_nack_cause_name(uint8_t cause)
-{
- return get_value_string(nack_cause_names, cause);
-}
-
-/* Chapter 9.4.16: Event Type */
-static const struct value_string event_type_names[] = {
- { NM_EVT_COMM_FAIL, "communication failure" },
- { NM_EVT_QOS_FAIL, "quality of service failure" },
- { NM_EVT_PROC_FAIL, "processing failure" },
- { NM_EVT_EQUIP_FAIL, "equipment failure" },
- { NM_EVT_ENV_FAIL, "environment failure" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable string for OML event type */
-const char *abis_nm_event_type_name(uint8_t cause)
-{
- return get_value_string(event_type_names, cause);
-}
-
-/* Chapter 9.4.63: Perceived Severity */
-static const struct value_string severity_names[] = {
- { NM_SEVER_CEASED, "failure ceased" },
- { NM_SEVER_CRITICAL, "critical failure" },
- { NM_SEVER_MAJOR, "major failure" },
- { NM_SEVER_MINOR, "minor failure" },
- { NM_SEVER_WARNING, "warning level failure" },
- { NM_SEVER_INDETERMINATE, "indeterminate failure" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable string for perceived OML severity */
-const char *abis_nm_severity_name(uint8_t cause)
-{
- return get_value_string(severity_names, cause);
-}
-
-/*! \brief Attributes that the BSC can set, not only get, according to Section 9.4 */
-const enum abis_nm_attr abis_nm_att_settable[] = {
- NM_ATT_ADD_INFO,
- NM_ATT_ADD_TEXT,
- NM_ATT_DEST,
- NM_ATT_EVENT_TYPE,
- NM_ATT_FILE_DATA,
- NM_ATT_GET_ARI,
- NM_ATT_HW_CONF_CHG,
- NM_ATT_LIST_REQ_ATTR,
- NM_ATT_MDROP_LINK,
- NM_ATT_MDROP_NEXT,
- NM_ATT_NACK_CAUSES,
- NM_ATT_OUTST_ALARM,
- NM_ATT_PHYS_CONF,
- NM_ATT_PROB_CAUSE,
- NM_ATT_RAD_SUBC,
- NM_ATT_SOURCE,
- NM_ATT_SPEC_PROB,
- NM_ATT_START_TIME,
- NM_ATT_TEST_DUR,
- NM_ATT_TEST_NO,
- NM_ATT_TEST_REPORT,
- NM_ATT_WINDOW_SIZE,
- NM_ATT_SEVERITY,
- NM_ATT_MEAS_RES,
- NM_ATT_MEAS_TYPE,
-};
-
-/*! \brief GSM A-bis OML TLV parser definition */
-const struct tlv_definition abis_nm_att_tlvdef = {
- .def = {
- [NM_ATT_ABIS_CHANNEL] = { TLV_TYPE_FIXED, 3 },
- [NM_ATT_ADD_INFO] = { TLV_TYPE_TL16V },
- [NM_ATT_ADD_TEXT] = { TLV_TYPE_TL16V },
- [NM_ATT_ADM_STATE] = { TLV_TYPE_TV },
- [NM_ATT_ARFCN_LIST]= { TLV_TYPE_TL16V },
- [NM_ATT_AUTON_REPORT] = { TLV_TYPE_TV },
- [NM_ATT_AVAIL_STATUS] = { TLV_TYPE_TL16V },
- [NM_ATT_BCCH_ARFCN] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_BSIC] = { TLV_TYPE_TV },
- [NM_ATT_BTS_AIR_TIMER] = { TLV_TYPE_TV },
- [NM_ATT_CCCH_L_I_P] = { TLV_TYPE_TV },
- [NM_ATT_CCCH_L_T] = { TLV_TYPE_TV },
- [NM_ATT_CHAN_COMB] = { TLV_TYPE_TV },
- [NM_ATT_CONN_FAIL_CRIT] = { TLV_TYPE_TL16V },
- [NM_ATT_DEST] = { TLV_TYPE_TL16V },
- [NM_ATT_EVENT_TYPE] = { TLV_TYPE_TV },
- [NM_ATT_FILE_DATA] = { TLV_TYPE_TL16V },
- [NM_ATT_FILE_ID] = { TLV_TYPE_TL16V },
- [NM_ATT_FILE_VERSION] = { TLV_TYPE_TL16V },
- [NM_ATT_GSM_TIME] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_HSN] = { TLV_TYPE_TV },
- [NM_ATT_HW_CONFIG] = { TLV_TYPE_TL16V },
- [NM_ATT_HW_DESC] = { TLV_TYPE_TL16V },
- [NM_ATT_INTAVE_PARAM] = { TLV_TYPE_TV },
- [NM_ATT_INTERF_BOUND] = { TLV_TYPE_FIXED, 6 },
- [NM_ATT_LIST_REQ_ATTR] = { TLV_TYPE_TL16V },
- [NM_ATT_MAIO] = { TLV_TYPE_TV },
- [NM_ATT_MANUF_STATE] = { TLV_TYPE_TV },
- [NM_ATT_MANUF_THRESH] = { TLV_TYPE_TL16V },
- [NM_ATT_MANUF_ID] = { TLV_TYPE_TL16V },
- [NM_ATT_MAX_TA] = { TLV_TYPE_TV },
- [NM_ATT_MDROP_LINK] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_MDROP_NEXT] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_NACK_CAUSES] = { TLV_TYPE_TV },
- [NM_ATT_NY1] = { TLV_TYPE_TV },
- [NM_ATT_OPER_STATE] = { TLV_TYPE_TV },
- [NM_ATT_OVERL_PERIOD] = { TLV_TYPE_TL16V },
- [NM_ATT_PHYS_CONF] = { TLV_TYPE_TL16V },
- [NM_ATT_POWER_CLASS] = { TLV_TYPE_TV },
- [NM_ATT_POWER_THRESH] = { TLV_TYPE_FIXED, 3 },
- [NM_ATT_PROB_CAUSE] = { TLV_TYPE_FIXED, 3 },
- [NM_ATT_RACH_B_THRESH] = { TLV_TYPE_TV },
- [NM_ATT_LDAVG_SLOTS] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_RAD_SUBC] = { TLV_TYPE_TV },
- [NM_ATT_RF_MAXPOWR_R] = { TLV_TYPE_TV },
- [NM_ATT_SITE_INPUTS] = { TLV_TYPE_TL16V },
- [NM_ATT_SITE_OUTPUTS] = { TLV_TYPE_TL16V },
- [NM_ATT_SOURCE] = { TLV_TYPE_TL16V },
- [NM_ATT_SPEC_PROB] = { TLV_TYPE_TV },
- [NM_ATT_START_TIME] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_T200] = { TLV_TYPE_FIXED, 7 },
- [NM_ATT_TEI] = { TLV_TYPE_TV },
- [NM_ATT_TEST_DUR] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_TEST_NO] = { TLV_TYPE_TV },
- [NM_ATT_TEST_REPORT] = { TLV_TYPE_TL16V },
- [NM_ATT_VSWR_THRESH] = { TLV_TYPE_FIXED, 2 },
- [NM_ATT_WINDOW_SIZE] = { TLV_TYPE_TV },
- [NM_ATT_TSC] = { TLV_TYPE_TV },
- [NM_ATT_SW_CONFIG] = { TLV_TYPE_TL16V },
- [NM_ATT_SEVERITY] = { TLV_TYPE_TV },
- [NM_ATT_GET_ARI] = { TLV_TYPE_TL16V },
- [NM_ATT_HW_CONF_CHG] = { TLV_TYPE_TL16V },
- [NM_ATT_OUTST_ALARM] = { TLV_TYPE_TV },
- [NM_ATT_MEAS_RES] = { TLV_TYPE_TL16V },
- },
-};
-
-/*! \brief Human-readable strings for A-bis OML Object Class */
-const struct value_string abis_nm_obj_class_names[] = {
- { NM_OC_SITE_MANAGER, "SITE-MANAGER" },
- { NM_OC_BTS, "BTS" },
- { NM_OC_RADIO_CARRIER, "RADIO-CARRIER" },
- { NM_OC_BASEB_TRANSC, "BASEBAND-TRANSCEIVER" },
- { NM_OC_CHANNEL, "CHANNEL" },
- { NM_OC_BS11_ADJC, "ADJC" },
- { NM_OC_BS11_HANDOVER, "HANDOVER" },
- { NM_OC_BS11_PWR_CTRL, "POWER-CONTROL" },
- { NM_OC_BS11_BTSE, "BTSE" },
- { NM_OC_BS11_RACK, "RACK" },
- { NM_OC_BS11_TEST, "TEST" },
- { NM_OC_BS11_ENVABTSE, "ENVABTSE" },
- { NM_OC_BS11_BPORT, "BPORT" },
- { NM_OC_GPRS_NSE, "GPRS-NSE" },
- { NM_OC_GPRS_CELL, "GPRS-CELL" },
- { NM_OC_GPRS_NSVC, "GPRS-NSVC" },
- { NM_OC_BS11, "SIEMENSHW" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable string for OML Operational State */
-const char *abis_nm_opstate_name(uint8_t os)
-{
- switch (os) {
- case NM_OPSTATE_DISABLED:
- return "Disabled";
- case NM_OPSTATE_ENABLED:
- return "Enabled";
- case NM_OPSTATE_NULL:
- return "NULL";
- default:
- return "RFU";
- }
-}
-
-/* Chapter 9.4.7 */
-static const struct value_string avail_names[] = {
- { 0, "In test" },
- { 1, "Failed" },
- { 2, "Power off" },
- { 3, "Off line" },
- /* Not used */
- { 5, "Dependency" },
- { 6, "Degraded" },
- { 7, "Not installed" },
- { 0xff, "OK" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable string for OML Availability State */
-const char *abis_nm_avail_name(uint8_t avail)
-{
- return get_value_string(avail_names, avail);
-}
-
-static struct value_string test_names[] = {
- /* FIXME: standard test names */
- { NM_IPACC_TESTNO_CHAN_USAGE, "Channel Usage" },
- { NM_IPACC_TESTNO_BCCH_CHAN_USAGE, "BCCH Channel Usage" },
- { NM_IPACC_TESTNO_FREQ_SYNC, "Frequency Synchronization" },
- { NM_IPACC_TESTNO_BCCH_INFO, "BCCH Info" },
- { NM_IPACC_TESTNO_TX_BEACON, "Transmit Beacon" },
- { NM_IPACC_TESTNO_SYSINFO_MONITOR, "System Info Monitor" },
- { NM_IPACC_TESTNO_BCCCH_MONITOR, "BCCH Monitor" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable string for OML test */
-const char *abis_nm_test_name(uint8_t test)
-{
- return get_value_string(test_names, test);
-}
-
-/*! \brief Human-readable names for OML administrative state */
-const struct value_string abis_nm_adm_state_names[] = {
- { NM_STATE_LOCKED, "Locked" },
- { NM_STATE_UNLOCKED, "Unlocked" },
- { NM_STATE_SHUTDOWN, "Shutdown" },
- { NM_STATE_NULL, "NULL" },
- { 0, NULL }
-};
-
-/*! \brief write a human-readable OML header to the debug log
- * \param[in] ss Logging sub-system
- * \param[in] foh A-bis OML FOM header
- */
-void abis_nm_debugp_foh(int ss, struct abis_om_fom_hdr *foh)
-{
- DEBUGP(ss, "OC=%s(%02x) INST=(%02x,%02x,%02x) ",
- get_value_string(abis_nm_obj_class_names, foh->obj_class),
- foh->obj_class, foh->obj_inst.bts_nr, foh->obj_inst.trx_nr,
- foh->obj_inst.ts_nr);
-}
-
-static const enum abis_nm_chan_comb chcomb4pchan[] = {
- [GSM_PCHAN_NONE] = 0xff,
- [GSM_PCHAN_CCCH] = NM_CHANC_mainBCCH,
- [GSM_PCHAN_CCCH_SDCCH4] = NM_CHANC_BCCHComb,
- [GSM_PCHAN_TCH_F] = NM_CHANC_TCHFull,
- [GSM_PCHAN_TCH_H] = NM_CHANC_TCHHalf,
- [GSM_PCHAN_SDCCH8_SACCH8C] = NM_CHANC_SDCCH,
- [GSM_PCHAN_PDCH] = NM_CHANC_IPAC_PDCH,
- [GSM_PCHAN_TCH_F_PDCH] = NM_CHANC_IPAC_TCHFull_PDCH,
- [GSM_PCHAN_UNKNOWN] = 0xff,
- /* FIXME: bounds check */
-};
-
-/*! \brief Obtain OML Channel Combination for phnsical channel config */
-int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan)
-{
- if (pchan < ARRAY_SIZE(chcomb4pchan))
- return chcomb4pchan[pchan];
-
- return -EINVAL;
-}
-
-/*! \brief Obtain physical channel config for OML Channel Combination */
-enum abis_nm_chan_comb abis_nm_pchan4chcomb(uint8_t chcomb)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(chcomb4pchan); i++) {
- if (chcomb4pchan[i] == chcomb)
- return i;
- }
- return GSM_PCHAN_NONE;
-}
-
-/*! @} */
diff --git a/src/shared/libosmocore/src/gsm/auth_comp128v1.c b/src/shared/libosmocore/src/gsm/auth_comp128v1.c
deleted file mode 100644
index 41aef71c..00000000
--- a/src/shared/libosmocore/src/gsm/auth_comp128v1.c
+++ /dev/null
@@ -1,47 +0,0 @@
-
-/* GSM/GPRS/3G authentication core infrastructure */
-
-/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/crypt/auth.h>
-#include <osmocom/gsm/comp128.h>
-
-static int c128v1_gen_vec(struct osmo_auth_vector *vec,
- struct osmo_sub_auth_data *aud,
- const uint8_t *_rand)
-{
- comp128(aud->u.gsm.ki, _rand, vec->sres, vec->kc);
- vec->auth_types = OSMO_AUTH_TYPE_GSM;
-
- return 0;
-}
-
-static struct osmo_auth_impl c128v1_alg = {
- .algo = OSMO_AUTH_ALG_COMP128v1,
- .name = "COMP128v1 (libosmogsm built-in)",
- .priority = 1000,
- .gen_vec = &c128v1_gen_vec,
-};
-
-static __attribute__((constructor)) void on_dso_load_c128(void)
-{
- osmo_auth_register(&c128v1_alg);
-}
diff --git a/src/shared/libosmocore/src/gsm/auth_core.c b/src/shared/libosmocore/src/gsm/auth_core.c
deleted file mode 100644
index 5cf8dfcf..00000000
--- a/src/shared/libosmocore/src/gsm/auth_core.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* GSM/GPRS/3G authentication core infrastructure */
-
-/* (C) 2010-2012 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/plugin.h>
-
-#include <osmocom/crypt/auth.h>
-
-/*! \addtogroup auth
- * @{
- */
-
-/* \file auth_core.c
- */
-
-static LLIST_HEAD(osmo_auths);
-
-static struct osmo_auth_impl *selected_auths[_OSMO_AUTH_ALG_NUM];
-
-/*! \brief Register an authentication algorithm implementation with the core
- * \param[in] impl Structure describing implementation and it's callbacks
- *
- * This function is called by an authentication implementation plugin to
- * register itself with the authentication core.
- */
-int osmo_auth_register(struct osmo_auth_impl *impl)
-{
- if (impl->algo >= ARRAY_SIZE(selected_auths))
- return -ERANGE;
-
- llist_add_tail(&impl->list, &osmo_auths);
-
- /* check if we want to select this implementation over others */
- if (!selected_auths[impl->algo] ||
- (selected_auths[impl->algo]->priority > impl->priority))
- selected_auths[impl->algo] = impl;
-
- return 0;
-}
-
-/*! \brief Load all available authentication plugins from the given path
- * \param[in] path Path name of the directory containing the plugins
- *
- * This function will load all plugins contained in the specified path.
- */
-int osmo_auth_load(const char *path)
-{
- /* load all plugins available from path */
- return osmo_plugin_load_all(path);
-}
-
-/*! \brief Determine if a given authentication algorithm is supported
- * \param[in] algo Algorithm which should be checked
- *
- * This function is used by an application to determine at runtime if a
- * given authentication algorithm is supported or not.
- */
-int osmo_auth_supported(enum osmo_auth_algo algo)
-{
- if (algo >= ARRAY_SIZE(selected_auths))
- return -ERANGE;
-
- if (selected_auths[algo])
- return 1;
-
- return 0;
-}
-
-/*! \brief Generate authentication vector
- * \param[out] vec Generated authentication vector
- * \param[in] aud Subscriber-specific key material
- * \param[in] rand Random challenge to be used
- *
- * This function performs the core cryptographic function of the AUC,
- * computing authentication triples/quintuples based on the permanent
- * subscriber data and a random value. The result is what is forwarded
- * by the AUC via HLR and VLR to the MSC which will then be able to
- * invoke authentication with the MS
- */
-int osmo_auth_gen_vec(struct osmo_auth_vector *vec,
- struct osmo_sub_auth_data *aud,
- const uint8_t *_rand)
-{
- struct osmo_auth_impl *impl = selected_auths[aud->algo];
- int rc;
-
- if (!impl)
- return -ENOENT;
-
- rc = impl->gen_vec(vec, aud, _rand);
- if (rc < 0)
- return rc;
-
- memcpy(vec->rand, _rand, sizeof(vec->rand));
-
- return 0;
-}
-
-/*! \brief Generate authentication vector and re-sync sequence
- * \param[out] vec Generated authentication vector
- * \param[in] aud Subscriber-specific key material
- * \param[in] rand_auts RAND value sent by the SIM/MS
- * \param[in] auts AUTS value sent by the SIM/MS
- * \param[in] rand Random challenge to be used to generate vector
- *
- * This function performs a special variant of the core cryptographic
- * function of the AUC: computing authentication triples/quintuples
- * based on the permanent subscriber data, a random value as well as the
- * AUTS and RAND values returned by the SIM/MS. This special variant is
- * needed if the sequence numbers between MS and AUC have for some
- * reason become diffrent.
- */
-int osmo_auth_gen_vec_auts(struct osmo_auth_vector *vec,
- struct osmo_sub_auth_data *aud,
- const uint8_t *rand_auts, const uint8_t *auts,
- const uint8_t *_rand)
-{
- struct osmo_auth_impl *impl = selected_auths[aud->algo];
-
- if (!impl || !impl->gen_vec_auts)
- return -ENOENT;
-
- return impl->gen_vec_auts(vec, aud, rand_auts, auts, _rand);
-}
-
-static const struct value_string auth_alg_vals[] = {
- { OSMO_AUTH_ALG_NONE, "None" },
- { OSMO_AUTH_ALG_COMP128v1, "COMP128v1" },
- { OSMO_AUTH_ALG_COMP128v2, "COMP128v2" },
- { OSMO_AUTH_ALG_COMP128v3, "COMP128v3" },
- { OSMO_AUTH_ALG_XOR, "XOR" },
- { OSMO_AUTH_ALG_MILENAGE, "MILENAGE" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable name of authentication algorithm */
-const char *osmo_auth_alg_name(enum osmo_auth_algo alg)
-{
- return get_value_string(auth_alg_vals, alg);
-}
-
-/*! \brief Parse human-readable name of authentication algorithm */
-enum osmo_auth_algo osmo_auth_alg_parse(const char *name)
-{
- return get_string_value(auth_alg_vals, name);
-}
-
-/*! @} */
diff --git a/src/shared/libosmocore/src/gsm/auth_milenage.c b/src/shared/libosmocore/src/gsm/auth_milenage.c
deleted file mode 100644
index 5b2787dd..00000000
--- a/src/shared/libosmocore/src/gsm/auth_milenage.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* GSM/GPRS/3G authentication core infrastructure */
-
-/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/crypt/auth.h>
-#include "milenage/common.h"
-#include "milenage/milenage.h"
-
-static void sqn_u64_to_48bit(uint8_t *sqn, const uint64_t sqn64)
-{
- sqn[5] = (sqn64 >> 0) & 0xff;
- sqn[4] = (sqn64 >> 8) & 0xff;
- sqn[3] = (sqn64 >> 16) & 0xff;
- sqn[2] = (sqn64 >> 24) & 0xff;
- sqn[1] = (sqn64 >> 32) & 0xff;
- sqn[0] = (sqn64 >> 40) & 0xff;
-}
-
-static uint64_t sqn_48bit_to_u64(const uint8_t *sqn)
-{
- uint64_t sqn64;
-
- sqn64 = sqn[0];
- sqn64 <<= 8;
- sqn64 |= sqn[1];
- sqn64 <<= 8;
- sqn64 |= sqn[2];
- sqn64 <<= 8;
- sqn64 |= sqn[3];
- sqn64 <<= 8;
- sqn64 |= sqn[4];
- sqn64 <<= 8;
- sqn64 |= sqn[5];
-
- return sqn64;
-}
-
-
-static int milenage_gen_vec(struct osmo_auth_vector *vec,
- struct osmo_sub_auth_data *aud,
- const uint8_t *_rand)
-{
- size_t res_len = sizeof(vec->res);
- uint8_t sqn[6];
- int rc;
-
- sqn_u64_to_48bit(sqn, aud->u.umts.sqn);
- milenage_generate(aud->u.umts.opc, aud->u.umts.amf, aud->u.umts.k,
- sqn, _rand,
- vec->autn, vec->ik, vec->ck, vec->res, &res_len);
- vec->res_len = res_len;
- rc = gsm_milenage(aud->u.umts.opc, aud->u.umts.k, _rand, vec->sres, vec->kc);
- if (rc < 0)
- return rc;
-
- vec->auth_types = OSMO_AUTH_TYPE_UMTS | OSMO_AUTH_TYPE_GSM;
- aud->u.umts.sqn++;
-
- return 0;
-}
-
-static int milenage_gen_vec_auts(struct osmo_auth_vector *vec,
- struct osmo_sub_auth_data *aud,
- const uint8_t *auts, const uint8_t *rand_auts,
- const uint8_t *_rand)
-{
- uint8_t sqn_out[6];
- uint8_t gen_opc[16];
- uint8_t *opc;
- int rc;
-
- /* Check if we only know OP and compute OPC if required */
- if (aud->type == OSMO_AUTH_TYPE_UMTS && aud->u.umts.opc_is_op) {
- rc = milenage_opc_gen(gen_opc, aud->u.umts.k,
- aud->u.umts.opc);
- if (rc < 0)
- return rc;
- opc = gen_opc;
- } else
- opc = aud->u.umts.opc;
-
- rc = milenage_auts(opc, aud->u.umts.k, rand_auts, auts, sqn_out);
- if (rc < 0)
- return rc;
-
- aud->u.umts.sqn = sqn_48bit_to_u64(sqn_out) + 1;
-
- return milenage_gen_vec(vec, aud, _rand);
-}
-
-static struct osmo_auth_impl milenage_alg = {
- .algo = OSMO_AUTH_ALG_MILENAGE,
- .name = "MILENAGE (libosmogsm built-in)",
- .priority = 1000,
- .gen_vec = &milenage_gen_vec,
- .gen_vec_auts = &milenage_gen_vec_auts,
-};
-
-static __attribute__((constructor)) void on_dso_load_milenage(void)
-{
- osmo_auth_register(&milenage_alg);
-}
diff --git a/src/shared/libosmocore/src/gsm/comp128.c b/src/shared/libosmocore/src/gsm/comp128.c
deleted file mode 100644
index b7a23820..00000000
--- a/src/shared/libosmocore/src/gsm/comp128.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * COMP128 implementation
- *
- *
- * This code is inspired by original code from :
- * Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>,
- * and David Wagner <daw@cs.berkeley.edu>
- *
- * But it has been fully rewritten from various PDFs found online describing
- * the algorithm because the licence of the code referenced above was unclear.
- * A comment snippet from the original code is included below, it describes
- * where the doc came from and how the algorithm was reverse engineered.
- *
- *
- * (C) 2009 by Sylvain Munaut <tnt@246tNt.com>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/*
- * --- SNIP ---
- *
- * This code derived from a leaked document from the GSM standards.
- * Some missing pieces were filled in by reverse-engineering a working SIM.
- * We have verified that this is the correct COMP128 algorithm.
- *
- * The first page of the document identifies it as
- * _Technical Information: GSM System Security Study_.
- * 10-1617-01, 10th June 1988.
- * The bottom of the title page is marked
- * Racal Research Ltd.
- * Worton Drive, Worton Grange Industrial Estate,
- * Reading, Berks. RG2 0SB, England.
- * Telephone: Reading (0734) 868601 Telex: 847152
- * The relevant bits are in Part I, Section 20 (pages 66--67). Enjoy!
- *
- * Note: There are three typos in the spec (discovered by
- * reverse-engineering).
- * First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read
- * "z = (2 * x[m] + x[n]) mod 2^(9-j)".
- * Second, the "k" loop in the "Form bits from bytes" section is severely
- * botched: the k index should run only from 0 to 3, and clearly the range
- * on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8,
- * to be consistent with the subsequent section).
- * Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as
- * claimed in the document. (And the document doesn't specify how Kc is
- * derived, but that was also easily discovered with reverse engineering.)
- * All of these typos have been corrected in the following code.
- *
- * --- /SNIP ---
- */
-
-#include <string.h>
-#include <stdint.h>
-
-/* The compression tables (just copied ...) */
-static const uint8_t table_0[512] = {
- 102, 177, 186, 162, 2, 156, 112, 75, 55, 25, 8, 12, 251, 193, 246, 188,
- 109, 213, 151, 53, 42, 79, 191, 115, 233, 242, 164, 223, 209, 148, 108, 161,
- 252, 37, 244, 47, 64, 211, 6, 237, 185, 160, 139, 113, 76, 138, 59, 70,
- 67, 26, 13, 157, 63, 179, 221, 30, 214, 36, 166, 69, 152, 124, 207, 116,
- 247, 194, 41, 84, 71, 1, 49, 14, 95, 35, 169, 21, 96, 78, 215, 225,
- 182, 243, 28, 92, 201, 118, 4, 74, 248, 128, 17, 11, 146, 132, 245, 48,
- 149, 90, 120, 39, 87, 230, 106, 232, 175, 19, 126, 190, 202, 141, 137, 176,
- 250, 27, 101, 40, 219, 227, 58, 20, 51, 178, 98, 216, 140, 22, 32, 121,
- 61, 103, 203, 72, 29, 110, 85, 212, 180, 204, 150, 183, 15, 66, 172, 196,
- 56, 197, 158, 0, 100, 45, 153, 7, 144, 222, 163, 167, 60, 135, 210, 231,
- 174, 165, 38, 249, 224, 34, 220, 229, 217, 208, 241, 68, 206, 189, 125, 255,
- 239, 54, 168, 89, 123, 122, 73, 145, 117, 234, 143, 99, 129, 200, 192, 82,
- 104, 170, 136, 235, 93, 81, 205, 173, 236, 94, 105, 52, 46, 228, 198, 5,
- 57, 254, 97, 155, 142, 133, 199, 171, 187, 50, 65, 181, 127, 107, 147, 226,
- 184, 218, 131, 33, 77, 86, 31, 44, 88, 62, 238, 18, 24, 43, 154, 23,
- 80, 159, 134, 111, 9, 114, 3, 91, 16, 130, 83, 10, 195, 240, 253, 119,
- 177, 102, 162, 186, 156, 2, 75, 112, 25, 55, 12, 8, 193, 251, 188, 246,
- 213, 109, 53, 151, 79, 42, 115, 191, 242, 233, 223, 164, 148, 209, 161, 108,
- 37, 252, 47, 244, 211, 64, 237, 6, 160, 185, 113, 139, 138, 76, 70, 59,
- 26, 67, 157, 13, 179, 63, 30, 221, 36, 214, 69, 166, 124, 152, 116, 207,
- 194, 247, 84, 41, 1, 71, 14, 49, 35, 95, 21, 169, 78, 96, 225, 215,
- 243, 182, 92, 28, 118, 201, 74, 4, 128, 248, 11, 17, 132, 146, 48, 245,
- 90, 149, 39, 120, 230, 87, 232, 106, 19, 175, 190, 126, 141, 202, 176, 137,
- 27, 250, 40, 101, 227, 219, 20, 58, 178, 51, 216, 98, 22, 140, 121, 32,
- 103, 61, 72, 203, 110, 29, 212, 85, 204, 180, 183, 150, 66, 15, 196, 172,
- 197, 56, 0, 158, 45, 100, 7, 153, 222, 144, 167, 163, 135, 60, 231, 210,
- 165, 174, 249, 38, 34, 224, 229, 220, 208, 217, 68, 241, 189, 206, 255, 125,
- 54, 239, 89, 168, 122, 123, 145, 73, 234, 117, 99, 143, 200, 129, 82, 192,
- 170, 104, 235, 136, 81, 93, 173, 205, 94, 236, 52, 105, 228, 46, 5, 198,
- 254, 57, 155, 97, 133, 142, 171, 199, 50, 187, 181, 65, 107, 127, 226, 147,
- 218, 184, 33, 131, 86, 77, 44, 31, 62, 88, 18, 238, 43, 24, 23, 154,
- 159, 80, 111, 134, 114, 9, 91, 3, 130, 16, 10, 83, 240, 195, 119, 253,
-}, table_1[256] = {
- 19, 11, 80, 114, 43, 1, 69, 94, 39, 18, 127, 117, 97, 3, 85, 43,
- 27, 124, 70, 83, 47, 71, 63, 10, 47, 89, 79, 4, 14, 59, 11, 5,
- 35, 107, 103, 68, 21, 86, 36, 91, 85, 126, 32, 50, 109, 94, 120, 6,
- 53, 79, 28, 45, 99, 95, 41, 34, 88, 68, 93, 55, 110, 125, 105, 20,
- 90, 80, 76, 96, 23, 60, 89, 64, 121, 56, 14, 74, 101, 8, 19, 78,
- 76, 66, 104, 46, 111, 50, 32, 3, 39, 0, 58, 25, 92, 22, 18, 51,
- 57, 65, 119, 116, 22, 109, 7, 86, 59, 93, 62, 110, 78, 99, 77, 67,
- 12, 113, 87, 98, 102, 5, 88, 33, 38, 56, 23, 8, 75, 45, 13, 75,
- 95, 63, 28, 49, 123, 120, 20, 112, 44, 30, 15, 98, 106, 2, 103, 29,
- 82, 107, 42, 124, 24, 30, 41, 16, 108, 100, 117, 40, 73, 40, 7, 114,
- 82, 115, 36, 112, 12, 102, 100, 84, 92, 48, 72, 97, 9, 54, 55, 74,
- 113, 123, 17, 26, 53, 58, 4, 9, 69, 122, 21, 118, 42, 60, 27, 73,
- 118, 125, 34, 15, 65, 115, 84, 64, 62, 81, 70, 1, 24, 111, 121, 83,
- 104, 81, 49, 127, 48, 105, 31, 10, 6, 91, 87, 37, 16, 54, 116, 126,
- 31, 38, 13, 0, 72, 106, 77, 61, 26, 67, 46, 29, 96, 37, 61, 52,
- 101, 17, 44, 108, 71, 52, 66, 57, 33, 51, 25, 90, 2, 119, 122, 35,
-}, table_2[128] = {
- 52, 50, 44, 6, 21, 49, 41, 59, 39, 51, 25, 32, 51, 47, 52, 43,
- 37, 4, 40, 34, 61, 12, 28, 4, 58, 23, 8, 15, 12, 22, 9, 18,
- 55, 10, 33, 35, 50, 1, 43, 3, 57, 13, 62, 14, 7, 42, 44, 59,
- 62, 57, 27, 6, 8, 31, 26, 54, 41, 22, 45, 20, 39, 3, 16, 56,
- 48, 2, 21, 28, 36, 42, 60, 33, 34, 18, 0, 11, 24, 10, 17, 61,
- 29, 14, 45, 26, 55, 46, 11, 17, 54, 46, 9, 24, 30, 60, 32, 0,
- 20, 38, 2, 30, 58, 35, 1, 16, 56, 40, 23, 48, 13, 19, 19, 27,
- 31, 53, 47, 38, 63, 15, 49, 5, 37, 53, 25, 36, 63, 29, 5, 7,
-}, table_3[64] = {
- 1, 5, 29, 6, 25, 1, 18, 23, 17, 19, 0, 9, 24, 25, 6, 31,
- 28, 20, 24, 30, 4, 27, 3, 13, 15, 16, 14, 18, 4, 3, 8, 9,
- 20, 0, 12, 26, 21, 8, 28, 2, 29, 2, 15, 7, 11, 22, 14, 10,
- 17, 21, 12, 30, 26, 27, 16, 31, 11, 7, 13, 23, 10, 5, 22, 19,
-}, table_4[32] = {
- 15, 12, 10, 4, 1, 14, 11, 7, 5, 0, 14, 7, 1, 2, 13, 8,
- 10, 3, 4, 9, 6, 0, 3, 2, 5, 6, 8, 9, 11, 13, 15, 12,
-};
-
-static const uint8_t *_comp128_table[5] = { table_0, table_1, table_2, table_3, table_4 };
-
-
-static inline void
-_comp128_compression_round(uint8_t *x, int n, const uint8_t *tbl)
-{
- int i, j, m, a, b, y, z;
- m = 4 - n;
- for (i=0; i<(1<<n); i++)
- for (j=0; j<(1<<m); j++) {
- a = j + i * (2<<m);
- b = a + (1<<m);
- y = (x[a] + (x[b]<<1)) & ((32<<m)-1);
- z = ((x[a]<<1) + x[b]) & ((32<<m)-1);
- x[a] = tbl[y];
- x[b] = tbl[z];
- }
-}
-
-static inline void
-_comp128_compression(uint8_t *x)
-{
- int n;
- for (n=0; n<5; n++)
- _comp128_compression_round(x, n, _comp128_table[n]);
-}
-
-static inline void
-_comp128_bitsfrombytes(uint8_t *x, uint8_t *bits)
-{
- int i;
- memset(bits, 0x00, 128);
- for (i=0; i<128; i++)
- if (x[i>>2] & (1<<(3-(i&3))))
- bits[i] = 1;
-}
-
-static inline void
-_comp128_permutation(uint8_t *x, uint8_t *bits)
-{
- int i;
- memset(&x[16], 0x00, 16);
- for (i=0; i<128; i++)
- x[(i>>3)+16] |= bits[(i*17) & 127] << (7-(i&7));
-}
-
-void
-comp128(const uint8_t *ki, const uint8_t *rand, uint8_t *sres, uint8_t *kc)
-{
- int i;
- uint8_t x[32], bits[128];
-
- /* x[16-31] = RAND */
- memcpy(&x[16], rand, 16);
-
- /* Round 1-7 */
- for (i=0; i<7; i++) {
- /* x[0-15] = Ki */
- memcpy(x, ki, 16);
-
- /* Compression */
- _comp128_compression(x);
-
- /* FormBitFromBytes */
- _comp128_bitsfrombytes(x, bits);
-
- /* Permutation */
- _comp128_permutation(x, bits);
- }
-
- /* Round 8 (final) */
- /* x[0-15] = Ki */
- memcpy(x, ki, 16);
-
- /* Compression */
- _comp128_compression(x);
-
- /* Output stage */
- for (i=0; i<8; i+=2)
- sres[i>>1] = x[i]<<4 | x[i+1];
-
- for (i=0; i<12; i+=2)
- kc[i>>1] = (x[i + 18] << 6) |
- (x[i + 19] << 2) |
- (x[i + 20] >> 2);
-
- kc[6] = (x[30]<<6) | (x[31]<<2);
- kc[7] = 0;
-}
-
diff --git a/src/shared/libosmocore/src/gsm/gan.c b/src/shared/libosmocore/src/gsm/gan.c
deleted file mode 100644
index e041936e..00000000
--- a/src/shared/libosmocore/src/gsm/gan.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* (C) 2012 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <unistd.h>
-#include <osmocom/core/utils.h>
-
-#include <osmocom/gsm/protocol/gsm_44_318.h>
-
-
-const struct value_string gan_msgt_vals[] = {
- { GA_MT_RC_DISCOVERY_REQUEST, "GA-RC DISCOVERY REQUEST" },
- { GA_MT_RC_DISCOVERY_ACCEPT, "GA-RC DISCOVERY ACCEPT" },
- { GA_MT_RC_DISCOVERY_REJECT, "GA-RC DISCOVERY REJECT" },
- { GA_MT_RC_REGISTER_REQUEST, "GA-RC REGISTER REQUEST" },
- { GA_MT_RC_REGISTER_ACCEPT, "GA-RC REGISTER ACCEPT" },
- { GA_MT_RC_REGISTER_REDIRECT, "GA-RC REGISTER REDIRECT" },
- { GA_MT_RC_REGISTER_REJECT, "GA-RC REGISTER REJECT" },
- { GA_MT_RC_DEREGISTER, "GA-RC DEREGISTER" },
- { GA_MT_RC_REGISTER_UPDATE_UL, "GA-RC REGISTER UPDATE UL" },
- { GA_MT_RC_REGISTER_UPDATE_DL, "GA-RC REGISTER UPDATE DL" },
- { GA_MT_RC_CELL_BCAST_INFO, "GA-RC CELL BROADCAST INFO" },
- { GA_MT_CSR_CIPH_MODE_CMD, "GA-CSR CIPHER MDOE COMMAND" },
- { GA_MT_CSR_CIPH_MODE_COMPL, "GA-CSR CIPHER MODE COMPLETE" },
- { GA_MT_CSR_ACT_CHAN, "GA-CSR ACTIVATE CHANNEL" },
- { GA_MT_CSR_ACT_CHAN_ACK, "GA-CSR ACTIVATE CHANNEL ACK" },
- { GA_MT_CSR_ACT_CHAN_COMPL, "GA-CSR ACTIVATE CHANNEL COMPLETE" },
- { GA_MT_CSR_ACT_CHAN_FAIL, "GA-CSR ACTIVATE CHANNEL FAIL" },
- { GA_MT_CSR_CHAN_MODE_MOD, "GA-CSR CHANNEL MODE MODIFY" },
- { GA_MT_CSR_CHAN_MODE_MOD_ACK, "GA-CSR CHANNEL MODE MODIFY ACK" },
- { GA_MT_CSR_RELEASE, "GA-CSR RELEASE" },
- { GA_MT_CSR_RELEASE_COMPL, "GA-CSR RELEASE COMPLETE" },
- { GA_MT_CSR_CLEAR_REQ, "GA-CSR CLEAR REQUEST" },
- { GA_MT_CSR_HO_ACCESS, "GA-CSR HANDOVER ACCESS" },
- { GA_MT_CSR_HO_COMPL, "GA-CSR HANDOVER COMPLETE" },
- { GA_MT_CSR_UL_QUAL_IND, "GA-CSR UL QUALITY INDICATION" },
- { GA_MT_CSR_HO_INFO, "GA-CSR HANDOVER INFO" },
- { GA_MT_CSR_HO_CMD, "GA-CSR HANDOVER COMMAND" },
- { GA_MT_CSR_HO_FAIL, "GA-CSR HANDOVER FAILURE" },
- { GA_MT_CSR_PAGING_REQ, "GA-CSR PAGING REQUEST" },
- { GA_MT_CSR_PAGING_RESP, "GA-CSR PAGING RESPONSE" },
- { GA_MT_CSR_UL_DIRECT_XFER, "GA-CSR UL DIRECT TRANSFER" },
- { GA_MT_CSR_DL_DIRECT_XFER, "GA-CSR DL DIRECT TRANSFER" },
- { GA_MT_CSR_STATUS, "GA-CSR STATUS" },
- { GA_MT_RC_KEEPALIVE, "GA-CSR KEEPALIVE" },
- { GA_MT_CSR_CM_ENQ, "GA-CSR CLASSMARK ENQUIRY" },
- { GA_MT_CSR_CM_CHANGE, "GA-CSR CLASSMARK CHANGE" },
- { GA_MT_PSR_GPRS_SUSPEND_REQ, "GA-PSR GPRS SUSPEND REQUEST" },
- { GA_RC_SYNC_INFO, "GA-RC SYNCH INFORMATION" },
- { GA_CSR_UTRAN_CM_CHG, "GA-CSR UTRAN CLASSMARK CHANGE" },
- { GA_MT_CSR_REQUEST, "GA-CSR REQUEST" },
- { GA_MT_CSR_REQUEST_ACCEPT, "GA-CSR REQUEST ACCEPT" },
- { GA_MT_CSR_REQUEST_REJECT, "GA-CSR REQUEST REJECT" },
- { 0, NULL }
-};
-
-static const struct value_string gan_pdisc_vals[] = {
- { GA_PDISC_RC, "RC" },
- { GA_PDISC_CSR, "CSR" },
- { GA_PDISC_PSR, "PSR" },
- { 0, NULL }
-};
-
diff --git a/src/shared/libosmocore/src/gsm/gprs_cipher_core.c b/src/shared/libosmocore/src/gsm/gprs_cipher_core.c
deleted file mode 100644
index b9a22a10..00000000
--- a/src/shared/libosmocore/src/gsm/gprs_cipher_core.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/* GPRS LLC cipher core infrastructure */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <errno.h>
-#include <stdint.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/plugin.h>
-
-#include <osmocom/crypt/gprs_cipher.h>
-
-static LLIST_HEAD(gprs_ciphers);
-
-static struct gprs_cipher_impl *selected_ciphers[_GPRS_ALGO_NUM];
-
-/* register a cipher with the core */
-int gprs_cipher_register(struct gprs_cipher_impl *ciph)
-{
- if (ciph->algo >= ARRAY_SIZE(selected_ciphers))
- return -ERANGE;
-
- llist_add_tail(&ciph->list, &gprs_ciphers);
-
- /* check if we want to select this implementation over others */
- if (!selected_ciphers[ciph->algo] ||
- (selected_ciphers[ciph->algo]->priority > ciph->priority))
- selected_ciphers[ciph->algo] = ciph;
-
- return 0;
-}
-
-/* load all available GPRS cipher plugins */
-int gprs_cipher_load(const char *path)
-{
- /* load all plugins available from path */
- return osmo_plugin_load_all(path);
-}
-
-/* function to be called by core code */
-int gprs_cipher_run(uint8_t *out, uint16_t len, enum gprs_ciph_algo algo,
- uint64_t kc, uint32_t iv, enum gprs_cipher_direction dir)
-{
- if (algo >= ARRAY_SIZE(selected_ciphers))
- return -ERANGE;
-
- if (!selected_ciphers[algo])
- return -EINVAL;
-
- if (len > GSM0464_CIPH_MAX_BLOCK)
- return -ERANGE;
-
- /* run the actual cipher from the plugin */
- return selected_ciphers[algo]->run(out, len, kc, iv, dir);
-}
-
-int gprs_cipher_supported(enum gprs_ciph_algo algo)
-{
- if (algo >= ARRAY_SIZE(selected_ciphers))
- return -ERANGE;
-
- if (selected_ciphers[algo])
- return 1;
-
- return 0;
-}
-
-/* GSM TS 04.64 / Section A.2.1 : Generation of 'input' */
-uint32_t gprs_cipher_gen_input_ui(uint32_t iov_ui, uint8_t sapi, uint32_t lfn, uint32_t oc)
-{
- uint32_t sx = ((1<<27) * sapi) + (1<<31);
-
- return (iov_ui ^ sx) + lfn + oc;
-}
-
-/* GSM TS 04.64 / Section A.2.1 : Generation of 'input' */
-uint32_t gprs_cipher_gen_input_i(uint32_t iov_i, uint32_t lfn, uint32_t oc)
-{
- return iov_i + lfn + oc;
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm0411_smc.c b/src/shared/libosmocore/src/gsm/gsm0411_smc.c
deleted file mode 100644
index 4152ef1c..00000000
--- a/src/shared/libosmocore/src/gsm/gsm0411_smc.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/* Point-to-Point (PP) Short Message Service (SMS)
- * Support on Mobile Radio Interface
- * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
-
-/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
- * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* Notes on msg:
- *
- * Messages from lower layer are freed by lower layer.
- *
- * Messages to upper layer are freed after upper layer call returns, so upper
- * layer cannot use data after returning. Upper layer must not free the msg.
- *
- * This implies: Lower layer messages can be forwarded to upper layer.
- *
- * Upper layer messages are freed by lower layer, so they must not be freed
- * after calling lower layer.
- *
- *
- * Notes on release:
- *
- * Whenever the process returns to IDLE, the MM connection is released using
- * MMSMS-REL-REQ. It is allowed to destroy this process while processing
- * this message.
- *
- * There is expeption, if MMSMS-REL-IND is received from lower layer, the
- * process returns to IDLE without sending MMSMS-REL-REQ.
- *
- */
-
-#include <string.h>
-#include <errno.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-
-#include <osmocom/gsm/gsm0411_utils.h>
-#include <osmocom/gsm/gsm0411_smc.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-static void cp_timer_expired(void *data);
-
-#define MAX_SMS_RETRY 2
-
-/* init a new instance */
-void gsm411_smc_init(struct gsm411_smc_inst *inst, int network,
- int (*mn_recv) (struct gsm411_smc_inst *inst, int msg_type,
- struct msgb *msg),
- int (*mm_send) (struct gsm411_smc_inst *inst, int msg_type,
- struct msgb *msg, int cp_msg_type))
-{
- memset(inst, 0, sizeof(*inst));
- inst->network = network;
- inst->cp_max_retr = MAX_SMS_RETRY;
- inst->cp_tc1 = GSM411_TMR_TC1A_SEC / (inst->cp_max_retr + 1);
- inst->cp_state = GSM411_CPS_IDLE;
- inst->mn_recv = mn_recv;
- inst->mm_send = mm_send;
-
- LOGP(DLSMS, LOGL_INFO, "New SMC instance created\n");
-}
-
-/* clear instance */
-void gsm411_smc_clear(struct gsm411_smc_inst *inst)
-{
- LOGP(DLSMS, LOGL_INFO, "Clear SMC instance\n");
-
- osmo_timer_del(&inst->cp_timer);
-
- /* free stored msg */
- if (inst->cp_msg) {
- LOGP(DLSMS, LOGL_INFO, "Dropping pending message\n");
- msgb_free(inst->cp_msg);
- inst->cp_msg = NULL;
- }
-}
-
-const char *smc_state_names[] = {
- "IDLE",
- "MM_CONN_PENDING",
- "WAIT_CP_ACK",
- "MM_ESTABLISHED",
-};
-
-const struct value_string gsm411_cp_cause_strs[] = {
- { GSM411_CP_CAUSE_NET_FAIL, "Network Failure" },
- { GSM411_CP_CAUSE_CONGESTION, "Congestion" },
- { GSM411_CP_CAUSE_INV_TRANS_ID, "Invalid Transaction ID" },
- { GSM411_CP_CAUSE_SEMANT_INC_MSG, "Semantically Incorrect Message" },
- { GSM411_CP_CAUSE_INV_MAND_INF, "Invalid Mandatory Information" },
- { GSM411_CP_CAUSE_MSGTYPE_NOTEXIST, "Message Type doesn't exist" },
- { GSM411_CP_CAUSE_MSG_INCOMP_STATE,
- "Message incompatible with protocol state" },
- { GSM411_CP_CAUSE_IE_NOTEXIST, "IE does not exist" },
- { GSM411_CP_CAUSE_PROTOCOL_ERR, "Protocol Error" },
- { 0, 0 }
-};
-
-static void new_cp_state(struct gsm411_smc_inst *inst,
- enum gsm411_cp_state state)
-{
- LOGP(DLSMS, LOGL_INFO, "New CP state %s -> %s\n",
- smc_state_names[inst->cp_state], smc_state_names[state]);
- inst->cp_state = state;
-}
-
-static int gsm411_tx_cp_error(struct gsm411_smc_inst *inst, uint8_t cause)
-{
- struct msgb *nmsg = gsm411_msgb_alloc();
- uint8_t *causep;
-
- LOGP(DLSMS, LOGL_NOTICE, "TX CP-ERROR, cause %d (%s)\n", cause,
- get_value_string(gsm411_cp_cause_strs, cause));
-
- causep = msgb_put(nmsg, 1);
- *causep = cause;
-
- return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg,
- GSM411_MT_CP_ERROR);
-}
-
-/* establish SMC connection */
-static int gsm411_mnsms_est_req(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- if (inst->cp_msg) {
- LOGP(DLSMS, LOGL_FATAL, "EST REQ, but we already have an "
- "cp_msg. This should never happen, please fix!\n");
- msgb_free(inst->cp_msg);
- }
-
- inst->cp_msg = msg;
- new_cp_state(inst, GSM411_CPS_MM_CONN_PENDING);
- /* clear stored release flag */
- inst->cp_rel = 0;
- /* send MMSMS_EST_REQ */
- nmsg = gsm411_msgb_alloc();
- return inst->mm_send(inst, GSM411_MMSMS_EST_REQ, nmsg, 0);
-}
-
-static int gsm411_mmsms_send_msg(struct gsm411_smc_inst *inst)
-{
- struct msgb *nmsg;
-
- LOGP(DLSMS, LOGL_INFO, "Send CP data\n");
- /* reset retry counter */
- if (inst->cp_state != GSM411_CPS_WAIT_CP_ACK)
- inst->cp_retx = 0;
- /* 5.2.3.1.2: enter MO-wait for CP-ACK */
- /* 5.2.3.2.3: enter MT-wait for CP-ACK */
- new_cp_state(inst, GSM411_CPS_WAIT_CP_ACK);
- inst->cp_timer.data = inst;
- inst->cp_timer.cb = cp_timer_expired;
- /* 5.3.2.1: Set Timer TC1A */
- osmo_timer_schedule(&inst->cp_timer, inst->cp_tc1, 0);
- /* clone cp_msg */
- nmsg = gsm411_msgb_alloc();
- memcpy(msgb_put(nmsg, inst->cp_msg->len), inst->cp_msg->data,
- inst->cp_msg->len);
- /* send MMSMS_DATA_REQ with CP-DATA */
- return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg,
- GSM411_MT_CP_DATA);
-}
-
-static int gsm411_mmsms_est_cnf(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- if (!inst->cp_msg) {
- LOGP(DLSMS, LOGL_FATAL, "EST CNF, but we have no cp_msg. This "
- "should never happen, please fix!\n");
- return -EINVAL;
- }
-
- return gsm411_mmsms_send_msg(inst);
-}
-
-/* SMC TC1* is expired */
-static void cp_timer_expired(void *data)
-{
- struct gsm411_smc_inst *inst = data;
- struct msgb *nmsg;
-
- if (inst->cp_retx == inst->cp_max_retr) {
-
- LOGP(DLSMS, LOGL_INFO, "TC1* timeout, no more retries.\n");
- /* 5.3.2.1: enter idle state */
- new_cp_state(inst, GSM411_CPS_IDLE);
- /* indicate error */
- nmsg = gsm411_msgb_alloc();
- inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
- msgb_free(nmsg);
- /* free pending stored msg */
- if (inst->cp_msg) {
- msgb_free(inst->cp_msg);
- inst->cp_msg = NULL;
- }
- /* release MM connection */
- nmsg = gsm411_msgb_alloc();
- inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
- return;
- }
-
- LOGP(DLSMS, LOGL_INFO, "TC1* timeout, retrying...\n");
- inst->cp_retx++;
- gsm411_mmsms_est_cnf(inst, NULL);
-}
-
-static int gsm411_mmsms_cp_ack(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- /* free stored msg */
- if (inst->cp_msg) {
- msgb_free(inst->cp_msg);
- inst->cp_msg = NULL;
- }
-
- LOGP(DLSMS, LOGL_INFO, "Received CP-ACK\n");
- /* 5.3.2.1 enter MM Connection established */
- new_cp_state(inst, GSM411_CPS_MM_ESTABLISHED);
- /* 5.3.2.1: Reset Timer TC1* */
- osmo_timer_del(&inst->cp_timer);
-
- /* pending release? */
- if (inst->cp_rel) {
- struct msgb *nmsg;
-
- LOGP(DLSMS, LOGL_INFO, "We have pending release.\n");
- new_cp_state(inst, GSM411_CPS_IDLE);
- /* release MM connection */
- nmsg = gsm411_msgb_alloc();
- return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
- }
-
- return 0;
-}
-
-static int gsm411_mmsms_cp_data(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- struct msgb *nmsg;
- int mt = GSM411_MNSMS_DATA_IND;
-
- LOGP(DLSMS, LOGL_INFO, "Received CP-DATA\n");
- /* 5.3.1 enter MM Connection established (if idle) */
- if (inst->cp_state == GSM411_CPS_IDLE) {
- new_cp_state(inst, GSM411_CPS_MM_ESTABLISHED);
- mt = GSM411_MNSMS_EST_IND;
- /* clear stored release flag */
- inst->cp_rel = 0;
- }
- /* send MMSMS_DATA_REQ (CP ACK) */
- nmsg = gsm411_msgb_alloc();
- inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg, GSM411_MT_CP_ACK);
- /* indicate data */
- inst->mn_recv(inst, mt, msg);
-
- return 0;
-}
-
-/* send CP DATA */
-static int gsm411_mnsms_data_req(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- if (inst->cp_msg) {
- LOGP(DLSMS, LOGL_FATAL, "DATA REQ, but we already have an "
- "cp_msg. This should never happen, please fix!\n");
- msgb_free(inst->cp_msg);
- }
-
- /* store and send */
- inst->cp_msg = msg;
- return gsm411_mmsms_send_msg(inst);
-}
-
-/* release SMC connection */
-static int gsm411_mnsms_rel_req(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- msgb_free(msg);
-
- /* discard silently */
- if (inst->cp_state == GSM411_CPS_IDLE)
- return 0;
-
- /* store release, until established or released */
- if (inst->cp_state != GSM411_CPS_MM_ESTABLISHED) {
- LOGP(DLSMS, LOGL_NOTICE,
- "Cannot release yet current state: %s\n",
- smc_state_names[inst->cp_state]);
- inst->cp_rel = 1;
- return 0;
- }
-
- /* free stored msg */
- if (inst->cp_msg) {
- msgb_free(inst->cp_msg);
- inst->cp_msg = NULL;
- }
-
- new_cp_state(inst, GSM411_CPS_IDLE);
- /* release MM connection */
- nmsg = gsm411_msgb_alloc();
- return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
-}
-
-static int gsm411_mmsms_cp_error(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- /* free stored msg */
- if (inst->cp_msg) {
- msgb_free(inst->cp_msg);
- inst->cp_msg = NULL;
- }
-
- LOGP(DLSMS, LOGL_INFO, "Received CP-ERROR\n");
- /* 5.3.4 enter idle */
- new_cp_state(inst, GSM411_CPS_IDLE);
- /* indicate error */
- inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, msg);
- /* release MM connection */
- nmsg = gsm411_msgb_alloc();
- return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
-}
-
-static int gsm411_mmsms_rel_ind(struct gsm411_smc_inst *inst, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- /* free stored msg */
- if (inst->cp_msg) {
- msgb_free(inst->cp_msg);
- inst->cp_msg = NULL;
- }
-
- LOGP(DLSMS, LOGL_INFO, "MM layer is released\n");
- /* 5.3.4 enter idle */
- new_cp_state(inst, GSM411_CPS_IDLE);
- /* indicate error */
- nmsg = gsm411_msgb_alloc();
- inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
- msgb_free(nmsg);
-
- return 0;
-}
-
-/* abort SMC connection */
-static int gsm411_mnsms_abort_req(struct gsm411_smc_inst *inst,
- struct msgb *msg)
-{
- struct msgb *nmsg;
-
- /* free stored msg */
- if (inst->cp_msg) {
- msgb_free(inst->cp_msg);
- inst->cp_msg = NULL;
- }
-
- /* 5.3.4 go idle */
- new_cp_state(inst, GSM411_CPS_IDLE);
- /* send MMSMS_DATA_REQ with CP-ERROR */
- inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, msg, GSM411_MT_CP_ERROR);
- /* release MM connection */
- nmsg = gsm411_msgb_alloc();
- return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
-}
-
-/* statefull handling for MNSMS SAP messages */
-static struct smcdownstate {
- uint32_t states;
- int type;
- const char *name;
- int (*rout) (struct gsm411_smc_inst *inst,
- struct msgb *msg);
-} smcdownstatelist[] = {
- /* establish request */
- {SBIT(GSM411_CPS_IDLE),
- GSM411_MNSMS_EST_REQ,
- "MNSMS-EST-REQ", gsm411_mnsms_est_req},
-
- /* release request */
- {ALL_STATES,
- GSM411_MNSMS_REL_REQ,
- "MNSMS-REL-REQ", gsm411_mnsms_rel_req},
-
- /* data request */
- {SBIT(GSM411_CPS_MM_ESTABLISHED),
- GSM411_MNSMS_DATA_REQ,
- "MNSMS-DATA-REQ", gsm411_mnsms_data_req},
-
- /* abort request */
- {ALL_STATES - SBIT(GSM411_CPS_IDLE),
- GSM411_MNSMS_ABORT_REQ,
- "MNSMS-ABORT-REQ", gsm411_mnsms_abort_req},
-};
-
-#define SMCDOWNSLLEN \
- (sizeof(smcdownstatelist) / sizeof(struct smcdownstate))
-
-/* message from upper layer */
-int gsm411_smc_send(struct gsm411_smc_inst *inst, int msg_type,
- struct msgb *msg)
-{
- int i, rc;
-
- /* find function for current state and message */
- for (i = 0; i < SMCDOWNSLLEN; i++) {
- if ((msg_type == smcdownstatelist[i].type)
- && (SBIT(inst->cp_state) & smcdownstatelist[i].states))
- break;
- }
- if (i == SMCDOWNSLLEN) {
- LOGP(DLSMS, LOGL_NOTICE, "Message %u unhandled at this state "
- "%s.\n", msg_type, smc_state_names[inst->cp_state]);
- msgb_free(msg);
- return 0;
- }
-
- LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
- smcdownstatelist[i].name, smc_state_names[inst->cp_state]);
-
- rc = smcdownstatelist[i].rout(inst, msg);
-
- return rc;
-}
-
-/* statefull handling for MMSMS SAP messages */
-static struct smcdatastate {
- uint32_t states;
- int type, cp_type;
- const char *name;
- int (*rout) (struct gsm411_smc_inst *inst,
- struct msgb *msg);
-} smcdatastatelist[] = {
- /* establish confirm */
- {SBIT(GSM411_CPS_MM_CONN_PENDING),
- GSM411_MMSMS_EST_CNF, 0,
- "MMSMS-EST-CNF", gsm411_mmsms_est_cnf},
-
- /* establish indication (CP DATA) */
- {SBIT(GSM411_CPS_IDLE),
- GSM411_MMSMS_EST_IND, GSM411_MT_CP_DATA,
- "MMSMS-EST-IND (CP DATA)", gsm411_mmsms_cp_data},
-
- /* data indication (CP DATA) */
- {SBIT(GSM411_CPS_MM_ESTABLISHED),
- GSM411_MMSMS_DATA_IND, GSM411_MT_CP_DATA,
- "MMSMS-DATA-IND (CP DATA)", gsm411_mmsms_cp_data},
-
- /* data indication (CP ACK) */
- {SBIT(GSM411_CPS_WAIT_CP_ACK),
- GSM411_MMSMS_DATA_IND, GSM411_MT_CP_ACK,
- "MMSMS-DATA-IND (CP ACK)", gsm411_mmsms_cp_ack},
-
- /* data indication (CP ERROR) */
- {ALL_STATES,
- GSM411_MMSMS_DATA_IND, GSM411_MT_CP_ERROR,
- "MMSMS-DATA-IND (CP_ERROR)", gsm411_mmsms_cp_error},
-
- /* release indication */
- {ALL_STATES - SBIT(GSM411_CPS_IDLE),
- GSM411_MMSMS_REL_IND, 0,
- "MMSMS-REL-IND", gsm411_mmsms_rel_ind},
-
-};
-
-#define SMCDATASLLEN \
- (sizeof(smcdatastatelist) / sizeof(struct smcdatastate))
-
-/* message from lower layer
- * WARNING: We must not free msg, since it will be performed by the
- * lower layer. */
-int gsm411_smc_recv(struct gsm411_smc_inst *inst, int msg_type,
- struct msgb *msg, int cp_msg_type)
-{
- int i, rc;
-
- /* find function for current state and message */
- for (i = 0; i < SMCDATASLLEN; i++) {
- /* state must machtch, MM message must match
- * CP msg must match only in case of MMSMS_DATA_IND
- */
- if ((msg_type == smcdatastatelist[i].type)
- && (SBIT(inst->cp_state) & smcdatastatelist[i].states)
- && (msg_type != GSM411_MMSMS_DATA_IND
- || cp_msg_type == smcdatastatelist[i].cp_type))
- break;
- }
- if (i == SMCDATASLLEN) {
- LOGP(DLSMS, LOGL_NOTICE, "Message 0x%x/%u unhandled at this "
- "state %s.\n", msg_type, cp_msg_type,
- smc_state_names[inst->cp_state]);
- if (msg_type == GSM411_MMSMS_EST_IND
- || msg_type == GSM411_MMSMS_DATA_IND) {
- struct msgb *nmsg;
-
- LOGP(DLSMS, LOGL_NOTICE, "RX Unimplemented CP "
- "msg_type: 0x%02x\n", msg_type);
- /* 5.3.4 enter idle */
- new_cp_state(inst, GSM411_CPS_IDLE);
- /* indicate error */
- gsm411_tx_cp_error(inst,
- GSM411_CP_CAUSE_MSGTYPE_NOTEXIST);
- /* send error indication to upper layer */
- nmsg = gsm411_msgb_alloc();
- inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
- msgb_free(nmsg);
- /* release MM connection */
- nmsg = gsm411_msgb_alloc();
- return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg,
- 0);
- }
- return 0;
- }
-
- LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
- smcdatastatelist[i].name, smc_state_names[inst->cp_state]);
-
- rc = smcdatastatelist[i].rout(inst, msg);
-
- return rc;
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm0411_smr.c b/src/shared/libosmocore/src/gsm/gsm0411_smr.c
deleted file mode 100644
index 7dd8f723..00000000
--- a/src/shared/libosmocore/src/gsm/gsm0411_smr.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/* Point-to-Point (PP) Short Message Service (SMS)
- * Support on Mobile Radio Interface
- * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
-
-/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
- * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-/* Notes on msg:
- *
- * Messages from lower layer are freed by lower layer.
- *
- * Messages to upper layer are freed after upper layer call returns, so upper
- * layer cannot use data after returning. Upper layer must not free the msg.
- *
- * This implies: Lower layer messages can be forwarded to upper layer.
- *
- * Upper layer messages are freed by lower layer, so they must not be freed
- * after calling lower layer.
- *
- *
- * Notes on release:
- *
- * Sending Abort/Release (MNSMS-ABORT-REQ or MNSMS-REL-REQ) may cause the
- * lower layer to become IDLE. Then it is allowed to destroy this instance,
- * so sending this this MUST be the last thing that is done.
- *
- */
-
-
-#include <string.h>
-#include <errno.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/gsm/tlv.h>
-
-#include <osmocom/gsm/gsm0411_utils.h>
-#include <osmocom/gsm/gsm0411_smc.h>
-#include <osmocom/gsm/gsm0411_smr.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-static void rp_timer_expired(void *data);
-
-/* init a new instance */
-void gsm411_smr_init(struct gsm411_smr_inst *inst, int network,
- int (*rl_recv) (struct gsm411_smr_inst *inst, int msg_type,
- struct msgb *msg),
- int (*mn_send) (struct gsm411_smr_inst *inst, int msg_type,
- struct msgb *msg))
-{
- memset(inst, 0, sizeof(*inst));
- inst->network = network;
- inst->rp_state = GSM411_RPS_IDLE;
- inst->rl_recv = rl_recv;
- inst->mn_send = mn_send;
- inst->rp_timer.data = inst;
- inst->rp_timer.cb = rp_timer_expired;
-
- LOGP(DLSMS, LOGL_INFO, "New SMR instance created\n");
-}
-
-/* clear instance */
-void gsm411_smr_clear(struct gsm411_smr_inst *inst)
-{
- LOGP(DLSMS, LOGL_INFO, "Clear SMR instance\n");
-
- osmo_timer_del(&inst->rp_timer);
-}
-
-const char *smr_state_names[] = {
- "IDLE",
- "WAIT_FOR_RP_ACK",
- "illegal state 2"
- "WAIT_TO_TX_RP_ACK",
- "WAIT_FOR_RETRANS_T",
-};
-
-const struct value_string gsm411_rp_cause_strs[] = {
- { GSM411_RP_CAUSE_MO_NUM_UNASSIGNED, "(MO) Number not assigned" },
- { GSM411_RP_CAUSE_MO_OP_DET_BARR, "(MO) Operator determined barring" },
- { GSM411_RP_CAUSE_MO_CALL_BARRED, "(MO) Call barred" },
- { GSM411_RP_CAUSE_MO_SMS_REJECTED, "(MO) SMS rejected" },
- { GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER, "(MO) Destination out of order" },
- { GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR, "(MO) Unidentified subscriber" },
- { GSM411_RP_CAUSE_MO_FACILITY_REJ, "(MO) Facility reject" },
- { GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR, "(MO) Unknown subscriber" },
- { GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER, "(MO) Network out of order" },
- { GSM411_RP_CAUSE_MO_TEMP_FAIL, "(MO) Temporary failure" },
- { GSM411_RP_CAUSE_MO_CONGESTION, "(MO) Congestion" },
- { GSM411_RP_CAUSE_MO_RES_UNAVAIL, "(MO) Resource unavailable" },
- { GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR, "(MO) Requested facility not subscribed" },
- { GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL, "(MO) Requested facility not implemented" },
- { GSM411_RP_CAUSE_MO_INTERWORKING, "(MO) Interworking" },
- /* valid only for MT */
- { GSM411_RP_CAUSE_MT_MEM_EXCEEDED, "(MT) Memory Exceeded" },
- /* valid for both directions */
- { GSM411_RP_CAUSE_INV_TRANS_REF, "Invalid Transaction Reference" },
- { GSM411_RP_CAUSE_SEMANT_INC_MSG, "Semantically Incorrect Message" },
- { GSM411_RP_CAUSE_INV_MAND_INF, "Invalid Mandatory Information" },
- { GSM411_RP_CAUSE_MSGTYPE_NOTEXIST, "Message Type non-existant" },
- { GSM411_RP_CAUSE_MSG_INCOMP_STATE, "Message incompatible with protocol state" },
- { GSM411_RP_CAUSE_IE_NOTEXIST, "Information Element not existing" },
- { GSM411_RP_CAUSE_PROTOCOL_ERR, "Protocol Error" },
- { 0, NULL }
-};
-
-static void new_rp_state(struct gsm411_smr_inst *inst,
- enum gsm411_rp_state state)
-{
- LOGP(DLSMS, LOGL_INFO, "New RP state %s -> %s\n",
- smr_state_names[inst->rp_state], smr_state_names[state]);
- inst->rp_state = state;
-
- /* stop timer when going idle */
- if (state == GSM411_RPS_IDLE)
- osmo_timer_del(&inst->rp_timer);
-}
-
-/* Prefix msg with a RP-DATA header and send as CP-DATA */
-static int gsm411_rp_sendmsg(struct gsm411_smr_inst *inst, struct msgb *msg,
- uint8_t rp_msg_type, uint8_t rp_msg_ref,
- int mnsms_msg_type)
-{
- struct gsm411_rp_hdr *rp;
- uint8_t len = msg->len;
-
- /* GSM 04.11 RP-DATA header */
- rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
- rp->len = len + 2;
- rp->msg_type = rp_msg_type;
- rp->msg_ref = rp_msg_ref; /* FIXME: Choose randomly */
-
- return inst->mn_send(inst, mnsms_msg_type, msg);
-}
-
-static int gsm411_send_rp_error(struct gsm411_smr_inst *inst,
- uint8_t msg_ref, uint8_t cause)
-{
- struct msgb *msg = gsm411_msgb_alloc();
-
- msgb_tv_put(msg, 1, cause);
-
- LOGP(DLSMS, LOGL_NOTICE, "TX: SMS RP ERROR, cause %d (%s)\n", cause,
- get_value_string(gsm411_rp_cause_strs, cause));
-
- return gsm411_rp_sendmsg(inst, msg,
- (inst->network) ? GSM411_MT_RP_ERROR_MT : GSM411_MT_RP_ERROR_MO,
- msg_ref, GSM411_MNSMS_DATA_REQ);
-}
-
-static int gsm411_send_release(struct gsm411_smr_inst *inst)
-{
- struct msgb *msg = gsm411_msgb_alloc();
-
- LOGP(DLSMS, LOGL_DEBUG, "TX: MNSMS-REL-REQ\n");
-
- return inst->mn_send(inst, GSM411_MNSMS_REL_REQ, msg);
-}
-
-static int gsm411_send_abort(struct gsm411_smr_inst *inst)
-{
- struct msgb *msg = gsm411_msgb_alloc();
-
- msgb_tv_put(msg, 1, 111); //FIXME: better idea ? */
- LOGP(DLSMS, LOGL_DEBUG, "TX: MNSMS-ABORT-REQ\n");
-
- return inst->mn_send(inst, GSM411_MNSMS_ABORT_REQ, msg);
-}
-
-static int gsm411_send_report(struct gsm411_smr_inst *inst)
-{
- struct msgb *msg = gsm411_msgb_alloc();
-
- LOGP(DLSMS, LOGL_DEBUG, "Sending empty SM_RL_REPORT_IND\n");
-
- return inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
-}
-
-static int gsm411_rl_data_req(struct gsm411_smr_inst *inst, struct msgb *msg)
-{
- LOGP(DLSMS, LOGL_DEBUG, "TX SMS RP-DATA\n");
- /* start TR1N and enter 'wait for RP-ACK state' */
- osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR1M);
- new_rp_state(inst, GSM411_RPS_WAIT_FOR_RP_ACK);
-
- return inst->mn_send(inst, GSM411_MNSMS_EST_REQ, msg);
-}
-
-static int gsm411_rl_report_req(struct gsm411_smr_inst *inst, struct msgb *msg)
-{
- LOGP(DLSMS, LOGL_DEBUG, "TX SMS REPORT\n");
- new_rp_state(inst, GSM411_RPS_IDLE);
-
- inst->mn_send(inst, GSM411_MNSMS_DATA_REQ, msg);
- gsm411_send_release(inst);
- return 0;
-}
-
-static int gsm411_mnsms_est_ind(struct gsm411_smr_inst *inst, struct msgb *msg)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr*)msg->l3h;
- struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
- uint8_t msg_type = rp_data->msg_type & 0x07;
- int rc;
-
- /* check direction */
- if (inst->network == (msg_type & 1)) {
- LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
- gsm411_send_rp_error(inst, rp_data->msg_ref,
- GSM411_RP_CAUSE_MSG_INCOMP_STATE);
- new_rp_state(inst, GSM411_RPS_IDLE);
- gsm411_send_release(inst);
- return -EINVAL;
- }
-
- switch (msg_type) {
- case GSM411_MT_RP_DATA_MT:
- case GSM411_MT_RP_DATA_MO:
- LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-DATA\n");
- /* start TR2N and enter 'wait to send RP-ACK state' */
- osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M);
- new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK);
- rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg);
- break;
- case GSM411_MT_RP_SMMA_MO:
- LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-SMMA\n");
- /* start TR2N and enter 'wait to send RP-ACK state' */
- osmo_timer_schedule(&inst->rp_timer, GSM411_TMR_TR2M);
- new_rp_state(inst, GSM411_RPS_WAIT_TO_TX_RP_ACK);
- rc = inst->rl_recv(inst, GSM411_SM_RL_DATA_IND, msg);
- break;
- default:
- LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
- gsm411_send_rp_error(inst, rp_data->msg_ref,
- GSM411_RP_CAUSE_MSGTYPE_NOTEXIST);
- new_rp_state(inst, GSM411_RPS_IDLE);
- rc = -EINVAL;
- break;
- }
-
- return rc;
-}
-
-static int gsm411_mnsms_data_ind_tx(struct gsm411_smr_inst *inst,
- struct msgb *msg)
-{
- struct gsm48_hdr *gh = (struct gsm48_hdr*)msg->l3h;
- struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
- uint8_t msg_type = rp_data->msg_type & 0x07;
- int rc;
-
- /* check direction */
- if (inst->network == (msg_type & 1)) {
- LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
- gsm411_send_rp_error(inst, rp_data->msg_ref,
- GSM411_RP_CAUSE_MSG_INCOMP_STATE);
- new_rp_state(inst, GSM411_RPS_IDLE);
- gsm411_send_release(inst);
- return -EINVAL;
- }
-
- switch (msg_type) {
- case GSM411_MT_RP_ACK_MO:
- case GSM411_MT_RP_ACK_MT:
- LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-ACK\n");
- new_rp_state(inst, GSM411_RPS_IDLE);
- inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
- gsm411_send_release(inst);
- return 0;
- case GSM411_MT_RP_ERROR_MO:
- case GSM411_MT_RP_ERROR_MT:
- LOGP(DLSMS, LOGL_DEBUG, "RX SMS RP-ERROR\n");
- new_rp_state(inst, GSM411_RPS_IDLE);
- inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
- gsm411_send_release(inst);
- return 0;
- default:
- LOGP(DLSMS, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
- gsm411_send_rp_error(inst, rp_data->msg_ref,
- GSM411_RP_CAUSE_MSGTYPE_NOTEXIST);
- new_rp_state(inst, GSM411_RPS_IDLE);
- gsm411_send_release(inst);
- return -EINVAL;
- }
-
- return rc;
-}
-
-static int gsm411_mnsms_error_ind_tx(struct gsm411_smr_inst *inst,
- struct msgb *msg)
-{
- LOGP(DLSMS, LOGL_DEBUG, "RX SMS MNSMS-ERROR-IND\n");
- new_rp_state(inst, GSM411_RPS_IDLE);
- inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
- gsm411_send_release(inst);
- return 0;
-}
-
-static int gsm411_mnsms_error_ind_rx(struct gsm411_smr_inst *inst,
- struct msgb *msg)
-{
- LOGP(DLSMS, LOGL_DEBUG, "RX SMS MNSMS-ERROR-IND\n");
- new_rp_state(inst, GSM411_RPS_IDLE);
- return inst->rl_recv(inst, GSM411_SM_RL_REPORT_IND, msg);
-}
-
-/* SMR TR1* is expired */
-static void rp_timer_expired(void *data)
-{
- struct gsm411_smr_inst *inst = data;
-
- if (inst->rp_state == GSM411_RPS_WAIT_TO_TX_RP_ACK)
- LOGP(DLSMS, LOGL_DEBUG, "TR2N\n");
- else
- LOGP(DLSMS, LOGL_DEBUG, "TR1N\n");
- gsm411_send_report(inst);
- gsm411_send_abort(inst);
-}
-
-/* statefull handling for SM-RL SAP messages */
-static struct smrdownstate {
- uint32_t states;
- int type;
- const char *name;
- int (*rout) (struct gsm411_smr_inst *inst,
- struct msgb *msg);
-} smrdownstatelist[] = {
- /* data request */
- {SBIT(GSM411_RPS_IDLE),
- GSM411_SM_RL_DATA_REQ,
- "SM-RL-DATA_REQ", gsm411_rl_data_req},
-
- /* report request */
- {SBIT(GSM411_RPS_WAIT_TO_TX_RP_ACK),
- GSM411_SM_RL_REPORT_REQ,
- "SM-RL-REPORT_REQ", gsm411_rl_report_req},
-};
-
-#define SMRDOWNSLLEN \
- (sizeof(smrdownstatelist) / sizeof(struct smrdownstate))
-
-/* message from upper layer */
-int gsm411_smr_send(struct gsm411_smr_inst *inst, int msg_type,
- struct msgb *msg)
-{
- int i, rc;
-
- /* find function for current state and message */
- for (i = 0; i < SMRDOWNSLLEN; i++) {
- if ((msg_type == smrdownstatelist[i].type)
- && (SBIT(inst->rp_state) & smrdownstatelist[i].states))
- break;
- }
- if (i == SMRDOWNSLLEN) {
- LOGP(DLSMS, LOGL_NOTICE, "Message %u unhandled at this state "
- "%s.\n", msg_type, smr_state_names[inst->rp_state]);
- msgb_free(msg);
- return 0;
- }
-
- LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
- smrdownstatelist[i].name, smr_state_names[inst->rp_state]);
-
- rc = smrdownstatelist[i].rout(inst, msg);
-
- return rc;
-}
-
-/* statefull handling for MMSMS SAP messages */
-static struct smrdatastate {
- uint32_t states;
- int type;
- const char *name;
- int (*rout) (struct gsm411_smr_inst *inst,
- struct msgb *msg);
-} smrdatastatelist[] = {
- /* establish indication */
- {SBIT(GSM411_RPS_IDLE),
- GSM411_MNSMS_EST_IND,
- "MNSMS-EST-IND", gsm411_mnsms_est_ind},
-
- /* data indication */
- {SBIT(GSM411_RPS_WAIT_FOR_RP_ACK),
- GSM411_MNSMS_DATA_IND,
- "MNSMS-DATA-IND", gsm411_mnsms_data_ind_tx},
-
- /* error indication */
- {SBIT(GSM411_RPS_WAIT_FOR_RP_ACK),
- GSM411_MNSMS_ERROR_IND,
- "MNSMS-ERROR-IND", gsm411_mnsms_error_ind_tx},
-
- /* error indication */
- {SBIT(GSM411_RPS_WAIT_TO_TX_RP_ACK),
- GSM411_MNSMS_ERROR_IND,
- "MNSMS-ERROR-IND", gsm411_mnsms_error_ind_rx},
-
-};
-
-#define SMRDATASLLEN \
- (sizeof(smrdatastatelist) / sizeof(struct smrdatastate))
-
-/* message from lower layer
- * WARNING: We must not free msg, since it will be performed by the
- * lower layer. */
-int gsm411_smr_recv(struct gsm411_smr_inst *inst, int msg_type,
- struct msgb *msg)
-{
- int i, rc;
-
- /* find function for current state and message */
- for (i = 0; i < SMRDATASLLEN; i++) {
- /* state must machtch, MM message must match
- * CP msg must match only in case of MMSMS_DATA_IND
- */
- if ((msg_type == smrdatastatelist[i].type)
- && (SBIT(inst->rp_state) & smrdatastatelist[i].states))
- break;
- }
- if (i == SMRDATASLLEN) {
- LOGP(DLSMS, LOGL_NOTICE, "Message %u unhandled at this state "
- "%s.\n", msg_type, smr_state_names[inst->rp_state]);
- return 0;
- }
-
- LOGP(DLSMS, LOGL_INFO, "Message %s received in state %s\n",
- smrdatastatelist[i].name, smr_state_names[inst->rp_state]);
-
- rc = smrdatastatelist[i].rout(inst, msg);
-
- return rc;
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm0411_utils.c b/src/shared/libosmocore/src/gsm/gsm0411_utils.c
deleted file mode 100644
index fe69bf41..00000000
--- a/src/shared/libosmocore/src/gsm/gsm0411_utils.c
+++ /dev/null
@@ -1,314 +0,0 @@
-/* Point-to-Point (PP) Short Message Service (SMS)
- * Support on Mobile Radio Interface
- * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */
-
-/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by On-Waves
- * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "../../config.h"
-
-#include <time.h>
-#include <string.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/logging.h>
-
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/gsm/protocol/gsm_04_11.h>
-
-#define GSM411_ALLOC_SIZE 1024
-#define GSM411_ALLOC_HEADROOM 128
-
-struct msgb *gsm411_msgb_alloc(void)
-{
- return msgb_alloc_headroom(GSM411_ALLOC_SIZE, GSM411_ALLOC_HEADROOM,
- "GSM 04.11");
-}
-
-/* Turn int into semi-octet representation: 98 => 0x89 */
-uint8_t gsm411_bcdify(uint8_t value)
-{
- uint8_t ret;
-
- ret = value / 10;
- ret |= (value % 10) << 4;
-
- return ret;
-}
-
-/* Turn semi-octet representation into int: 0x89 => 98 */
-uint8_t gsm411_unbcdify(uint8_t value)
-{
- uint8_t ret;
-
- if ((value & 0x0F) > 9 || (value >> 4) > 9)
- LOGP(DLSMS, LOGL_ERROR,
- "gsm411_unbcdify got too big nibble: 0x%02X\n", value);
-
- ret = (value&0x0F)*10;
- ret += value>>4;
-
- return ret;
-}
-
-/* Generate 03.40 TP-SCTS */
-void gsm340_gen_scts(uint8_t *scts, time_t time)
-{
- struct tm *tm = gmtime(&time);
-
- *scts++ = gsm411_bcdify(tm->tm_year % 100);
- *scts++ = gsm411_bcdify(tm->tm_mon + 1);
- *scts++ = gsm411_bcdify(tm->tm_mday);
- *scts++ = gsm411_bcdify(tm->tm_hour);
- *scts++ = gsm411_bcdify(tm->tm_min);
- *scts++ = gsm411_bcdify(tm->tm_sec);
-#ifdef HAVE_TM_GMTOFF_IN_TM
- *scts++ = gsm411_bcdify(tm->tm_gmtoff/(60*15));
-#else
-#warning find a portable way to obtain timezone offset
- *scts++ = 0;
-#endif
-}
-
-/* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */
-time_t gsm340_scts(uint8_t *scts)
-{
- struct tm tm;
- uint8_t yr = gsm411_unbcdify(*scts++);
- int ofs;
-
- memset(&tm, 0x00, sizeof(struct tm));
-
- if (yr <= 80)
- tm.tm_year = 100 + yr;
- else
- tm.tm_year = yr;
- tm.tm_mon = gsm411_unbcdify(*scts++) - 1;
- tm.tm_mday = gsm411_unbcdify(*scts++);
- tm.tm_hour = gsm411_unbcdify(*scts++);
- tm.tm_min = gsm411_unbcdify(*scts++);
- tm.tm_sec = gsm411_unbcdify(*scts++);
-#ifdef HAVE_TM_GMTOFF_IN_TM
- tm.tm_gmtoff = gsm411_unbcdify(*scts++) * 15*60;
-#endif
-
- /* according to gsm 03.40 time zone is
- "expressed in quarters of an hour" */
- ofs = gsm411_unbcdify(*scts++) * 15*60;
-
- return mktime(&tm) - ofs;
-}
-
-/* Return the default validity period in minutes */
-static unsigned long gsm340_vp_default(void)
-{
- unsigned long minutes;
- /* Default validity: two days */
- minutes = 24 * 60 * 2;
- return minutes;
-}
-
-/* Decode validity period format 'relative' */
-static unsigned long gsm340_vp_relative(uint8_t *sms_vp)
-{
- /* Chapter 9.2.3.12.1 */
- uint8_t vp;
- unsigned long minutes;
-
- vp = *(sms_vp);
- if (vp <= 143)
- minutes = vp + 1 * 5;
- else if (vp <= 167)
- minutes = 12*60 + (vp-143) * 30;
- else if (vp <= 196)
- minutes = vp-166 * 60 * 24;
- else
- minutes = vp-192 * 60 * 24 * 7;
- return minutes;
-}
-
-/* Decode validity period format 'absolute' */
-static unsigned long gsm340_vp_absolute(uint8_t *sms_vp)
-{
- /* Chapter 9.2.3.12.2 */
- time_t expires, now;
- unsigned long minutes;
-
- expires = gsm340_scts(sms_vp);
- now = time(NULL);
- if (expires <= now)
- minutes = 0;
- else
- minutes = (expires-now)/60;
- return minutes;
-}
-
-/* Decode validity period format 'relative in integer representation' */
-static unsigned long gsm340_vp_relative_integer(uint8_t *sms_vp)
-{
- uint8_t vp;
- unsigned long minutes;
- vp = *(sms_vp);
- if (vp == 0) {
- LOGP(DLSMS, LOGL_ERROR,
- "reserved relative_integer validity period\n");
- return gsm340_vp_default();
- }
- minutes = vp/60;
- return minutes;
-}
-
-/* Decode validity period format 'relative in semi-octet representation' */
-static unsigned long gsm340_vp_relative_semioctet(uint8_t *sms_vp)
-{
- unsigned long minutes;
- minutes = gsm411_unbcdify(*sms_vp++)*60; /* hours */
- minutes += gsm411_unbcdify(*sms_vp++); /* minutes */
- minutes += gsm411_unbcdify(*sms_vp++)/60; /* seconds */
- return minutes;
-}
-
-/* decode validity period. return minutes */
-unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp)
-{
- uint8_t fi; /* functionality indicator */
-
- switch (sms_vpf) {
- case GSM340_TP_VPF_RELATIVE:
- return gsm340_vp_relative(sms_vp);
- case GSM340_TP_VPF_ABSOLUTE:
- return gsm340_vp_absolute(sms_vp);
- case GSM340_TP_VPF_ENHANCED:
- /* Chapter 9.2.3.12.3 */
- fi = *sms_vp++;
- /* ignore additional fi */
- if (fi & (1<<7)) sms_vp++;
- /* read validity period format */
- switch (fi & 0x7) {
- case 0x0:
- return gsm340_vp_default(); /* no vpf specified */
- case 0x1:
- return gsm340_vp_relative(sms_vp);
- case 0x2:
- return gsm340_vp_relative_integer(sms_vp);
- case 0x3:
- return gsm340_vp_relative_semioctet(sms_vp);
- default:
- /* The GSM spec says that the SC should reject any
- unsupported and/or undefined values. FIXME */
- LOGP(DLSMS, LOGL_ERROR,
- "Reserved enhanced validity period format\n");
- return gsm340_vp_default();
- }
- case GSM340_TP_VPF_NONE:
- default:
- return gsm340_vp_default();
- }
-}
-
-/* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
-enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs)
-{
- uint8_t cgbits = dcs >> 4;
- enum sms_alphabet alpha = DCS_NONE;
-
- if ((cgbits & 0xc) == 0) {
- if (cgbits & 2) {
- LOGP(DLSMS, LOGL_NOTICE,
- "Compressed SMS not supported yet\n");
- return 0xffffffff;
- }
-
- switch ((dcs >> 2)&0x03) {
- case 0:
- alpha = DCS_7BIT_DEFAULT;
- break;
- case 1:
- alpha = DCS_8BIT_DATA;
- break;
- case 2:
- alpha = DCS_UCS2;
- break;
- }
- } else if (cgbits == 0xc || cgbits == 0xd)
- alpha = DCS_7BIT_DEFAULT;
- else if (cgbits == 0xe)
- alpha = DCS_UCS2;
- else if (cgbits == 0xf) {
- if (dcs & 4)
- alpha = DCS_8BIT_DATA;
- else
- alpha = DCS_7BIT_DEFAULT;
- }
-
- return alpha;
-}
-
-/* generate a TPDU address field compliant with 03.40 sec. 9.1.2.5 */
-int gsm340_gen_oa(uint8_t *oa, unsigned int oa_len, uint8_t type,
- uint8_t plan, const char *number)
-{
- int len_in_bytes;
-
- /* prevent buffer overflows */
- if (strlen(number) > 20)
- number = "";
-
- oa[1] = 0x80 | (type << 4) | plan;
-
- len_in_bytes = gsm48_encode_bcd_number(oa, oa_len, 1, number);
-
- /* GSM 03.40 tells us the length is in 'useful semi-octets' */
- oa[0] = strlen(number) & 0xff;
-
- return len_in_bytes;
-}
-
-/* Prefix msg with a RP header */
-int gsm411_push_rp_header(struct msgb *msg, uint8_t rp_msg_type,
- uint8_t rp_msg_ref)
-{
- struct gsm411_rp_hdr *rp;
- uint8_t len = msg->len;
-
- /* GSM 04.11 RP-DATA header */
- rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
- rp->len = len + 2;
- rp->msg_type = rp_msg_type;
- rp->msg_ref = rp_msg_ref; /* FIXME: Choose randomly */
-
- return 0;
-}
-
-/* Prefix msg with a 04.08/04.11 CP header */
-int gsm411_push_cp_header(struct msgb *msg, uint8_t proto, uint8_t trans,
- uint8_t msg_type)
-{
- struct gsm48_hdr *gh;
-
- gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
- /* Outgoing needs the highest bit set */
- gh->proto_discr = proto | (trans << 4);
- gh->msg_type = msg_type;
-
- return 0;
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm0480.c b/src/shared/libosmocore/src/gsm/gsm0480.c
deleted file mode 100644
index b9b3ed97..00000000
--- a/src/shared/libosmocore/src/gsm/gsm0480.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/* Format functions for GSM 04.80 */
-
-/*
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by Mike Haben <michael.haben@btinternet.com>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/gsm/gsm0480.h>
-#include <osmocom/gsm/gsm_utils.h>
-
-#include <osmocom/core/logging.h>
-
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_04_80.h>
-
-#include <string.h>
-
-static inline unsigned char *msgb_wrap_with_TL(struct msgb *msgb, uint8_t tag)
-{
- uint8_t *data = msgb_push(msgb, 2);
-
- data[0] = tag;
- data[1] = msgb->len - 2;
- return data;
-}
-
-static inline unsigned char *msgb_push_TLV1(struct msgb *msgb, uint8_t tag,
- uint8_t value)
-{
- uint8_t *data = msgb_push(msgb, 3);
-
- data[0] = tag;
- data[1] = 1;
- data[2] = value;
- return data;
-}
-
-/* wrap an invoke around it... the other way around
- *
- * 1.) Invoke Component tag
- * 2.) Invoke ID Tag
- * 3.) Operation
- * 4.) Data
- */
-int gsm0480_wrap_invoke(struct msgb *msg, int op, int link_id)
-{
- /* 3. operation */
- msgb_push_TLV1(msg, GSM0480_OPERATION_CODE, op);
-
- /* 2. invoke id tag */
- msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, link_id);
-
- /* 1. component tag */
- msgb_wrap_with_TL(msg, GSM0480_CTYPE_INVOKE);
-
- return 0;
-}
-
-/* wrap the GSM 04.08 Facility IE around it */
-int gsm0480_wrap_facility(struct msgb *msg)
-{
- msgb_wrap_with_TL(msg, GSM0480_IE_FACILITY);
-
- return 0;
-}
-
-struct msgb *gsm0480_create_unstructuredSS_Notify(int alertPattern, const char *text)
-{
- struct msgb *msg;
- uint8_t *seq_len_ptr, *ussd_len_ptr, *data;
- int len;
-
- msg = msgb_alloc_headroom(1024, 128, "GSM 04.80");
- if (!msg)
- return NULL;
-
- /* SEQUENCE { */
- msgb_put_u8(msg, GSM_0480_SEQUENCE_TAG);
- seq_len_ptr = msgb_put(msg, 1);
-
- /* DCS { */
- msgb_put_u8(msg, ASN1_OCTET_STRING_TAG);
- msgb_put_u8(msg, 1);
- msgb_put_u8(msg, 0x0F);
- /* } DCS */
-
- /* USSD-String { */
- msgb_put_u8(msg, ASN1_OCTET_STRING_TAG);
- ussd_len_ptr = msgb_put(msg, 1);
- data = msgb_put(msg, 0);
- len = gsm_7bit_encode(data, text);
- msgb_put(msg, len);
- ussd_len_ptr[0] = len;
- /* USSD-String } */
-
- /* alertingPattern { */
- msgb_put_u8(msg, ASN1_OCTET_STRING_TAG);
- msgb_put_u8(msg, 1);
- msgb_put_u8(msg, alertPattern);
- /* } alertingPattern */
-
- seq_len_ptr[0] = 3 + 2 + ussd_len_ptr[0] + 3;
- /* } SEQUENCE */
-
- return msg;
-}
-
-struct msgb *gsm0480_create_notifySS(const char *text)
-{
- struct msgb *msg;
- uint8_t *data, *tmp_len;
- uint8_t *seq_len_ptr, *cal_len_ptr, *opt_len_ptr, *nam_len_ptr;
- int len;
-
- len = strlen(text);
- if (len < 1 || len > 160)
- return NULL;
-
- msg = msgb_alloc_headroom(1024, 128, "GSM 04.80");
- if (!msg)
- return NULL;
-
- msgb_put_u8(msg, GSM_0480_SEQUENCE_TAG);
- seq_len_ptr = msgb_put(msg, 1);
-
- /* ss_code for CNAP { */
- msgb_put_u8(msg, 0x81);
- msgb_put_u8(msg, 1);
- msgb_put_u8(msg, 0x19);
- /* } ss_code */
-
-
- /* nameIndicator { */
- msgb_put_u8(msg, 0xB4);
- nam_len_ptr = msgb_put(msg, 1);
-
- /* callingName { */
- msgb_put_u8(msg, 0xA0);
- opt_len_ptr = msgb_put(msg, 1);
- msgb_put_u8(msg, 0xA0);
- cal_len_ptr = msgb_put(msg, 1);
-
- /* namePresentationAllowed { */
- /* add the DCS value */
- msgb_put_u8(msg, 0x80);
- msgb_put_u8(msg, 1);
- msgb_put_u8(msg, 0x0F);
-
- /* add the lengthInCharacters */
- msgb_put_u8(msg, 0x81);
- msgb_put_u8(msg, 1);
- msgb_put_u8(msg, strlen(text));
-
- /* add the actual string */
- msgb_put_u8(msg, 0x82);
- tmp_len = msgb_put(msg, 1);
- data = msgb_put(msg, 0);
- len = gsm_7bit_encode(data, text);
- tmp_len[0] = len;
- msgb_put(msg, len);
-
- /* }; namePresentationAllowed */
-
- cal_len_ptr[0] = 3 + 3 + 2 + len;
- opt_len_ptr[0] = cal_len_ptr[0] + 2;
- /* }; callingName */
-
- nam_len_ptr[0] = opt_len_ptr[0] + 2;
- /* ); nameIndicator */
-
- /* write the lengths... */
- seq_len_ptr[0] = 3 + nam_len_ptr[0] + 2;
-
- return msg;
-}
-
-/* Forward declarations */
-static int parse_ussd(const struct gsm48_hdr *hdr,
- uint16_t len, struct ussd_request *req);
-static int parse_ussd_info_elements(const uint8_t *ussd_ie, uint16_t len,
- struct ussd_request *req);
-static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length,
- struct ussd_request *req);
-static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length,
- struct ussd_request *req);
-static int parse_process_uss_req(const uint8_t *uss_req_data, uint16_t length,
- struct ussd_request *req);
-
-/* Decode a mobile-originated USSD-request message */
-int gsm0480_decode_ussd_request(const struct gsm48_hdr *hdr, uint16_t len,
- struct ussd_request *req)
-{
- int rc = 0;
-
- if (len < sizeof(*hdr) + 2) {
- LOGP(0, LOGL_DEBUG, "USSD Request is too short.\n");
- return 0;
- }
-
- if ((hdr->proto_discr & 0x0f) == GSM48_PDISC_NC_SS) {
- req->transaction_id = hdr->proto_discr & 0x70;
- rc = parse_ussd(hdr, len, req);
- }
-
- if (!rc)
- LOGP(0, LOGL_DEBUG, "Error occurred while parsing received USSD!\n");
-
- return rc;
-}
-
-static int parse_ussd(const struct gsm48_hdr *hdr, uint16_t len, struct ussd_request *req)
-{
- int rc = 1;
- uint8_t msg_type = hdr->msg_type & 0xBF; /* message-type - section 3.4 */
-
- switch (msg_type) {
- case GSM0480_MTYPE_RELEASE_COMPLETE:
- LOGP(0, LOGL_DEBUG, "USS Release Complete\n");
- /* could also parse out the optional Cause/Facility data */
- req->text[0] = 0xFF;
- break;
- case GSM0480_MTYPE_REGISTER:
- case GSM0480_MTYPE_FACILITY:
- rc &= parse_ussd_info_elements(&hdr->data[0], len - sizeof(*hdr), req);
- break;
- default:
- LOGP(0, LOGL_DEBUG, "Unknown GSM 04.80 message-type field 0x%02x\n",
- hdr->msg_type);
- rc = 0;
- break;
- }
-
- return rc;
-}
-
-static int parse_ussd_info_elements(const uint8_t *ussd_ie, uint16_t len,
- struct ussd_request *req)
-{
- int rc = -1;
- /* Information Element Identifier - table 3.2 & GSM 04.08 section 10.5 */
- uint8_t iei;
- uint8_t iei_length;
-
- iei = ussd_ie[0];
- iei_length = ussd_ie[1];
-
- /* If the data does not fit, report an error */
- if (len - 2 < iei_length)
- return 0;
-
- switch (iei) {
- case GSM48_IE_CAUSE:
- break;
- case GSM0480_IE_FACILITY:
- rc = parse_facility_ie(ussd_ie+2, iei_length, req);
- break;
- case GSM0480_IE_SS_VERSION:
- break;
- default:
- LOGP(0, LOGL_DEBUG, "Unhandled GSM 04.08 or 04.80 IEI 0x%02x\n",
- iei);
- rc = 0;
- break;
- }
-
- return rc;
-}
-
-static int parse_facility_ie(const uint8_t *facility_ie, uint16_t length,
- struct ussd_request *req)
-{
- int rc = 1;
- uint8_t offset = 0;
-
- while (offset + 2 <= length) {
- /* Component Type tag - table 3.7 */
- uint8_t component_type = facility_ie[offset];
- uint8_t component_length = facility_ie[offset+1];
-
- /* size check */
- if (offset + 2 + component_length > length) {
- LOGP(0, LOGL_ERROR, "Component does not fit.\n");
- return 0;
- }
-
- switch (component_type) {
- case GSM0480_CTYPE_INVOKE:
- rc &= parse_ss_invoke(facility_ie+2,
- component_length,
- req);
- break;
- case GSM0480_CTYPE_RETURN_RESULT:
- break;
- case GSM0480_CTYPE_RETURN_ERROR:
- break;
- case GSM0480_CTYPE_REJECT:
- break;
- default:
- LOGP(0, LOGL_DEBUG, "Unknown GSM 04.80 Facility "
- "Component Type 0x%02x\n", component_type);
- rc = 0;
- break;
- }
- offset += (component_length+2);
- };
-
- return rc;
-}
-
-/* Parse an Invoke component - see table 3.3 */
-static int parse_ss_invoke(const uint8_t *invoke_data, uint16_t length,
- struct ussd_request *req)
-{
- int rc = 1;
- uint8_t offset;
-
- if (length < 3)
- return 0;
-
- /* mandatory part */
- if (invoke_data[0] != GSM0480_COMPIDTAG_INVOKE_ID) {
- LOGP(0, LOGL_DEBUG, "Unexpected GSM 04.80 Component-ID tag "
- "0x%02x (expecting Invoke ID tag)\n", invoke_data[0]);
- }
-
- offset = invoke_data[1] + 2;
- req->invoke_id = invoke_data[2];
-
- /* look ahead once */
- if (offset + 1 > length)
- return 0;
-
- /* optional part */
- if (invoke_data[offset] == GSM0480_COMPIDTAG_LINKED_ID)
- offset += invoke_data[offset+1] + 2; /* skip over it */
-
- /* mandatory part */
- if (invoke_data[offset] == GSM0480_OPERATION_CODE) {
- if (offset + 2 > length)
- return 0;
- uint8_t operation_code = invoke_data[offset+2];
- switch (operation_code) {
- case GSM0480_OP_CODE_PROCESS_USS_REQ:
- rc = parse_process_uss_req(invoke_data + offset + 3,
- length - offset - 3,
- req);
- break;
- default:
- LOGP(0, LOGL_DEBUG, "GSM 04.80 operation code 0x%02x "
- "is not yet handled\n", operation_code);
- rc = 0;
- break;
- }
- } else {
- LOGP(0, LOGL_DEBUG, "Unexpected GSM 04.80 Component-ID tag 0x%02x "
- "(expecting Operation Code tag)\n",
- invoke_data[0]);
- rc = 0;
- }
-
- return rc;
-}
-
-/* Parse the parameters of a Process UnstructuredSS Request */
-static int parse_process_uss_req(const uint8_t *uss_req_data, uint16_t length,
- struct ussd_request *req)
-{
- int rc = 0;
- int num_chars;
- uint8_t dcs;
-
-
- /* we need at least that much */
- if (length < 8)
- return 0;
-
-
- if (uss_req_data[0] == GSM_0480_SEQUENCE_TAG) {
- if (uss_req_data[2] == ASN1_OCTET_STRING_TAG) {
- dcs = uss_req_data[4];
- if ((dcs == 0x0F) &&
- (uss_req_data[5] == ASN1_OCTET_STRING_TAG)) {
- num_chars = (uss_req_data[6] * 8) / 7;
- /* Prevent a mobile-originated buffer-overrun! */
- if (num_chars > MAX_LEN_USSD_STRING)
- num_chars = MAX_LEN_USSD_STRING;
- gsm_7bit_decode(req->text,
- &(uss_req_data[7]), num_chars);
- rc = 1;
- }
- }
- }
- return rc;
-}
-
-struct msgb *gsm0480_create_ussd_resp(uint8_t invoke_id, uint8_t trans_id, const char *text)
-{
- struct msgb *msg;
- struct gsm48_hdr *gh;
- uint8_t *ptr8;
- int response_len;
-
- msg = msgb_alloc_headroom(1024, 128, "GSM 04.80");
- if (!msg)
- return NULL;
-
- /* First put the payload text into the message */
- ptr8 = msgb_put(msg, 0);
- response_len = gsm_7bit_encode(ptr8, text);
- msgb_put(msg, response_len);
-
- /* Then wrap it as an Octet String */
- msgb_wrap_with_TL(msg, ASN1_OCTET_STRING_TAG);
-
- /* Pre-pend the DCS octet string */
- msgb_push_TLV1(msg, ASN1_OCTET_STRING_TAG, 0x0F);
-
- /* Then wrap these as a Sequence */
- msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG);
-
- /* Pre-pend the operation code */
- msgb_push_TLV1(msg, GSM0480_OPERATION_CODE,
- GSM0480_OP_CODE_PROCESS_USS_REQ);
-
- /* Wrap the operation code and IA5 string as a sequence */
- msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG);
-
- /* Pre-pend the invoke ID */
- msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, invoke_id);
-
- /* Wrap this up as a Return Result component */
- msgb_wrap_with_TL(msg, GSM0480_CTYPE_RETURN_RESULT);
-
- /* Wrap the component in a Facility message */
- msgb_wrap_with_TL(msg, GSM0480_IE_FACILITY);
-
- /* And finally pre-pend the L3 header */
- gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
- gh->proto_discr = GSM48_PDISC_NC_SS | trans_id
- | (1<<7); /* TI direction = 1 */
- gh->msg_type = GSM0480_MTYPE_RELEASE_COMPLETE;
-
- return msg;
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm0502.c b/src/shared/libosmocore/src/gsm/gsm0502.c
deleted file mode 100644
index df1d8e9e..00000000
--- a/src/shared/libosmocore/src/gsm/gsm0502.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Paging helper code */
-
-/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdint.h>
-
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/gsm0502.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/gsm/rsl.h>
-
-unsigned int
-gsm0502_calc_paging_group(struct gsm48_control_channel_descr *chan_desc, uint64_t imsi)
-{
- int ccch_conf;
- int bs_cc_chans;
- int blocks;
- unsigned int group;
-
- ccch_conf = chan_desc->ccch_conf;
- bs_cc_chans = rsl_ccch_conf_to_bs_cc_chans(ccch_conf);
- /* code word + 2, as 2 channels equals 0x0 */
- blocks = gsm48_number_of_paging_subchannels(chan_desc);
- group = gsm0502_get_paging_group(imsi, bs_cc_chans, blocks);
-
- return group;
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm0808.c b/src/shared/libosmocore/src/gsm/gsm0808.c
deleted file mode 100644
index 30098278..00000000
--- a/src/shared/libosmocore/src/gsm/gsm0808.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* (C) 2009,2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009,2010 by On-Waves
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/gsm/gsm0808.h>
-#include <osmocom/gsm/protocol/gsm_08_08.h>
-#include <osmocom/gsm/gsm48.h>
-
-#include <arpa/inet.h>
-
-#define BSSMAP_MSG_SIZE 512
-#define BSSMAP_MSG_HEADROOM 128
-
-struct msgb *gsm0808_create_layer3(struct msgb *msg_l3, uint16_t nc, uint16_t cc, int lac, uint16_t _ci)
-{
- struct msgb* msg;
- struct {
- uint8_t ident;
- struct gsm48_loc_area_id lai;
- uint16_t ci;
- } __attribute__ ((packed)) lai_ci;
-
- msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap cmpl l3");
- if (!msg)
- return NULL;
-
- /* create layer 3 header */
- msgb_v_put(msg, BSS_MAP_MSG_COMPLETE_LAYER_3);
-
- /* create the cell header */
- lai_ci.ident = CELL_IDENT_WHOLE_GLOBAL;
- gsm48_generate_lai(&lai_ci.lai, cc, nc, lac);
- lai_ci.ci = htons(_ci);
- msgb_tlv_put(msg, GSM0808_IE_CELL_IDENTIFIER, sizeof(lai_ci),
- (uint8_t *) &lai_ci);
-
- /* copy the layer3 data */
- msgb_tlv_put(msg, GSM0808_IE_LAYER_3_INFORMATION,
- msgb_l3len(msg_l3), msg_l3->l3h);
-
- /* push the bssmap header */
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_reset(void)
-{
- uint8_t cause = GSM0808_CAUSE_EQUIPMENT_FAILURE;
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: reset");
- if (!msg)
- return NULL;
-
- msgb_v_put(msg, BSS_MAP_MSG_RESET);
- msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_clear_complete(void)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: clear complete");
- uint8_t val = BSS_MAP_MSG_CLEAR_COMPLETE;
- if (!msg)
- return NULL;
-
- msg->l3h = msg->data;
- msgb_tlv_put(msg, BSSAP_MSG_BSS_MANAGEMENT, 1, &val);
-
- return msg;
-}
-
-struct msgb *gsm0808_create_clear_command(uint8_t reason)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: clear command");
- if (!msg)
- return NULL;
-
- msg->l3h = msgb_tv_put(msg, BSSAP_MSG_BSS_MANAGEMENT, 4);
- msgb_v_put(msg, BSS_MAP_MSG_CLEAR_CMD);
- msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &reason);
-
- return msg;
-}
-
-struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "cipher-complete");
- if (!msg)
- return NULL;
-
- /* send response with BSS override for A5/1... cheating */
- msgb_v_put(msg, BSS_MAP_MSG_CIPHER_MODE_COMPLETE);
-
- /* include layer3 in case we have at least two octets */
- if (layer3 && msgb_l3len(layer3) > 2) {
- msg->l4h = msgb_tlv_put(msg, GSM0808_IE_LAYER_3_MESSAGE_CONTENTS,
- msgb_l3len(layer3), layer3->l3h);
- }
-
- /* and the optional BSS message */
- msgb_tv_put(msg, GSM0808_IE_CHOSEN_ENCR_ALG, alg_id);
-
- /* pre-pend the header */
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_cipher_reject(uint8_t cause)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: clear complete");
- if (!msg)
- return NULL;
-
- msgb_tv_put(msg, BSS_MAP_MSG_CIPHER_MODE_REJECT, cause);
-
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len,
- const uint8_t *cm3, uint8_t cm3_len)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "classmark-update");
- if (!msg)
- return NULL;
-
- msgb_v_put(msg, BSS_MAP_MSG_CLASSMARK_UPDATE);
- msgb_tlv_put(msg, GSM0808_IE_CLASSMARK_INFORMATION_T2, cm2_len, cm2);
- if (cm3)
- msgb_tlv_put(msg, GSM0808_IE_CLASSMARK_INFORMATION_T3,
- cm3_len, cm3);
-
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_sapi_reject(uint8_t link_id)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: sapi 'n' reject");
- if (!msg)
- return NULL;
-
- msgb_v_put(msg, BSS_MAP_MSG_SAPI_N_REJECT);
- msgb_v_put(msg, link_id);
- msgb_v_put(msg, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
-
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
- uint8_t chosen_channel, uint8_t encr_alg_id,
- uint8_t speech_mode)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: ass compl");
- if (!msg)
- return NULL;
-
- msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_COMPLETE);
-
- /* write 3.2.2.22 */
- msgb_tv_put(msg, GSM0808_IE_RR_CAUSE, rr_cause);
-
- /* write cirtcuit identity code 3.2.2.2 */
- /* write cell identifier 3.2.2.17 */
- /* write chosen channel 3.2.2.33 when BTS picked it */
- msgb_tv_put(msg, GSM0808_IE_CHOSEN_CHANNEL, chosen_channel);
-
- /* write chosen encryption algorithm 3.2.2.44 */
- msgb_tv_put(msg, GSM0808_IE_CHOSEN_ENCR_ALG, encr_alg_id);
-
- /* write circuit pool 3.2.2.45 */
- /* write speech version chosen: 3.2.2.51 when BTS picked it */
- if (speech_mode != 0)
- msgb_tv_put(msg, GSM0808_IE_SPEECH_VERSION, speech_mode);
-
- /* write LSA identifier 3.2.2.15 */
-
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause)
-{
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: ass fail");
- if (!msg)
- return NULL;
-
- msgb_v_put(msg, BSS_MAP_MSG_ASSIGMENT_FAILURE);
- msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
-
- /* RR cause 3.2.2.22 */
- if (rr_cause)
- msgb_tv_put(msg, GSM0808_IE_RR_CAUSE, *rr_cause);
-
- /* Circuit pool 3.22.45 */
- /* Circuit pool list 3.2.2.46 */
-
- /* update the size */
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-struct msgb *gsm0808_create_clear_rqst(uint8_t cause)
-{
- struct msgb *msg;
-
- msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "bssmap: clear rqst");
- if (!msg)
- return NULL;
-
- msgb_v_put(msg, BSS_MAP_MSG_CLEAR_RQST);
- msgb_tlv_put(msg, GSM0808_IE_CAUSE, 1, &cause);
- msg->l3h = msgb_tv_push(msg, BSSAP_MSG_BSS_MANAGEMENT, msgb_length(msg));
-
- return msg;
-}
-
-void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id)
-{
- uint8_t *hh = msgb_push(msg, 3);
- hh[0] = BSSAP_MSG_DTAP;
- hh[1] = link_id;
- hh[2] = msg->len - 3;
-}
-
-struct msgb *gsm0808_create_dtap(struct msgb *msg_l3, uint8_t link_id)
-{
- struct dtap_header *header;
- uint8_t *data;
- struct msgb *msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM,
- "dtap");
- if (!msg)
- return NULL;
-
- /* DTAP header */
- msg->l3h = msgb_put(msg, sizeof(*header));
- header = (struct dtap_header *) &msg->l3h[0];
- header->type = BSSAP_MSG_DTAP;
- header->link_id = link_id;
- header->length = msgb_l3len(msg_l3);
-
- /* Payload */
- data = msgb_put(msg, header->length);
- memcpy(data, msg_l3->l3h, header->length);
-
- return msg;
-}
-
-static const struct tlv_definition bss_att_tlvdef = {
- .def = {
- [GSM0808_IE_IMSI] = { TLV_TYPE_TLV },
- [GSM0808_IE_TMSI] = { TLV_TYPE_TLV },
- [GSM0808_IE_CELL_IDENTIFIER_LIST] = { TLV_TYPE_TLV },
- [GSM0808_IE_CHANNEL_NEEDED] = { TLV_TYPE_TV },
- [GSM0808_IE_EMLPP_PRIORITY] = { TLV_TYPE_TV },
- [GSM0808_IE_CHANNEL_TYPE] = { TLV_TYPE_TLV },
- [GSM0808_IE_PRIORITY] = { TLV_TYPE_TLV },
- [GSM0808_IE_CIRCUIT_IDENTITY_CODE] = { TLV_TYPE_FIXED, 2 },
- [GSM0808_IE_DOWNLINK_DTX_FLAG] = { TLV_TYPE_TV },
- [GSM0808_IE_INTERFERENCE_BAND_TO_USE] = { TLV_TYPE_TV },
- [GSM0808_IE_CLASSMARK_INFORMATION_T2] = { TLV_TYPE_TLV },
- [GSM0808_IE_GROUP_CALL_REFERENCE] = { TLV_TYPE_TLV },
- [GSM0808_IE_TALKER_FLAG] = { TLV_TYPE_T },
- [GSM0808_IE_CONFIG_EVO_INDI] = { TLV_TYPE_TV },
- [GSM0808_IE_LSA_ACCESS_CTRL_SUPPR] = { TLV_TYPE_TV },
- [GSM0808_IE_SERVICE_HANDOVER] = { TLV_TYPE_TLV },
- [GSM0808_IE_ENCRYPTION_INFORMATION] = { TLV_TYPE_TLV },
- [GSM0808_IE_CIPHER_RESPONSE_MODE] = { TLV_TYPE_TV },
- [GSM0808_IE_CELL_IDENTIFIER] = { TLV_TYPE_TLV },
- [GSM0808_IE_CHOSEN_CHANNEL] = { TLV_TYPE_TV },
- [GSM0808_IE_LAYER_3_INFORMATION] = { TLV_TYPE_TLV },
- [GSM0808_IE_SPEECH_VERSION] = { TLV_TYPE_TV },
- [GSM0808_IE_CHOSEN_ENCR_ALG] = { TLV_TYPE_TV },
- },
-};
-
-const struct tlv_definition *gsm0808_att_tlvdef(void)
-{
- return &bss_att_tlvdef;
-}
-
-static const struct value_string gsm0808_msgt_names[] = {
- { BSS_MAP_MSG_ASSIGMENT_RQST, "ASSIGNMENT REQ" },
- { BSS_MAP_MSG_ASSIGMENT_COMPLETE, "ASSIGNMENT COMPL" },
- { BSS_MAP_MSG_ASSIGMENT_FAILURE, "ASSIGNMENT FAIL" },
-
- { BSS_MAP_MSG_HANDOVER_RQST, "HANDOVER REQ" },
- { BSS_MAP_MSG_HANDOVER_REQUIRED, "HANDOVER REQUIRED" },
- { BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE,"HANDOVER REQ ACK" },
- { BSS_MAP_MSG_HANDOVER_CMD, "HANDOVER CMD" },
- { BSS_MAP_MSG_HANDOVER_COMPLETE, "HANDOVER COMPLETE" },
- { BSS_MAP_MSG_HANDOVER_SUCCEEDED, "HANDOVER SUCCESS" },
- { BSS_MAP_MSG_HANDOVER_FAILURE, "HANDOVER FAILURE" },
- { BSS_MAP_MSG_HANDOVER_PERFORMED, "HANDOVER PERFORMED" },
- { BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE, "HANDOVER CAND ENQ" },
- { BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE, "HANDOVER CAND RESP" },
- { BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT, "HANDOVER REQ REJ" },
- { BSS_MAP_MSG_HANDOVER_DETECT, "HANDOVER DETECT" },
-
- { BSS_MAP_MSG_CLEAR_CMD, "CLEAR COMMAND" },
- { BSS_MAP_MSG_CLEAR_COMPLETE, "CLEAR COMPLETE" },
- { BSS_MAP_MSG_CLEAR_RQST, "CLEAR REQUEST" },
- { BSS_MAP_MSG_SAPI_N_REJECT, "SAPI N REJECT" },
- { BSS_MAP_MSG_CONFUSION, "CONFUSION" },
-
- { BSS_MAP_MSG_SUSPEND, "SUSPEND" },
- { BSS_MAP_MSG_RESUME, "RESUME" },
- { BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION, "CONN ORIENT INFO" },
- { BSS_MAP_MSG_PERFORM_LOCATION_RQST, "PERFORM LOC REQ" },
- { BSS_MAP_MSG_LSA_INFORMATION, "LSA INFORMATION" },
- { BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE, "PERFORM LOC RESP" },
- { BSS_MAP_MSG_PERFORM_LOCATION_ABORT, "PERFORM LOC ABORT" },
- { BSS_MAP_MSG_COMMON_ID, "COMMON ID" },
-
- { BSS_MAP_MSG_RESET, "RESET" },
- { BSS_MAP_MSG_RESET_ACKNOWLEDGE, "RESET ACK" },
- { BSS_MAP_MSG_OVERLOAD, "OVERLOAD" },
- { BSS_MAP_MSG_RESET_CIRCUIT, "RESET CIRCUIT" },
- { BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE, "RESET CIRCUIT ACK" },
- { BSS_MAP_MSG_MSC_INVOKE_TRACE, "MSC INVOKE TRACE" },
- { BSS_MAP_MSG_BSS_INVOKE_TRACE, "BSS INVOKE TRACE" },
- { BSS_MAP_MSG_CONNECTIONLESS_INFORMATION, "CONNLESS INFO" },
-
- { BSS_MAP_MSG_BLOCK, "BLOCK" },
- { BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE, "BLOCK ACK" },
- { BSS_MAP_MSG_UNBLOCK, "UNBLOCK" },
- { BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE, "UNBLOCK ACK" },
- { BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK, "CIRC GROUP BLOCK" },
- { BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE, "CIRC GORUP BLOCK ACK" },
- { BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK, "CIRC GROUP UNBLOCK" },
- { BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE, "CIRC GROUP UNBLOCK ACK" },
- { BSS_MAP_MSG_UNEQUIPPED_CIRCUIT, "UNEQUIPPED CIRCUIT" },
- { BSS_MAP_MSG_CHANGE_CIRCUIT, "CHANGE CIRCUIT" },
- { BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE, "CHANGE CIRCUIT ACK" },
-
- { BSS_MAP_MSG_RESOURCE_RQST, "RESOURCE REQ" },
- { BSS_MAP_MSG_RESOURCE_INDICATION, "RESOURCE IND" },
- { BSS_MAP_MSG_PAGING, "PAGING" },
- { BSS_MAP_MSG_CIPHER_MODE_CMD, "CIPHER MODE CMD" },
- { BSS_MAP_MSG_CLASSMARK_UPDATE, "CLASSMARK UPDATE" },
- { BSS_MAP_MSG_CIPHER_MODE_COMPLETE, "CIPHER MODE COMPLETE" },
- { BSS_MAP_MSG_QUEUING_INDICATION, "QUEUING INDICATION" },
- { BSS_MAP_MSG_COMPLETE_LAYER_3, "COMPLETE LAYER 3" },
- { BSS_MAP_MSG_CLASSMARK_RQST, "CLASSMARK REQ" },
- { BSS_MAP_MSG_CIPHER_MODE_REJECT, "CIPHER MODE REJECT" },
- { BSS_MAP_MSG_LOAD_INDICATION, "LOAD IND" },
-
- /* FIXME: VGCS/VBS */
-
- { 0, NULL }
-};
-
-const char *gsm0808_bssmap_name(uint8_t msg_type)
-{
- return get_value_string(gsm0808_msgt_names, msg_type);
-}
-
-static const struct value_string gsm0808_bssap_names[] = {
- { BSSAP_MSG_BSS_MANAGEMENT, "MANAGEMENT" },
- { BSSAP_MSG_DTAP, "DTAP" },
-};
-
-const char *gsm0808_bssap_name(uint8_t msg_type)
-{
- return get_value_string(gsm0808_bssap_names, msg_type);
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm48.c b/src/shared/libosmocore/src/gsm/gsm48.c
deleted file mode 100644
index ea05d450..00000000
--- a/src/shared/libosmocore/src/gsm/gsm48.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/* GSM Mobile Radio Interface Layer 3 messages
- * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
-
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <arpa/inet.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/gsm/gsm0502.h>
-
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_08_58.h>
-
-const struct tlv_definition gsm48_att_tlvdef = {
- .def = {
- [GSM48_IE_MOBILE_ID] = { TLV_TYPE_TLV },
- [GSM48_IE_NAME_LONG] = { TLV_TYPE_TLV },
- [GSM48_IE_NAME_SHORT] = { TLV_TYPE_TLV },
- [GSM48_IE_UTC] = { TLV_TYPE_TV },
- [GSM48_IE_NET_TIME_TZ] = { TLV_TYPE_FIXED, 7 },
- [GSM48_IE_LSA_IDENT] = { TLV_TYPE_TLV },
-
- [GSM48_IE_BEARER_CAP] = { TLV_TYPE_TLV },
- [GSM48_IE_CAUSE] = { TLV_TYPE_TLV },
- [GSM48_IE_CC_CAP] = { TLV_TYPE_TLV },
- [GSM48_IE_ALERT] = { TLV_TYPE_TLV },
- [GSM48_IE_FACILITY] = { TLV_TYPE_TLV },
- [GSM48_IE_PROGR_IND] = { TLV_TYPE_TLV },
- [GSM48_IE_AUX_STATUS] = { TLV_TYPE_TLV },
- [GSM48_IE_NOTIFY] = { TLV_TYPE_TV },
- [GSM48_IE_KPD_FACILITY] = { TLV_TYPE_TV },
- [GSM48_IE_SIGNAL] = { TLV_TYPE_TV },
- [GSM48_IE_CONN_BCD] = { TLV_TYPE_TLV },
- [GSM48_IE_CONN_SUB] = { TLV_TYPE_TLV },
- [GSM48_IE_CALLING_BCD] = { TLV_TYPE_TLV },
- [GSM48_IE_CALLING_SUB] = { TLV_TYPE_TLV },
- [GSM48_IE_CALLED_BCD] = { TLV_TYPE_TLV },
- [GSM48_IE_CALLED_SUB] = { TLV_TYPE_TLV },
- [GSM48_IE_REDIR_BCD] = { TLV_TYPE_TLV },
- [GSM48_IE_REDIR_SUB] = { TLV_TYPE_TLV },
- [GSM48_IE_LOWL_COMPAT] = { TLV_TYPE_TLV },
- [GSM48_IE_HIGHL_COMPAT] = { TLV_TYPE_TLV },
- [GSM48_IE_USER_USER] = { TLV_TYPE_TLV },
- [GSM48_IE_SS_VERS] = { TLV_TYPE_TLV },
- [GSM48_IE_MORE_DATA] = { TLV_TYPE_T },
- [GSM48_IE_CLIR_SUPP] = { TLV_TYPE_T },
- [GSM48_IE_CLIR_INVOC] = { TLV_TYPE_T },
- [GSM48_IE_REV_C_SETUP] = { TLV_TYPE_T },
- [GSM48_IE_REPEAT_CIR] = { TLV_TYPE_T },
- [GSM48_IE_REPEAT_SEQ] = { TLV_TYPE_T },
- /* FIXME: more elements */
- },
-};
-
-/* RR elements */
-const struct tlv_definition gsm48_rr_att_tlvdef = {
- .def = {
- /* NOTE: Don't add IE 17 = MOBILE_ID here, it already used. */
- [GSM48_IE_VGCS_TARGET] = { TLV_TYPE_TLV },
- [GSM48_IE_FRQSHORT_AFTER] = { TLV_TYPE_FIXED, 9 },
- [GSM48_IE_MUL_RATE_CFG] = { TLV_TYPE_TLV },
- [GSM48_IE_FREQ_L_AFTER] = { TLV_TYPE_TLV },
- [GSM48_IE_MSLOT_DESC] = { TLV_TYPE_TLV },
- [GSM48_IE_CHANMODE_2] = { TLV_TYPE_TV },
- [GSM48_IE_FRQSHORT_BEFORE] = { TLV_TYPE_FIXED, 9 },
- [GSM48_IE_CHANMODE_3] = { TLV_TYPE_TV },
- [GSM48_IE_CHANMODE_4] = { TLV_TYPE_TV },
- [GSM48_IE_CHANMODE_5] = { TLV_TYPE_TV },
- [GSM48_IE_CHANMODE_6] = { TLV_TYPE_TV },
- [GSM48_IE_CHANMODE_7] = { TLV_TYPE_TV },
- [GSM48_IE_CHANMODE_8] = { TLV_TYPE_TV },
- [GSM48_IE_FREQ_L_BEFORE] = { TLV_TYPE_TLV },
- [GSM48_IE_CH_DESC_1_BEFORE] = { TLV_TYPE_FIXED, 3 },
- [GSM48_IE_CH_DESC_2_BEFORE] = { TLV_TYPE_FIXED, 3 },
- [GSM48_IE_F_CH_SEQ_BEFORE] = { TLV_TYPE_FIXED, 9 },
- [GSM48_IE_CLASSMARK3] = { TLV_TYPE_TLV },
- [GSM48_IE_MA_BEFORE] = { TLV_TYPE_TLV },
- [GSM48_IE_RR_PACKET_UL] = { TLV_TYPE_TLV },
- [GSM48_IE_RR_PACKET_DL] = { TLV_TYPE_TLV },
- [GSM48_IE_CELL_CH_DESC] = { TLV_TYPE_FIXED, 16 },
- [GSM48_IE_CHANMODE_1] = { TLV_TYPE_TV },
- [GSM48_IE_CHDES_2_AFTER] = { TLV_TYPE_FIXED, 3 },
- [GSM48_IE_MODE_SEC_CH] = { TLV_TYPE_TV },
- [GSM48_IE_F_CH_SEQ_AFTER] = { TLV_TYPE_FIXED, 9 },
- [GSM48_IE_MA_AFTER] = { TLV_TYPE_TLV },
- [GSM48_IE_BA_RANGE] = { TLV_TYPE_TLV },
- [GSM48_IE_GROUP_CHDES] = { TLV_TYPE_TLV },
- [GSM48_IE_BA_LIST_PREF] = { TLV_TYPE_TLV },
- [GSM48_IE_MOB_OVSERV_DIF] = { TLV_TYPE_TLV },
- [GSM48_IE_REALTIME_DIFF] = { TLV_TYPE_TLV },
- [GSM48_IE_START_TIME] = { TLV_TYPE_FIXED, 2 },
- [GSM48_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
- [GSM48_IE_GROUP_CIP_SEQ] = { TLV_TYPE_SINGLE_TV },
- [GSM48_IE_CIP_MODE_SET] = { TLV_TYPE_SINGLE_TV },
- [GSM48_IE_GPRS_RESUMPT] = { TLV_TYPE_SINGLE_TV },
- [GSM48_IE_SYNC_IND] = { TLV_TYPE_SINGLE_TV },
- },
-};
-
-/* MM elements */
-const struct tlv_definition gsm48_mm_att_tlvdef = {
- .def = {
- [GSM48_IE_MOBILE_ID] = { TLV_TYPE_TLV },
- [GSM48_IE_NAME_LONG] = { TLV_TYPE_TLV },
- [GSM48_IE_NAME_SHORT] = { TLV_TYPE_TLV },
- [GSM48_IE_UTC] = { TLV_TYPE_TV },
- [GSM48_IE_NET_TIME_TZ] = { TLV_TYPE_FIXED, 7 },
- [GSM48_IE_LSA_IDENT] = { TLV_TYPE_TLV },
-
- [GSM48_IE_LOCATION_AREA] = { TLV_TYPE_FIXED, 5 },
- [GSM48_IE_PRIORITY_LEV] = { TLV_TYPE_SINGLE_TV },
- [GSM48_IE_FOLLOW_ON_PROC] = { TLV_TYPE_T },
- [GSM48_IE_CTS_PERMISSION] = { TLV_TYPE_T },
- },
-};
-
-static const struct value_string rr_cause_names[] = {
- { GSM48_RR_CAUSE_NORMAL, "Normal event" },
- { GSM48_RR_CAUSE_ABNORMAL_UNSPEC, "Abnormal release, unspecified" },
- { GSM48_RR_CAUSE_ABNORMAL_UNACCT, "Abnormal release, channel unacceptable" },
- { GSM48_RR_CAUSE_ABNORMAL_TIMER, "Abnormal release, timer expired" },
- { GSM48_RR_CAUSE_ABNORMAL_NOACT, "Abnormal release, no activity on radio path" },
- { GSM48_RR_CAUSE_PREMPTIVE_REL, "Preemptive release" },
- { GSM48_RR_CAUSE_HNDOVER_IMP, "Handover impossible, timing advance out of range" },
- { GSM48_RR_CAUSE_CHAN_MODE_UNACCT, "Channel mode unacceptable" },
- { GSM48_RR_CAUSE_FREQ_NOT_IMPL, "Frequency not implemented" },
- { GSM48_RR_CAUSE_CALL_CLEARED, "Call already cleared" },
- { GSM48_RR_CAUSE_SEMANT_INCORR, "Semantically incorrect message" },
- { GSM48_RR_CAUSE_INVALID_MAND_INF, "Invalid mandatory information" },
- { GSM48_RR_CAUSE_MSG_TYPE_N, "Message type non-existant or not implemented" },
- { GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT, "Message type not compatible with protocol state" },
- { GSM48_RR_CAUSE_COND_IE_ERROR, "Conditional IE error" },
- { GSM48_RR_CAUSE_NO_CELL_ALLOC_A, "No cell allocation available" },
- { GSM48_RR_CAUSE_PROT_ERROR_UNSPC, "Protocol error unspecified" },
- { 0, NULL },
-};
-
-/* FIXME: convert to value_string */
-static const char *cc_state_names[32] = {
- "NULL",
- "INITIATED",
- "MM_CONNECTION_PEND",
- "MO_CALL_PROC",
- "CALL_DELIVERED",
- "illegal state 5",
- "CALL_PRESENT",
- "CALL_RECEIVED",
- "CONNECT_REQUEST",
- "MO_TERM_CALL_CONF",
- "ACTIVE",
- "DISCONNECT_REQ",
- "DISCONNECT_IND",
- "illegal state 13",
- "illegal state 14",
- "illegal state 15",
- "illegal state 16",
- "illegal state 17",
- "illegal state 18",
- "RELEASE_REQ",
- "illegal state 20",
- "illegal state 21",
- "illegal state 22",
- "illegal state 23",
- "illegal state 24",
- "illegal state 25",
- "MO_ORIG_MODIFY",
- "MO_TERM_MODIFY",
- "CONNECT_IND",
- "illegal state 29",
- "illegal state 30",
- "illegal state 31",
-};
-
-const char *gsm48_cc_state_name(uint8_t state)
-{
- if (state < ARRAY_SIZE(cc_state_names))
- return cc_state_names[state];
-
- return "invalid";
-}
-
-static const struct value_string cc_msg_names[] = {
- { GSM48_MT_CC_ALERTING, "ALERTING" },
- { GSM48_MT_CC_CALL_PROC, "CALL_PROC" },
- { GSM48_MT_CC_PROGRESS, "PROGRESS" },
- { GSM48_MT_CC_ESTAB, "ESTAB" },
- { GSM48_MT_CC_SETUP, "SETUP" },
- { GSM48_MT_CC_ESTAB_CONF, "ESTAB_CONF" },
- { GSM48_MT_CC_CONNECT, "CONNECT" },
- { GSM48_MT_CC_CALL_CONF, "CALL_CONF" },
- { GSM48_MT_CC_START_CC, "START_CC" },
- { GSM48_MT_CC_RECALL, "RECALL" },
- { GSM48_MT_CC_EMERG_SETUP, "EMERG_SETUP" },
- { GSM48_MT_CC_CONNECT_ACK, "CONNECT_ACK" },
- { GSM48_MT_CC_USER_INFO, "USER_INFO" },
- { GSM48_MT_CC_MODIFY_REJECT, "MODIFY_REJECT" },
- { GSM48_MT_CC_MODIFY, "MODIFY" },
- { GSM48_MT_CC_HOLD, "HOLD" },
- { GSM48_MT_CC_HOLD_ACK, "HOLD_ACK" },
- { GSM48_MT_CC_HOLD_REJ, "HOLD_REJ" },
- { GSM48_MT_CC_RETR, "RETR" },
- { GSM48_MT_CC_RETR_ACK, "RETR_ACK" },
- { GSM48_MT_CC_RETR_REJ, "RETR_REJ" },
- { GSM48_MT_CC_MODIFY_COMPL, "MODIFY_COMPL" },
- { GSM48_MT_CC_DISCONNECT, "DISCONNECT" },
- { GSM48_MT_CC_RELEASE_COMPL, "RELEASE_COMPL" },
- { GSM48_MT_CC_RELEASE, "RELEASE" },
- { GSM48_MT_CC_STOP_DTMF, "STOP_DTMF" },
- { GSM48_MT_CC_STOP_DTMF_ACK, "STOP_DTMF_ACK" },
- { GSM48_MT_CC_STATUS_ENQ, "STATUS_ENQ" },
- { GSM48_MT_CC_START_DTMF, "START_DTMF" },
- { GSM48_MT_CC_START_DTMF_ACK, "START_DTMF_ACK" },
- { GSM48_MT_CC_START_DTMF_REJ, "START_DTMF_REJ" },
- { GSM48_MT_CC_CONG_CTRL, "CONG_CTRL" },
- { GSM48_MT_CC_FACILITY, "FACILITY" },
- { GSM48_MT_CC_STATUS, "STATUS" },
- { GSM48_MT_CC_NOTIFY, "NOTFIY" },
- { 0, NULL }
-};
-
-const char *gsm48_cc_msg_name(uint8_t msgtype)
-{
- return get_value_string(cc_msg_names, msgtype);
-}
-
-const char *rr_cause_name(uint8_t cause)
-{
- return get_value_string(rr_cause_names, cause);
-}
-
-static void to_bcd(uint8_t *bcd, uint16_t val)
-{
- bcd[2] = val % 10;
- val = val / 10;
- bcd[1] = val % 10;
- val = val / 10;
- bcd[0] = val % 10;
- val = val / 10;
-}
-
-void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
- uint16_t mnc, uint16_t lac)
-{
- uint8_t bcd[3];
-
- to_bcd(bcd, mcc);
- lai48->digits[0] = bcd[0] | (bcd[1] << 4);
- lai48->digits[1] = bcd[2];
-
- to_bcd(bcd, mnc);
- /* FIXME: do we need three-digit MNC? See Table 10.5.3 */
- if (mnc > 99) {
- lai48->digits[1] |= bcd[2] << 4;
- lai48->digits[2] = bcd[0] | (bcd[1] << 4);
- } else {
- lai48->digits[1] |= 0xf << 4;
- lai48->digits[2] = bcd[1] | (bcd[2] << 4);
- }
-
- lai48->lac = htons(lac);
-}
-
-/* Attention: this function retunrs true integers, not hex! */
-int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
- uint16_t *mnc, uint16_t *lac)
-{
- *mcc = (lai->digits[0] & 0x0f) * 100
- + (lai->digits[0] >> 4) * 10
- + (lai->digits[1] & 0x0f);
-
- if ((lai->digits[1] & 0xf0) == 0xf0) {
- *mnc = (lai->digits[2] & 0x0f) * 10
- + (lai->digits[2] >> 4);
- } else {
- *mnc = (lai->digits[2] & 0x0f) * 100
- + (lai->digits[2] >> 4) * 10
- + (lai->digits[1] >> 4);
- }
- *lac = ntohs(lai->lac);
-
- return 0;
-}
-
-int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi)
-{
- uint32_t *tptr = (uint32_t *) &buf[3];
-
- buf[0] = GSM48_IE_MOBILE_ID;
- buf[1] = GSM48_TMSI_LEN;
- buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
- *tptr = htonl(tmsi);
-
- return 7;
-}
-
-int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
-{
- unsigned int length = strlen(imsi), i, off = 0;
- uint8_t odd = (length & 0x1) == 1;
-
- buf[0] = GSM48_IE_MOBILE_ID;
- buf[2] = osmo_char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3);
-
- /* if the length is even we will fill half of the last octet */
- if (odd)
- buf[1] = (length + 1) >> 1;
- else
- buf[1] = (length + 2) >> 1;
-
- for (i = 1; i < buf[1]; ++i) {
- uint8_t lower, upper;
-
- lower = osmo_char2bcd(imsi[++off]);
- if (!odd && off + 1 == length)
- upper = 0x0f;
- else
- upper = osmo_char2bcd(imsi[++off]) & 0x0f;
-
- buf[2 + i] = (upper << 4) | lower;
- }
-
- return 2 + buf[1];
-}
-
-/* Convert Mobile Identity (10.5.1.4) to string */
-int gsm48_mi_to_string(char *string, const int str_len, const uint8_t *mi,
- const int mi_len)
-{
- int i;
- uint8_t mi_type;
- char *str_cur = string;
- uint32_t tmsi;
-
- mi_type = mi[0] & GSM_MI_TYPE_MASK;
-
- switch (mi_type) {
- case GSM_MI_TYPE_NONE:
- break;
- case GSM_MI_TYPE_TMSI:
- /* Table 10.5.4.3, reverse generate_mid_from_tmsi */
- if (mi_len == GSM48_TMSI_LEN && mi[0] == (0xf0 | GSM_MI_TYPE_TMSI)) {
- memcpy(&tmsi, &mi[1], 4);
- tmsi = ntohl(tmsi);
- return snprintf(string, str_len, "%u", tmsi);
- }
- break;
- case GSM_MI_TYPE_IMSI:
- case GSM_MI_TYPE_IMEI:
- case GSM_MI_TYPE_IMEISV:
- *str_cur++ = osmo_bcd2char(mi[0] >> 4);
-
- for (i = 1; i < mi_len; i++) {
- if (str_cur + 2 >= string + str_len)
- return str_cur - string;
- *str_cur++ = osmo_bcd2char(mi[i] & 0xf);
- /* skip last nibble in last input byte when GSM_EVEN */
- if( (i != mi_len-1) || (mi[0] & GSM_MI_ODD))
- *str_cur++ = osmo_bcd2char(mi[i] >> 4);
- }
- break;
- default:
- break;
- }
- *str_cur++ = '\0';
-
- return str_cur - string;
-}
-
-void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf)
-{
- raid->mcc = (buf[0] & 0xf) * 100;
- raid->mcc += (buf[0] >> 4) * 10;
- raid->mcc += (buf[1] & 0xf) * 1;
-
- /* I wonder who came up with the stupidity of encoding the MNC
- * differently depending on how many digits its decimal number has! */
- if ((buf[1] >> 4) == 0xf) {
- raid->mnc = (buf[2] & 0xf) * 10;
- raid->mnc += (buf[2] >> 4) * 1;
- } else {
- raid->mnc = (buf[2] & 0xf) * 100;
- raid->mnc += (buf[2] >> 4) * 10;
- raid->mnc += (buf[1] >> 4) * 1;
- }
-
- raid->lac = ntohs(*(uint16_t *)(buf + 3));
- raid->rac = buf[5];
-}
-
-int gsm48_construct_ra(uint8_t *buf, const struct gprs_ra_id *raid)
-{
- uint16_t mcc = raid->mcc;
- uint16_t mnc = raid->mnc;
- uint16_t _lac;
-
- buf[0] = ((mcc / 100) % 10) | (((mcc / 10) % 10) << 4);
- buf[1] = (mcc % 10);
-
- /* I wonder who came up with the stupidity of encoding the MNC
- * differently depending on how many digits its decimal number has! */
- if (mnc < 100) {
- buf[1] |= 0xf0;
- buf[2] = ((mnc / 10) % 10) | ((mnc % 10) << 4);
- } else {
- buf[1] |= (mnc % 10) << 4;
- buf[2] = ((mnc / 100) % 10) | (((mnc / 10) % 10) << 4);
- }
-
- _lac = htons(raid->lac);
- memcpy(buf + 3, &_lac, 2);
-
- buf[5] = raid->rac;
-
- return 6;
-}
-
-/* From Table 10.5.33 of GSM 04.08 */
-int gsm48_number_of_paging_subchannels(struct gsm48_control_channel_descr *chan_desc)
-{
- unsigned int n_pag_blocks = gsm0502_get_n_pag_blocks(chan_desc);
-
- if (chan_desc->ccch_conf == RSL_BCCH_CCCH_CONF_1_C)
- return OSMO_MAX(1, n_pag_blocks) * (chan_desc->bs_pa_mfrms + 2);
- else
- return n_pag_blocks * (chan_desc->bs_pa_mfrms + 2);
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm48_ie.c b/src/shared/libosmocore/src/gsm/gsm48_ie.c
deleted file mode 100644
index 78619b97..00000000
--- a/src/shared/libosmocore/src/gsm/gsm48_ie.c
+++ /dev/null
@@ -1,1192 +0,0 @@
-/* GSM Mobile Radio Interface Layer 3 messages
- * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
-
-/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2010 by Andreas Eversberg
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/mncc.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/gsm48_ie.h>
-
-static const char bcd_num_digits[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', '*', '#', 'a', 'b', 'c', '\0'
-};
-
-/* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
-int gsm48_decode_bcd_number(char *output, int output_len,
- const uint8_t *bcd_lv, int h_len)
-{
- uint8_t in_len = bcd_lv[0];
- int i;
-
- for (i = 1 + h_len; i <= in_len; i++) {
- /* lower nibble */
- output_len--;
- if (output_len <= 1)
- break;
- *output++ = bcd_num_digits[bcd_lv[i] & 0xf];
-
- /* higher nibble */
- output_len--;
- if (output_len <= 1)
- break;
- *output++ = bcd_num_digits[bcd_lv[i] >> 4];
- }
- if (output_len >= 1)
- *output++ = '\0';
-
- return 0;
-}
-
-/* convert a single ASCII character to call-control BCD */
-static int asc_to_bcd(const char asc)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(bcd_num_digits); i++) {
- if (bcd_num_digits[i] == asc)
- return i;
- }
- return -EINVAL;
-}
-
-/* convert a ASCII phone number to 'called/calling/connect party BCD number' */
-int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
- int h_len, const char *input)
-{
- int in_len = strlen(input);
- int i;
- uint8_t *bcd_cur = bcd_lv + 1 + h_len;
-
- /* two digits per byte, plus type byte */
- bcd_lv[0] = in_len/2 + h_len;
- if (in_len % 2)
- bcd_lv[0]++;
-
- if (bcd_lv[0] > max_len)
- return -EIO;
-
- for (i = 0; i < in_len; i++) {
- int rc = asc_to_bcd(input[i]);
- if (rc < 0)
- return rc;
- if (i % 2 == 0)
- *bcd_cur = rc;
- else
- *bcd_cur++ |= (rc << 4);
- }
- /* append padding nibble in case of odd length */
- if (i % 2)
- *bcd_cur++ |= 0xf0;
-
- /* return how many bytes we used */
- return (bcd_cur - bcd_lv);
-}
-
-/* TS 04.08 10.5.4.5: decode 'bearer capability' */
-int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
- int i, s;
-
- if (in_len < 1)
- return -EINVAL;
-
- bcap->speech_ver[0] = -1; /* end of list, of maximum 7 values */
-
- /* octet 3 */
- bcap->transfer = lv[1] & 0x07;
- bcap->mode = (lv[1] & 0x08) >> 3;
- bcap->coding = (lv[1] & 0x10) >> 4;
- bcap->radio = (lv[1] & 0x60) >> 5;
-
- switch (bcap->transfer) {
- case GSM_MNCC_BCAP_SPEECH:
- i = 1;
- s = 0;
- while(!(lv[i] & 0x80)) {
- i++; /* octet 3a etc */
- if (in_len < i)
- return 0;
- bcap->speech_ver[s++] = lv[i] & 0x0f;
- bcap->speech_ver[s] = -1; /* end of list */
- if (i == 2) /* octet 3a */
- bcap->speech_ctm = (lv[i] & 0x20) >> 5;
- if (s == 7) /* maximum speech versions + end of list */
- return 0;
- }
- break;
- case GSM_MNCC_BCAP_UNR_DIG:
- case GSM_MNCC_BCAP_FAX_G3:
- i = 1;
- while(!(lv[i] & 0x80)) {
- i++; /* octet 3a etc */
- if (in_len < i)
- return 0;
- /* ignore them */
- }
- /* octet 4: skip */
- i++;
- /* octet 5 */
- i++;
- if (in_len < i)
- return 0;
- bcap->data.rate_adaption = (lv[i] >> 3) & 3;
- bcap->data.sig_access = lv[i] & 7;
- while(!(lv[i] & 0x80)) {
- i++; /* octet 5a etc */
- if (in_len < i)
- return 0;
- /* ignore them */
- }
- /* octet 6 */
- i++;
- if (in_len < i)
- return 0;
- bcap->data.async = lv[i] & 1;
- if (!(lv[i] & 0x80)) {
- i++;
- if (in_len < i)
- return 0;
- /* octet 6a */
- bcap->data.nr_stop_bits = ((lv[i] >> 7) & 1) + 1;
- if (lv[i] & 0x10)
- bcap->data.nr_data_bits = 8;
- else
- bcap->data.nr_data_bits = 7;
- bcap->data.user_rate = lv[i] & 0xf;
-
- if (!(lv[i] & 0x80)) {
- i++;
- if (in_len < i)
- return 0;
- /* octet 6b */
- bcap->data.parity = lv[i] & 7;
- bcap->data.interm_rate = (lv[i] >> 5) & 3;
-
- /* octet 6c */
- if (!(lv[i] & 0x80)) {
- i++;
- if (in_len < i)
- return 0;
- bcap->data.transp = (lv[i] >> 5) & 3;
- bcap->data.modem_type = lv[i] & 0x1F;
- }
- }
-
- }
- break;
- default:
- i = 1;
- while (!(lv[i] & 0x80)) {
- i++; /* octet 3a etc */
- if (in_len < i)
- return 0;
- /* ignore them */
- }
- /* FIXME: implement OCTET 4+ parsing */
- break;
- }
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.5: encode 'bearer capability' */
-int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only,
- const struct gsm_mncc_bearer_cap *bcap)
-{
- uint8_t lv[32 + 1];
- int i = 1, s;
-
- lv[1] = bcap->transfer;
- lv[1] |= bcap->mode << 3;
- lv[1] |= bcap->coding << 4;
- lv[1] |= bcap->radio << 5;
-
- switch (bcap->transfer) {
- case GSM_MNCC_BCAP_SPEECH:
- for (s = 0; bcap->speech_ver[s] >= 0; s++) {
- i++; /* octet 3a etc */
- lv[i] = bcap->speech_ver[s];
- if (i == 2) /* octet 3a */
- lv[i] |= bcap->speech_ctm << 5;
- }
- lv[i] |= 0x80; /* last IE of octet 3 etc */
- break;
- case GSM48_BCAP_ITCAP_UNR_DIG_INF:
- case GSM48_BCAP_ITCAP_FAX_G3:
- lv[i++] |= 0x80; /* last IE of octet 3 etc */
- /* octet 4 */
- lv[i++] = 0xb8;
- /* octet 5 */
- lv[i++] = 0x80 | ((bcap->data.rate_adaption & 3) << 3)
- | (bcap->data.sig_access & 7);
- /* octet 6 */
- lv[i++] = 0x20 | (bcap->data.async & 1);
- /* octet 6a */
- lv[i++] = (bcap->data.user_rate & 0xf) |
- (bcap->data.nr_data_bits == 8 ? 0x10 : 0x00) |
- (bcap->data.nr_stop_bits == 2 ? 0x40 : 0x00);
- /* octet 6b */
- lv[i++] = (bcap->data.parity & 7) |
- ((bcap->data.interm_rate & 3) << 5);
- /* octet 6c */
- lv[i] = 0x80 | (bcap->data.modem_type & 0x1f);
- break;
- default:
- return -EINVAL;
- }
-
- lv[0] = i;
- if (lv_only)
- msgb_lv_put(msg, lv[0], lv+1);
- else
- msgb_tlv_put(msg, GSM48_IE_BEARER_CAP, lv[0], lv+1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.5a: decode 'call control cap' */
-int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
-
- if (in_len < 1)
- return -EINVAL;
-
- /* octet 3 */
- ccap->dtmf = lv[1] & 0x01;
- ccap->pcp = (lv[1] & 0x02) >> 1;
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.5a: encode 'call control cap' */
-int gsm48_encode_cccap(struct msgb *msg,
- const struct gsm_mncc_cccap *ccap)
-{
- uint8_t lv[2];
-
- lv[0] = 1;
- lv[1] = 0;
- if (ccap->dtmf)
- lv [1] |= 0x01;
- if (ccap->pcp)
- lv [1] |= 0x02;
-
- msgb_tlv_put(msg, GSM48_IE_CC_CAP, lv[0], lv+1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.7: decode 'called party BCD number' */
-int gsm48_decode_called(struct gsm_mncc_number *called,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
-
- if (in_len < 1)
- return -EINVAL;
-
- /* octet 3 */
- called->plan = lv[1] & 0x0f;
- called->type = (lv[1] & 0x70) >> 4;
-
- /* octet 4..N */
- gsm48_decode_bcd_number(called->number, sizeof(called->number), lv, 1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.7: encode 'called party BCD number' */
-int gsm48_encode_called(struct msgb *msg,
- const struct gsm_mncc_number *called)
-{
- uint8_t lv[18];
- int ret;
-
- /* octet 3 */
- lv[1] = 0x80; /* no extension */
- lv[1] |= called->plan;
- lv[1] |= called->type << 4;
-
- /* octet 4..N, octet 2 */
- ret = gsm48_encode_bcd_number(lv, sizeof(lv), 1, called->number);
- if (ret < 0)
- return ret;
-
- msgb_tlv_put(msg, GSM48_IE_CALLED_BCD, lv[0], lv+1);
-
- return 0;
-}
-
-/* decode callerid of various IEs */
-int gsm48_decode_callerid(struct gsm_mncc_number *callerid,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
- int i = 1;
-
- if (in_len < 1)
- return -EINVAL;
-
- /* octet 3 */
- callerid->plan = lv[1] & 0x0f;
- callerid->type = (lv[1] & 0x70) >> 4;
-
- /* octet 3a */
- if (!(lv[1] & 0x80)) {
- callerid->screen = lv[2] & 0x03;
- callerid->present = (lv[2] & 0x60) >> 5;
- i = 2;
- }
-
- /* octet 4..N */
- gsm48_decode_bcd_number(callerid->number, sizeof(callerid->number), lv, i);
-
- return 0;
-}
-
-/* encode callerid of various IEs */
-int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len,
- const struct gsm_mncc_number *callerid)
-{
- uint8_t lv[max_len - 1];
- int h_len = 1;
- int ret;
-
- /* octet 3 */
- lv[1] = callerid->plan;
- lv[1] |= callerid->type << 4;
-
- if (callerid->present || callerid->screen) {
- /* octet 3a */
- lv[2] = callerid->screen;
- lv[2] |= callerid->present << 5;
- lv[2] |= 0x80;
- h_len++;
- } else
- lv[1] |= 0x80;
-
- /* octet 4..N, octet 2 */
- ret = gsm48_encode_bcd_number(lv, sizeof(lv), h_len, callerid->number);
- if (ret < 0)
- return ret;
-
- msgb_tlv_put(msg, ie, lv[0], lv+1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.11: decode 'cause' */
-int gsm48_decode_cause(struct gsm_mncc_cause *cause,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
- int i;
-
- if (in_len < 2)
- return -EINVAL;
-
- cause->diag_len = 0;
-
- /* octet 3 */
- cause->location = lv[1] & 0x0f;
- cause->coding = (lv[1] & 0x60) >> 5;
-
- i = 1;
- if (!(lv[i] & 0x80)) {
- i++; /* octet 3a */
- if (in_len < i+1)
- return 0;
- cause->rec = 1;
- cause->rec_val = lv[i] & 0x7f;
- }
- i++;
-
- /* octet 4 */
- cause->value = lv[i] & 0x7f;
- i++;
-
- if (in_len < i) /* no diag */
- return 0;
-
- if (in_len - (i-1) > 32) /* maximum 32 octets */
- return 0;
-
- /* octet 5-N */
- memcpy(cause->diag, lv + i, in_len - (i-1));
- cause->diag_len = in_len - (i-1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.11: encode 'cause' */
-int gsm48_encode_cause(struct msgb *msg, int lv_only,
- const struct gsm_mncc_cause *cause)
-{
- uint8_t lv[32+4];
- int i;
-
- if (cause->diag_len > 32)
- return -EINVAL;
-
- /* octet 3 */
- lv[1] = cause->location;
- lv[1] |= cause->coding << 5;
-
- i = 1;
- if (cause->rec) {
- i++; /* octet 3a */
- lv[i] = cause->rec_val;
- }
- lv[i] |= 0x80; /* end of octet 3 */
-
- /* octet 4 */
- i++;
- lv[i] = 0x80 | cause->value;
-
- /* octet 5-N */
- if (cause->diag_len) {
- memcpy(lv + i, cause->diag, cause->diag_len);
- i += cause->diag_len;
- }
-
- lv[0] = i;
- if (lv_only)
- msgb_lv_put(msg, lv[0], lv+1);
- else
- msgb_tlv_put(msg, GSM48_IE_CAUSE, lv[0], lv+1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.9: decode 'calling number' */
-int gsm48_decode_calling(struct gsm_mncc_number *calling,
- const uint8_t *lv)
-{
- return gsm48_decode_callerid(calling, lv);
-}
-
-/* TS 04.08 10.5.4.9: encode 'calling number' */
-int gsm48_encode_calling(struct msgb *msg,
- const struct gsm_mncc_number *calling)
-{
- return gsm48_encode_callerid(msg, GSM48_IE_CALLING_BCD, 14, calling);
-}
-
-/* TS 04.08 10.5.4.13: decode 'connected number' */
-int gsm48_decode_connected(struct gsm_mncc_number *connected,
- const uint8_t *lv)
-{
- return gsm48_decode_callerid(connected, lv);
-}
-
-/* TS 04.08 10.5.4.13: encode 'connected number' */
-int gsm48_encode_connected(struct msgb *msg,
- const struct gsm_mncc_number *connected)
-{
- return gsm48_encode_callerid(msg, GSM48_IE_CONN_BCD, 14, connected);
-}
-
-/* TS 04.08 10.5.4.21b: decode 'redirecting number' */
-int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting,
- const uint8_t *lv)
-{
- return gsm48_decode_callerid(redirecting, lv);
-}
-
-/* TS 04.08 10.5.4.21b: encode 'redirecting number' */
-int gsm48_encode_redirecting(struct msgb *msg,
- const struct gsm_mncc_number *redirecting)
-{
- return gsm48_encode_callerid(msg, GSM48_IE_REDIR_BCD, 19, redirecting);
-}
-
-/* TS 04.08 10.5.4.15: decode 'facility' */
-int gsm48_decode_facility(struct gsm_mncc_facility *facility,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
-
- if (in_len < 1)
- return -EINVAL;
-
- if (in_len > sizeof(facility->info))
- return -EINVAL;
-
- memcpy(facility->info, lv+1, in_len);
- facility->len = in_len;
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.15: encode 'facility' */
-int gsm48_encode_facility(struct msgb *msg, int lv_only,
- const struct gsm_mncc_facility *facility)
-{
- uint8_t lv[GSM_MAX_FACILITY + 1];
-
- if (facility->len < 1 || facility->len > GSM_MAX_FACILITY)
- return -EINVAL;
-
- memcpy(lv+1, facility->info, facility->len);
- lv[0] = facility->len;
- if (lv_only)
- msgb_lv_put(msg, lv[0], lv+1);
- else
- msgb_tlv_put(msg, GSM48_IE_FACILITY, lv[0], lv+1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.20: decode 'notify' */
-int gsm48_decode_notify(int *notify, const uint8_t *v)
-{
- *notify = v[0] & 0x7f;
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.20: encode 'notify' */
-int gsm48_encode_notify(struct msgb *msg, int notify)
-{
- msgb_v_put(msg, notify | 0x80);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.23: decode 'signal' */
-int gsm48_decode_signal(int *signal, const uint8_t *v)
-{
- *signal = v[0];
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.23: encode 'signal' */
-int gsm48_encode_signal(struct msgb *msg, int signal)
-{
- msgb_tv_put(msg, GSM48_IE_SIGNAL, signal);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.17: decode 'keypad' */
-int gsm48_decode_keypad(int *keypad, const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
-
- if (in_len < 1)
- return -EINVAL;
-
- *keypad = lv[1] & 0x7f;
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.17: encode 'keypad' */
-int gsm48_encode_keypad(struct msgb *msg, int keypad)
-{
- msgb_tv_put(msg, GSM48_IE_KPD_FACILITY, keypad);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.21: decode 'progress' */
-int gsm48_decode_progress(struct gsm_mncc_progress *progress,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
-
- if (in_len < 2)
- return -EINVAL;
-
- progress->coding = (lv[1] & 0x60) >> 5;
- progress->location = lv[1] & 0x0f;
- progress->descr = lv[2] & 0x7f;
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.21: encode 'progress' */
-int gsm48_encode_progress(struct msgb *msg, int lv_only,
- const struct gsm_mncc_progress *p)
-{
- uint8_t lv[3];
-
- lv[0] = 2;
- lv[1] = 0x80 | ((p->coding & 0x3) << 5) | (p->location & 0xf);
- lv[2] = 0x80 | (p->descr & 0x7f);
- if (lv_only)
- msgb_lv_put(msg, lv[0], lv+1);
- else
- msgb_tlv_put(msg, GSM48_IE_PROGR_IND, lv[0], lv+1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.25: decode 'user-user' */
-int gsm48_decode_useruser(struct gsm_mncc_useruser *uu,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
- char *info = uu->info;
- int info_len = sizeof(uu->info);
- int i;
-
- if (in_len < 1)
- return -EINVAL;
-
- uu->proto = lv[1];
-
- for (i = 2; i <= in_len; i++) {
- info_len--;
- if (info_len <= 1)
- break;
- *info++ = lv[i];
- }
- if (info_len >= 1)
- *info++ = '\0';
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.25: encode 'useruser' */
-int gsm48_encode_useruser(struct msgb *msg, int lv_only,
- const struct gsm_mncc_useruser *uu)
-{
- uint8_t lv[GSM_MAX_USERUSER + 2];
-
- if (strlen(uu->info) > GSM_MAX_USERUSER)
- return -EINVAL;
-
- lv[0] = 1 + strlen(uu->info);
- lv[1] = uu->proto;
- memcpy(lv + 2, uu->info, strlen(uu->info));
- if (lv_only)
- msgb_lv_put(msg, lv[0], lv+1);
- else
- msgb_tlv_put(msg, GSM48_IE_USER_USER, lv[0], lv+1);
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.24: decode 'ss version' */
-int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
-
- if (in_len < 1 || in_len < sizeof(ssv->info))
- return -EINVAL;
-
- memcpy(ssv->info, lv + 1, in_len);
- ssv->len = in_len;
-
- return 0;
-}
-
-/* TS 04.08 10.5.4.24: encode 'ss version' */
-int gsm48_encode_ssversion(struct msgb *msg,
- const struct gsm_mncc_ssversion *ssv)
-{
- uint8_t lv[GSM_MAX_SSVERSION + 1];
-
- if (ssv->len > GSM_MAX_SSVERSION)
- return -EINVAL;
-
- lv[0] = ssv->len;
- memcpy(lv + 1, ssv->info, ssv->len);
- msgb_tlv_put(msg, GSM48_IE_SS_VERS, lv[0], lv+1);
-
- return 0;
-}
-
-/* decode 'more data' does not require a function, because it has no value */
-
-/* TS 04.08 10.5.4.19: encode 'more data' */
-int gsm48_encode_more(struct msgb *msg)
-{
- uint8_t *ie;
-
- ie = msgb_put(msg, 1);
- ie[0] = GSM48_IE_MORE_DATA;
-
- return 0;
-}
-
-static int32_t smod(int32_t n, int32_t m)
-{
- int32_t res;
-
- res = n % m;
-
- if (res <= 0)
- res += m;
-
- return res;
-}
-
-/* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */
-int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd,
- uint8_t len, uint8_t mask, uint8_t frqt)
-{
- int i;
-
- /* NOTES:
- *
- * The Range format uses "SMOD" computation.
- * e.g. "n SMOD m" equals "((n - 1) % m) + 1"
- * A cascade of multiple SMOD computations is simpified:
- * "(n SMOD m) SMOD o" equals "(((n - 1) % m) % o) + 1"
- *
- * The Range format uses 16 octets of data in SYSTEM INFORMATION.
- * When used in dedicated messages, the length can be less.
- * In this case the ranges are decoded for all frequencies that
- * fit in the block of given length.
- */
-
- /* tabula rasa */
- for (i = 0; i < 1024; i++)
- f[i].mask &= ~frqt;
-
- /* 00..XXX. */
- if ((cd[0] & 0xc0 & mask) == 0x00) {
- /* Bit map 0 format */
- if (len < 16)
- return -EINVAL;
- for (i = 1; i <= 124; i++)
- if ((cd[15 - ((i-1) >> 3)] & (1 << ((i-1) & 7))))
- f[i].mask |= frqt;
-
- return 0;
- }
-
- /* 10..0XX. */
- if ((cd[0] & 0xc8 & mask) == 0x80) {
- /* Range 1024 format */
- uint16_t w[17]; /* 1..16 */
- struct gsm48_range_1024 *r = (struct gsm48_range_1024 *)cd;
-
- if (len < 2)
- return -EINVAL;
- memset(w, 0, sizeof(w));
- if (r->f0)
- f[0].mask |= frqt;
- w[1] = (r->w1_hi << 8) | r->w1_lo;
- if (len >= 4)
- w[2] = (r->w2_hi << 1) | r->w2_lo;
- if (len >= 5)
- w[3] = (r->w3_hi << 2) | r->w3_lo;
- if (len >= 6)
- w[4] = (r->w4_hi << 2) | r->w4_lo;
- if (len >= 7)
- w[5] = (r->w5_hi << 2) | r->w5_lo;
- if (len >= 8)
- w[6] = (r->w6_hi << 2) | r->w6_lo;
- if (len >= 9)
- w[7] = (r->w7_hi << 2) | r->w7_lo;
- if (len >= 10)
- w[8] = (r->w8_hi << 1) | r->w8_lo;
- if (len >= 10)
- w[9] = r->w9;
- if (len >= 11)
- w[10] = r->w10;
- if (len >= 12)
- w[11] = (r->w11_hi << 6) | r->w11_lo;
- if (len >= 13)
- w[12] = (r->w12_hi << 5) | r->w12_lo;
- if (len >= 14)
- w[13] = (r->w13_hi << 4) | r->w13_lo;
- if (len >= 15)
- w[14] = (r->w14_hi << 3) | r->w14_lo;
- if (len >= 16)
- w[15] = (r->w15_hi << 2) | r->w15_lo;
- if (len >= 16)
- w[16] = r->w16;
- if (w[1])
- f[w[1]].mask |= frqt;
- if (w[2])
- f[smod(w[1] - 512 + w[2], 1023)].mask |= frqt;
- if (w[3])
- f[smod(w[1] + w[3], 1023)].mask |= frqt;
- if (w[4])
- f[smod(w[1] - 512 + smod(w[2] - 256 + w[4], 511), 1023)].mask |= frqt;
- if (w[5])
- f[smod(w[1] + smod(w[3] - 256 + w[5], 511), 1023)].mask |= frqt;
- if (w[6])
- f[smod(w[1] - 512 + smod(w[2] + w[6], 511), 1023)].mask |= frqt;
- if (w[7])
- f[smod(w[1] + smod(w[3] + w[7], 511), 1023)].mask |= frqt;
- if (w[8])
- f[smod(w[1] - 512 + smod(w[2] - 256 + smod(w[4] - 128 + w[8] , 255), 511), 1023)].mask |= frqt;
- if (w[9])
- f[smod(w[1] + smod(w[3] - 256 + smod(w[5] - 128 + w[9] , 255), 511), 1023)].mask |= frqt;
- if (w[10])
- f[smod(w[1] - 512 + smod(w[2] + smod(w[6] - 128 + w[10], 255), 511), 1023)].mask |= frqt;
- if (w[11])
- f[smod(w[1] + smod(w[3] + smod(w[7] - 128 + w[11], 255), 511), 1023)].mask |= frqt;
- if (w[12])
- f[smod(w[1] - 512 + smod(w[2] - 256 + smod(w[4] + w[12], 255), 511), 1023)].mask |= frqt;
- if (w[13])
- f[smod(w[1] + smod(w[3] - 256 + smod(w[5] + w[13], 255), 511), 1023)].mask |= frqt;
- if (w[14])
- f[smod(w[1] - 512 + smod(w[2] + smod(w[6] + w[14], 255), 511), 1023)].mask |= frqt;
- if (w[15])
- f[smod(w[1] + smod(w[3] + smod(w[7] + w[15], 255), 511), 1023)].mask |= frqt;
- if (w[16])
- f[smod(w[1] - 512 + smod(w[2] - 256 + smod(w[4] - 128 + smod(w[8] - 64 + w[16], 127), 255), 511), 1023)].mask |= frqt;
-
- return 0;
- }
- /* 10..100. */
- if ((cd[0] & 0xce & mask) == 0x88) {
- /* Range 512 format */
- uint16_t w[18]; /* 1..17 */
- struct gsm48_range_512 *r = (struct gsm48_range_512 *)cd;
-
- if (len < 4)
- return -EINVAL;
- memset(w, 0, sizeof(w));
- w[0] = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
- w[1] = (r->w1_hi << 2) | r->w1_lo;
- if (len >= 5)
- w[2] = (r->w2_hi << 2) | r->w2_lo;
- if (len >= 6)
- w[3] = (r->w3_hi << 2) | r->w3_lo;
- if (len >= 7)
- w[4] = (r->w4_hi << 1) | r->w4_lo;
- if (len >= 7)
- w[5] = r->w5;
- if (len >= 8)
- w[6] = r->w6;
- if (len >= 9)
- w[7] = (r->w7_hi << 6) | r->w7_lo;
- if (len >= 10)
- w[8] = (r->w8_hi << 4) | r->w8_lo;
- if (len >= 11)
- w[9] = (r->w9_hi << 2) | r->w9_lo;
- if (len >= 11)
- w[10] = r->w10;
- if (len >= 12)
- w[11] = r->w11;
- if (len >= 13)
- w[12] = (r->w12_hi << 4) | r->w12_lo;
- if (len >= 14)
- w[13] = (r->w13_hi << 2) | r->w13_lo;
- if (len >= 14)
- w[14] = r->w14;
- if (len >= 15)
- w[15] = r->w15;
- if (len >= 16)
- w[16] = (r->w16_hi << 3) | r->w16_lo;
- if (len >= 16)
- w[17] = r->w17;
- f[w[0]].mask |= frqt;
- if (w[1])
- f[(w[0] + w[1]) % 1024].mask |= frqt;
- if (w[2])
- f[(w[0] + smod(w[1] - 256 + w[2], 511)) % 1024].mask |= frqt;
- if (w[3])
- f[(w[0] + smod(w[1] + w[3], 511)) % 1024].mask |= frqt;
- if (w[4])
- f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + w[4], 255), 511)) % 1024].mask |= frqt;
- if (w[5])
- f[(w[0] + smod(w[1] + smod(w[3] - 128 + w[5], 255), 511)) % 1024].mask |= frqt;
- if (w[6])
- f[(w[0] + smod(w[1] - 256 + smod(w[2] + w[6], 255), 511)) % 1024].mask |= frqt;
- if (w[7])
- f[(w[0] + smod(w[1] + smod(w[3] + w[7], 255), 511)) % 1024].mask |= frqt;
- if (w[8])
- f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + smod(w[4] - 64 + w[8] , 127), 255), 511)) % 1024].mask |= frqt;
- if (w[9])
- f[(w[0] + smod(w[1] + smod(w[3] - 128 + smod(w[5] - 64 + w[9] , 127), 255), 511)) % 1024].mask |= frqt;
- if (w[10])
- f[(w[0] + smod(w[1] - 256 + smod(w[2] + smod(w[6] - 64 + w[10], 127), 255), 511)) % 1024].mask |= frqt;
- if (w[11])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 64 + w[11], 127), 255), 511)) % 1024].mask |= frqt;
- if (w[12])
- f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + smod(w[4] + w[12], 127), 255), 511)) % 1024].mask |= frqt;
- if (w[13])
- f[(w[0] + smod(w[1] + smod(w[3] - 128 + smod(w[5] + w[13], 127), 255), 511)) % 1024].mask |= frqt;
- if (w[14])
- f[(w[0] + smod(w[1] - 256 + smod(w[2] + smod(w[6] + w[14], 127), 255), 511)) % 1024].mask |= frqt;
- if (w[15])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + w[15], 127), 255), 511)) % 1024].mask |= frqt;
- if (w[16])
- f[(w[0] + smod(w[1] - 256 + smod(w[2] - 128 + smod(w[4] - 64 + smod(w[8] - 32 + w[16], 63), 127), 255), 511)) % 1024].mask |= frqt;
- if (w[17])
- f[(w[0] + smod(w[1] + smod(w[3] - 128 + smod(w[5] - 64 + smod(w[9] - 32 + w[17], 63), 127), 255), 511)) % 1024].mask |= frqt;
-
- return 0;
- }
- /* 10..101. */
- if ((cd[0] & 0xce & mask) == 0x8a) {
- /* Range 256 format */
- uint16_t w[22]; /* 1..21 */
- struct gsm48_range_256 *r = (struct gsm48_range_256 *)cd;
-
- if (len < 4)
- return -EINVAL;
- memset(w, 0, sizeof(w));
- w[0] = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
- w[1] = (r->w1_hi << 1) | r->w1_lo;
- if (len >= 4)
- w[2] = r->w2;
- if (len >= 5)
- w[3] = r->w3;
- if (len >= 6)
- w[4] = (r->w4_hi << 5) | r->w4_lo;
- if (len >= 7)
- w[5] = (r->w5_hi << 3) | r->w5_lo;
- if (len >= 8)
- w[6] = (r->w6_hi << 1) | r->w6_lo;
- if (len >= 8)
- w[7] = r->w7;
- if (len >= 9)
- w[8] = (r->w8_hi << 4) | r->w8_lo;
- if (len >= 10)
- w[9] = (r->w9_hi << 1) | r->w9_lo;
- if (len >= 10)
- w[10] = r->w10;
- if (len >= 11)
- w[11] = (r->w11_hi << 3) | r->w11_lo;
- if (len >= 11)
- w[12] = r->w12;
- if (len >= 12)
- w[13] = r->w13;
- if (len >= 13)
- w[14] = r->w15;
- if (len >= 13)
- w[15] = (r->w14_hi << 2) | r->w14_lo;
- if (len >= 14)
- w[16] = (r->w16_hi << 3) | r->w16_lo;
- if (len >= 14)
- w[17] = r->w17;
- if (len >= 15)
- w[18] = r->w19;
- if (len >= 15)
- w[19] = (r->w18_hi << 3) | r->w18_lo;
- if (len >= 16)
- w[20] = (r->w20_hi << 3) | r->w20_lo;
- if (len >= 16)
- w[21] = r->w21;
- f[w[0]].mask |= frqt;
- if (w[1])
- f[(w[0] + w[1]) % 1024].mask |= frqt;
- if (w[2])
- f[(w[0] + smod(w[1] - 128 + w[2], 255)) % 1024].mask |= frqt;
- if (w[3])
- f[(w[0] + smod(w[1] + w[3], 255)) % 1024].mask |= frqt;
- if (w[4])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + w[4], 127), 255)) % 1024].mask |= frqt;
- if (w[5])
- f[(w[0] + smod(w[1] + smod(w[3] - 64 + w[5], 127), 255)) % 1024].mask |= frqt;
- if (w[6])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] + w[6], 127), 255)) % 1024].mask |= frqt;
- if (w[7])
- f[(w[0] + smod(w[1] + smod(w[3] + w[7], 127), 255)) % 1024].mask |= frqt;
- if (w[8])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] - 32 + w[8] , 63), 127), 255)) % 1024].mask |= frqt;
- if (w[9])
- f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] - 32 + w[9] , 63), 127), 255)) % 1024].mask |= frqt;
- if (w[10])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] + smod(w[6] - 32 + w[10], 63), 127), 255)) % 1024].mask |= frqt;
- if (w[11])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 32 + w[11], 63), 127), 255)) % 1024].mask |= frqt;
- if (w[12])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] + w[12], 63), 127), 255)) % 1024].mask |= frqt;
- if (w[13])
- f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] + w[13], 63), 127), 255)) % 1024].mask |= frqt;
- if (w[14])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] + smod(w[6] + w[14], 63), 127), 255)) % 1024].mask |= frqt;
- if (w[15])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + w[15], 63), 127), 255)) % 1024].mask |= frqt;
- if (w[16])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] - 32 + smod(w[8] - 16 + w[16], 31), 63), 127), 255)) % 1024].mask |= frqt;
- if (w[17])
- f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] - 32 + smod(w[9] - 16 + w[17], 31), 63), 127), 255)) % 1024].mask |= frqt;
- if (w[18])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] + smod(w[6] - 32 + smod(w[10] - 16 + w[18], 31), 63), 127), 255)) % 1024].mask |= frqt;
- if (w[19])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 32 + smod(w[11] - 16 + w[19], 31), 63), 127), 255)) % 1024].mask |= frqt;
- if (w[20])
- f[(w[0] + smod(w[1] - 128 + smod(w[2] - 64 + smod(w[4] + smod(w[12] - 16 + w[20], 31), 63), 127), 255)) % 1024].mask |= frqt;
- if (w[21])
- f[(w[0] + smod(w[1] + smod(w[3] - 64 + smod(w[5] + smod(w[13] - 16 + w[21], 31), 63), 127), 255)) % 1024].mask |= frqt;
-
- return 0;
- }
- /* 10..110. */
- if ((cd[0] & 0xce & mask) == 0x8c) {
- /* Range 128 format */
- uint16_t w[29]; /* 1..28 */
- struct gsm48_range_128 *r = (struct gsm48_range_128 *)cd;
-
- if (len < 3)
- return -EINVAL;
- memset(w, 0, sizeof(w));
- w[0] = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
- w[1] = r->w1;
- if (len >= 4)
- w[2] = r->w2;
- if (len >= 5)
- w[3] = (r->w3_hi << 4) | r->w3_lo;
- if (len >= 6)
- w[4] = (r->w4_hi << 1) | r->w4_lo;
- if (len >= 6)
- w[5] = r->w5;
- if (len >= 7)
- w[6] = (r->w6_hi << 3) | r->w6_lo;
- if (len >= 7)
- w[7] = r->w7;
- if (len >= 8)
- w[8] = r->w8;
- if (len >= 8)
- w[9] = r->w9;
- if (len >= 9)
- w[10] = r->w10;
- if (len >= 9)
- w[11] = r->w11;
- if (len >= 10)
- w[12] = r->w12;
- if (len >= 10)
- w[13] = r->w13;
- if (len >= 11)
- w[14] = r->w14;
- if (len >= 11)
- w[15] = r->w15;
- if (len >= 12)
- w[16] = r->w16;
- if (len >= 12)
- w[17] = r->w17;
- if (len >= 13)
- w[18] = (r->w18_hi << 1) | r->w18_lo;
- if (len >= 13)
- w[19] = r->w19;
- if (len >= 13)
- w[20] = r->w20;
- if (len >= 14)
- w[21] = (r->w21_hi << 2) | r->w21_lo;
- if (len >= 14)
- w[22] = r->w22;
- if (len >= 14)
- w[23] = r->w23;
- if (len >= 15)
- w[24] = r->w24;
- if (len >= 15)
- w[25] = r->w25;
- if (len >= 16)
- w[26] = (r->w26_hi << 1) | r->w26_lo;
- if (len >= 16)
- w[27] = r->w27;
- if (len >= 16)
- w[28] = r->w28;
- f[w[0]].mask |= frqt;
- if (w[1])
- f[(w[0] + w[1]) % 1024].mask |= frqt;
- if (w[2])
- f[(w[0] + smod(w[1] - 64 + w[2], 127)) % 1024].mask |= frqt;
- if (w[3])
- f[(w[0] + smod(w[1] + w[3], 127)) % 1024].mask |= frqt;
- if (w[4])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + w[4], 63), 127)) % 1024].mask |= frqt;
- if (w[5])
- f[(w[0] + smod(w[1] + smod(w[3] - 32 + w[5], 63), 127)) % 1024].mask |= frqt;
- if (w[6])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] + w[6], 63), 127)) % 1024].mask |= frqt;
- if (w[7])
- f[(w[0] + smod(w[1] + smod(w[3] + w[7], 63), 127)) % 1024].mask |= frqt;
- if (w[8])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] - 16 + w[8] , 31), 63), 127)) % 1024].mask |= frqt;
- if (w[9])
- f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] - 16 + w[9] , 31), 63), 127)) % 1024].mask |= frqt;
- if (w[10])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] - 16 + w[10], 31), 63), 127)) % 1024].mask |= frqt;
- if (w[11])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 16 + w[11], 31), 63), 127)) % 1024].mask |= frqt;
- if (w[12])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] + w[12], 31), 63), 127)) % 1024].mask |= frqt;
- if (w[13])
- f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] + w[13], 31), 63), 127)) % 1024].mask |= frqt;
- if (w[14])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] + w[14], 31), 63), 127)) % 1024].mask |= frqt;
- if (w[15])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + w[15], 31), 63), 127)) % 1024].mask |= frqt;
- if (w[16])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] - 16 + smod(w[8] - 8 + w[16], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[17])
- f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] - 16 + smod(w[9] - 8 + w[17], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[18])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] - 16 + smod(w[10] - 8 + w[18], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[19])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 16 + smod(w[11] - 8 + w[19], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[20])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] + smod(w[12] - 8 + w[20], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[21])
- f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] + smod(w[13] - 8 + w[21], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[22])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] + smod(w[14] - 8 + w[22], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[23])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] + smod(w[15] - 8 + w[23], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[24])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] - 16 + smod(w[8] + w[24], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[25])
- f[(w[0] + smod(w[1] + smod(w[3] - 32 + smod(w[5] - 16 + smod(w[9] + w[25], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[26])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] + smod(w[6] - 16 + smod(w[10] + w[26], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[27])
- f[(w[0] + smod(w[1] + smod(w[3] + smod(w[7] - 16 + smod(w[11] + w[27], 15), 31), 63), 127)) % 1024].mask |= frqt;
- if (w[28])
- f[(w[0] + smod(w[1] - 64 + smod(w[2] - 32 + smod(w[4] + smod(w[12] + w[28], 15), 31), 63), 127)) % 1024].mask |= frqt;
-
- return 0;
- }
- /* 10..111. */
- if ((cd[0] & 0xce & mask) == 0x8e) {
- /* Variable bitmap format (can be any length >= 3) */
- uint16_t orig = 0;
- struct gsm48_var_bit *r = (struct gsm48_var_bit *)cd;
-
- if (len < 3)
- return -EINVAL;
- orig = (r->orig_arfcn_hi << 9) | (r->orig_arfcn_mid << 1) | r->orig_arfcn_lo;
- f[orig].mask |= frqt;
- for (i = 1; 2 + (i >> 3) < len; i++)
- if ((cd[2 + (i >> 3)] & (0x80 >> (i & 7))))
- f[(orig + i) % 1024].mask |= frqt;
-
- return 0;
- }
-
- return 0;
-}
diff --git a/src/shared/libosmocore/src/gsm/gsm_utils.c b/src/shared/libosmocore/src/gsm/gsm_utils.c
deleted file mode 100644
index 8b1fae08..00000000
--- a/src/shared/libosmocore/src/gsm/gsm_utils.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
- * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010-2012 by Nico Golde <nico@ngolde.de>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/*! \mainpage libosmogsm Documentation
- *
- * \section sec_intro Introduction
- * This library is a collection of common code used in various
- * GSM related sub-projects inside the Osmocom family of projects. It
- * includes A5/1 and A5/2 ciphers, COMP128v1, a LAPDm implementation,
- * a GSM TLV parser, SMS utility routines as well as
- * protocol definitions for a series of protocols:
- * * Um L2 (04.06)
- * * Um L3 (04.08)
- * * A-bis RSL (08.58)
- * * A-bis OML (08.59, 12.21)
- * * A (08.08)
- * \n\n
- * Please note that C language projects inside Osmocom are typically
- * single-threaded event-loop state machine designs. As such,
- * routines in libosmogsm are not thread-safe. If you must use them in
- * a multi-threaded context, you have to add your own locking.
- *
- * \section sec_copyright Copyright and License
- * Copyright © 2008-2011 - Harald Welte, Holger Freyther and contributors\n
- * All rights reserved. \n\n
- * The source code of libosmogsm is licensed under the terms of the GNU
- * General Public License as published by the Free Software Foundation;
- * either version 2 of the License, or (at your option) any later
- * version.\n
- * See <http://www.gnu.org/licenses/> or COPYING included in the source
- * code package istelf.\n
- * The information detailed here is provided AS IS with NO WARRANTY OF
- * ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.
- * \n\n
- *
- * \section sec_contact Contact and Support
- * Community-based support is available at the OpenBSC mailing list
- * <http://lists.osmocom.org/mailman/listinfo/openbsc>\n
- * Commercial support options available upon request from
- * <http://sysmocom.de/>
- */
-
-//#include <openbsc/gsm_data.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/gsm_utils.h>
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "../../config.h"
-
-/* ETSI GSM 03.38 6.2.1 and 6.2.1.1 default alphabet
- * Greek symbols at hex positions 0x10 and 0x12-0x1a
- * left out as they can't be handled with a char and
- * since most phones don't display or write these
- * characters this would only needlessly make the code
- * more complex
-*/
-static unsigned char gsm_7bit_alphabet[] = {
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0xff, 0xff, 0x0d, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x20, 0x21, 0x22, 0x23, 0x02, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
- 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
- 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
- 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x3c, 0x2f, 0x3e, 0x14, 0x11, 0xff, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
- 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x28, 0x40, 0x29, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0x0c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x40, 0xff, 0x01, 0xff,
- 0x03, 0xff, 0x7b, 0x7d, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5b, 0x7e, 0x5d, 0xff, 0x7c, 0xff, 0xff, 0xff,
- 0xff, 0x5b, 0x0e, 0x1c, 0x09, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x5d,
- 0xff, 0xff, 0xff, 0xff, 0x5c, 0xff, 0x0b, 0xff, 0xff, 0xff, 0x5e, 0xff, 0xff, 0x1e, 0x7f,
- 0xff, 0xff, 0xff, 0x7b, 0x0f, 0x1d, 0xff, 0x04, 0x05, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff,
- 0xff, 0x7d, 0x08, 0xff, 0xff, 0xff, 0x7c, 0xff, 0x0c, 0x06, 0xff, 0xff, 0x7e, 0xff, 0xff
-};
-
-/* GSM 03.38 6.2.1 Character lookup for decoding */
-static int gsm_septet_lookup(uint8_t ch)
-{
- int i = 0;
- for (; i < sizeof(gsm_7bit_alphabet); i++) {
- if (gsm_7bit_alphabet[i] == ch)
- return i;
- }
- return -1;
-}
-
-/* Compute the number of octets from the number of septets, for instance: 47 septets needs 41,125 = 42 octets */
-uint8_t gsm_get_octet_len(const uint8_t sept_len){
- int octet_len = (sept_len * 7) / 8;
- if ((sept_len * 7) % 8 != 0)
- octet_len++;
-
- return octet_len;
-}
-
-/* GSM 03.38 6.2.1 Character unpacking */
-int gsm_7bit_decode_hdr(char *text, const uint8_t *user_data, uint8_t septet_l, uint8_t ud_hdr_ind)
-{
- int i = 0;
- int shift = 0;
- uint8_t c;
- uint8_t next_is_ext = 0;
-
- /* skip the user data header */
- if (ud_hdr_ind) {
- /* get user data header length + 1 (for the 'user data header length'-field) */
- shift = ((user_data[0] + 1) * 8) / 7;
- if ((((user_data[0] + 1) * 8) % 7) != 0)
- shift++;
- septet_l = septet_l - shift;
- }
-
- for (i = 0; i < septet_l; i++) {
- c =
- ((user_data[((i + shift) * 7 + 7) >> 3] <<
- (7 - (((i + shift) * 7 + 7) & 7))) |
- (user_data[((i + shift) * 7) >> 3] >>
- (((i + shift) * 7) & 7))) & 0x7f;
-
- /* this is an extension character */
- if (next_is_ext) {
- next_is_ext = 0;
- *(text++) = gsm_7bit_alphabet[0x7f + c];
- continue;
- }
-
- if (c == 0x1b && i + 1 < septet_l) {
- next_is_ext = 1;
- } else {
- *(text++) = gsm_septet_lookup(c);
- }
- }
-
- if (ud_hdr_ind)
- i += shift;
- *text = '\0';
-
- return i;
-}
-
-int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t septet_l)
-{
- return gsm_7bit_decode_hdr(text, user_data, septet_l, 0);
-}
-
-/* GSM 03.38 6.2.1 Prepare character packing */
-int gsm_septet_encode(uint8_t *result, const char *data)
-{
- int i, y = 0;
- uint8_t ch;
- for (i = 0; i < strlen(data); i++) {
- ch = data[i];
- switch(ch){
- /* fall-through for extension characters */
- case 0x0c:
- case 0x5e:
- case 0x7b:
- case 0x7d:
- case 0x5c:
- case 0x5b:
- case 0x7e:
- case 0x5d:
- case 0x7c:
- result[y++] = 0x1b;
- default:
- result[y] = gsm_7bit_alphabet[ch];
- break;
- }
- y++;
- }
-
- return y;
-}
-
-/* 7bit to octet packing */
-int gsm_septets2octets(uint8_t *result, uint8_t *rdata, uint8_t septet_len, uint8_t padding){
- int i = 0, z = 0;
- uint8_t cb, nb;
- int shift = 0;
- uint8_t *data = calloc(septet_len + 1, sizeof(uint8_t));
-
- if (padding) {
- shift = 7 - padding;
- /* the first zero is needed for padding */
- memcpy(data + 1, rdata, septet_len);
- septet_len++;
- } else
- memcpy(data, rdata, septet_len);
-
- for (i = 0; i < septet_len; i++) {
- if (shift == 7) {
- /*
- * special end case with the. This is necessary if the
- * last septet fits into the previous octet. E.g. 48
- * non-extension characters:
- * ....ag ( a = 1100001, g = 1100111)
- * result[40] = 100001 XX, result[41] = 1100111 1 */
- if (i + 1 < septet_len) {
- shift = 0;
- continue;
- } else if (i + 1 == septet_len)
- break;
- }
-
- cb = (data[i] & 0x7f) >> shift;
- if (i + 1 < septet_len) {
- nb = (data[i + 1] & 0x7f) << (7 - shift);
- cb = cb | nb;
- }
-
- result[z++] = cb;
- shift++;
- }
-
- free(data);
-
- return z;
-}
-
-/* GSM 03.38 6.2.1 Character packing */
-int gsm_7bit_encode(uint8_t *result, const char *data)
-{
- int y = 0;
-
- /* prepare for the worst case, every character expanding to two bytes */
- uint8_t *rdata = calloc(strlen(data) * 2, sizeof(uint8_t));
- y = gsm_septet_encode(rdata, data);
- gsm_septets2octets(result, rdata, y, 0);
-
- free(rdata);
-
- /*
- * We don't care about the number of octets, because they are not
- * unique. E.g.:
- * 1.) 46 non-extension characters + 1 extension character
- * => (46 * 7 bit + (1 * (2 * 7 bit))) / 8 bit = 42 octets
- * 2.) 47 non-extension characters
- * => (47 * 7 bit) / 8 bit = 41,125 = 42 octets
- * 3.) 48 non-extension characters
- * => (48 * 7 bit) / 8 bit = 42 octects
- */
- return y;
-}
-
-/* convert power class to dBm according to GSM TS 05.05 */
-unsigned int ms_class_gmsk_dbm(enum gsm_band band, int class)
-{
- switch (band) {
- case GSM_BAND_450:
- case GSM_BAND_480:
- case GSM_BAND_750:
- case GSM_BAND_900:
- case GSM_BAND_810:
- case GSM_BAND_850:
- if (class == 1)
- return 43; /* 20W */
- if (class == 2)
- return 39; /* 8W */
- if (class == 3)
- return 37; /* 5W */
- if (class == 4)
- return 33; /* 2W */
- if (class == 5)
- return 29; /* 0.8W */
- break;
- case GSM_BAND_1800:
- if (class == 1)
- return 30; /* 1W */
- if (class == 2)
- return 24; /* 0.25W */
- if (class == 3)
- return 36; /* 4W */
- break;
- case GSM_BAND_1900:
- if (class == 1)
- return 30; /* 1W */
- if (class == 2)
- return 24; /* 0.25W */
- if (class == 3)
- return 33; /* 2W */
- break;
- }
- return -EINVAL;
-}
-
-/* determine power control level for given dBm value, as indicated
- * by the tables in chapter 4.1.1 of GSM TS 05.05 */
-int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm)
-{
- switch (band) {
- case GSM_BAND_450:
- case GSM_BAND_480:
- case GSM_BAND_750:
- case GSM_BAND_900:
- case GSM_BAND_810:
- case GSM_BAND_850:
- if (dbm >= 39)
- return 0;
- else if (dbm < 5)
- return 19;
- else {
- /* we are guaranteed to have (5 <= dbm < 39) */
- return 2 + ((39 - dbm) / 2);
- }
- break;
- case GSM_BAND_1800:
- if (dbm >= 36)
- return 29;
- else if (dbm >= 34)
- return 30;
- else if (dbm >= 32)
- return 31;
- else if (dbm == 31)
- return 0;
- else {
- /* we are guaranteed to have (0 <= dbm < 31) */
- return (30 - dbm) / 2;
- }
- break;
- case GSM_BAND_1900:
- if (dbm >= 33)
- return 30;
- else if (dbm >= 32)
- return 31;
- else if (dbm == 31)
- return 0;
- else {
- /* we are guaranteed to have (0 <= dbm < 31) */
- return (30 - dbm) / 2;
- }
- break;
- }
- return -EINVAL;
-}
-
-int ms_pwr_dbm(enum gsm_band band, uint8_t lvl)
-{
- lvl &= 0x1f;
-
- switch (band) {
- case GSM_BAND_450:
- case GSM_BAND_480:
- case GSM_BAND_750:
- case GSM_BAND_900:
- case GSM_BAND_810:
- case GSM_BAND_850:
- if (lvl < 2)
- return 39;
- else if (lvl < 20)
- return 39 - ((lvl - 2) * 2) ;
- else
- return 5;
- break;
- case GSM_BAND_1800:
- if (lvl < 16)
- return 30 - (lvl * 2);
- else if (lvl < 29)
- return 0;
- else
- return 36 - ((lvl - 29) * 2);
- break;
- case GSM_BAND_1900:
- if (lvl < 16)
- return 30 - (lvl * 2);
- else if (lvl < 30)
- return -EINVAL;
- else
- return 33 - (lvl - 30);
- break;
- }
- return -EINVAL;
-}
-
-/* According to TS 08.05 Chapter 8.1.4 */
-int rxlev2dbm(uint8_t rxlev)
-{
- if (rxlev > 63)
- rxlev = 63;
-
- return -110 + rxlev;
-}
-
-/* According to TS 08.05 Chapter 8.1.4 */
-uint8_t dbm2rxlev(int dbm)
-{
- int rxlev = dbm + 110;
-
- if (rxlev > 63)
- rxlev = 63;
- else if (rxlev < 0)
- rxlev = 0;
-
- return rxlev;
-}
-
-const char *gsm_band_name(enum gsm_band band)
-{
- switch (band) {
- case GSM_BAND_450:
- return "GSM450";
- case GSM_BAND_480:
- return "GSM480";
- case GSM_BAND_750:
- return "GSM750";
- case GSM_BAND_810:
- return "GSM810";
- case GSM_BAND_850:
- return "GSM850";
- case GSM_BAND_900:
- return "GSM900";
- case GSM_BAND_1800:
- return "DCS1800";
- case GSM_BAND_1900:
- return "PCS1900";
- }
- return "invalid";
-}
-
-enum gsm_band gsm_band_parse(const char* mhz)
-{
- while (*mhz && !isdigit(*mhz))
- mhz++;
-
- if (*mhz == '\0')
- return -EINVAL;
-
- switch (strtol(mhz, NULL, 10)) {
- case 450:
- return GSM_BAND_450;
- case 480:
- return GSM_BAND_480;
- case 750:
- return GSM_BAND_750;
- case 810:
- return GSM_BAND_810;
- case 850:
- return GSM_BAND_850;
- case 900:
- return GSM_BAND_900;
- case 1800:
- return GSM_BAND_1800;
- case 1900:
- return GSM_BAND_1900;
- default:
- return -EINVAL;
- }
-}
-
-enum gsm_band gsm_arfcn2band(uint16_t arfcn)
-{
- int is_pcs = arfcn & ARFCN_PCS;
-
- arfcn &= ~ARFCN_FLAG_MASK;
-
- if (is_pcs)
- return GSM_BAND_1900;
- else if (arfcn <= 124)
- return GSM_BAND_900;
- else if (arfcn >= 955 && arfcn <= 1023)
- return GSM_BAND_900;
- else if (arfcn >= 128 && arfcn <= 251)
- return GSM_BAND_850;
- else if (arfcn >= 512 && arfcn <= 885)
- return GSM_BAND_1800;
- else if (arfcn >= 259 && arfcn <= 293)
- return GSM_BAND_450;
- else if (arfcn >= 306 && arfcn <= 340)
- return GSM_BAND_480;
- else if (arfcn >= 350 && arfcn <= 425)
- return GSM_BAND_810;
- else if (arfcn >= 438 && arfcn <= 511)
- return GSM_BAND_750;
- else
- return GSM_BAND_1800;
-}
-
-/* Convert an ARFCN to the frequency in MHz * 10 */
-uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink)
-{
- uint16_t freq10_ul;
- uint16_t freq10_dl;
- int is_pcs = arfcn & ARFCN_PCS;
-
- arfcn &= ~ARFCN_FLAG_MASK;
-
- if (is_pcs) {
- /* DCS 1900 */
- arfcn &= ~ARFCN_PCS;
- freq10_ul = 18502 + 2 * (arfcn-512);
- freq10_dl = freq10_ul + 800;
- } else if (arfcn <= 124) {
- /* Primary GSM + ARFCN 0 of E-GSM */
- freq10_ul = 8900 + 2 * arfcn;
- freq10_dl = freq10_ul + 450;
- } else if (arfcn >= 955 && arfcn <= 1023) {
- /* E-GSM and R-GSM */
- freq10_ul = 8900 + 2 * (arfcn - 1024);
- freq10_dl = freq10_ul + 450;
- } else if (arfcn >= 128 && arfcn <= 251) {
- /* GSM 850 */
- freq10_ul = 8242 + 2 * (arfcn - 128);
- freq10_dl = freq10_ul + 450;
- } else if (arfcn >= 512 && arfcn <= 885) {
- /* DCS 1800 */
- freq10_ul = 17102 + 2 * (arfcn - 512);
- freq10_dl = freq10_ul + 950;
- } else if (arfcn >= 259 && arfcn <= 293) {
- /* GSM 450 */
- freq10_ul = 4506 + 2 * (arfcn - 259);
- freq10_dl = freq10_ul + 100;
- } else if (arfcn >= 306 && arfcn <= 340) {
- /* GSM 480 */
- freq10_ul = 4790 + 2 * (arfcn - 306);
- freq10_dl = freq10_ul + 100;
- } else if (arfcn >= 350 && arfcn <= 425) {
- /* GSM 810 */
- freq10_ul = 8060 + 2 * (arfcn - 350);
- freq10_dl = freq10_ul + 450;
- } else if (arfcn >= 438 && arfcn <= 511) {
- /* GSM 750 */
- freq10_ul = 7472 + 2 * (arfcn - 438);
- freq10_dl = freq10_ul + 300;
- } else
- return 0xffff;
-
- if (uplink)
- return freq10_ul;
- else
- return freq10_dl;
-}
-
-void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn)
-{
- time->fn = fn;
- time->t1 = time->fn / (26*51);
- time->t2 = time->fn % 26;
- time->t3 = time->fn % 51;
- time->tc = (time->fn / 51) % 8;
-}
-
-uint32_t gsm_gsmtime2fn(struct gsm_time *time)
-{
- /* TS 05.02 Chapter 4.3.3 TDMA frame number */
- return (51 * ((time->t3 - time->t2 + 26) % 26) + time->t3 + (26 * 51 * time->t1));
-}
-
-/* TS 03.03 Chapter 2.6 */
-int gprs_tlli_type(uint32_t tlli)
-{
- if ((tlli & 0xc0000000) == 0xc0000000)
- return TLLI_LOCAL;
- else if ((tlli & 0xc0000000) == 0x80000000)
- return TLLI_FOREIGN;
- else if ((tlli & 0xf8000000) == 0x78000000)
- return TLLI_RANDOM;
- else if ((tlli & 0xf8000000) == 0x70000000)
- return TLLI_AUXILIARY;
-
- return TLLI_RESERVED;
-}
-
-uint32_t gprs_tmsi2tlli(uint32_t p_tmsi, enum gprs_tlli_type type)
-{
- uint32_t tlli;
- switch (type) {
- case TLLI_LOCAL:
- tlli = p_tmsi | 0xc0000000;
- break;
- case TLLI_FOREIGN:
- tlli = (p_tmsi & 0x3fffffff) | 0x80000000;
- break;
- default:
- tlli = 0;
- break;
- }
- return tlli;
-}
diff --git a/src/shared/libosmocore/src/gsm/lapd_core.c b/src/shared/libosmocore/src/gsm/lapd_core.c
deleted file mode 100644
index 96099edb..00000000
--- a/src/shared/libosmocore/src/gsm/lapd_core.c
+++ /dev/null
@@ -1,2169 +0,0 @@
-/* LAPD core implementation */
-
-/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010-2011 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/*! \addtogroup lapd
- * @{
- */
-
-/*! \file lapd.c */
-
-/*!
- * Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue
- *
- * RX data is stored in the rcv_buffer (pointer). If the message is complete, it
- * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is
- * received while there is an incomplete rcv_buffer, it is appended to it.
- *
- * TX data is stored in the send_queue first. When transmitting a frame,
- * the first message in the send_queue is moved to the send_buffer. There it
- * resides until all fragments are acknowledged. Fragments to be sent by I
- * frames are stored in the tx_hist buffer for resend, if required. Also the
- * current fragment is copied into the tx_queue. There it resides until it is
- * forwarded to layer 1.
- *
- * In case we have SAPI 0, we only have a window size of 1, so the unack-
- * nowledged message resides always in the send_buffer. In case of a suspend,
- * it can be written back to the first position of the send_queue.
- *
- * The layer 1 normally sends a PH-READY-TO-SEND. But because we use
- * asynchronous transfer between layer 1 and layer 2 (serial link), we must
- * send a frame before layer 1 reaches the right timeslot to send it. So we
- * move the tx_queue to layer 1 when there is not already a pending frame, and
- * wait until acknowledge after the frame has been sent. If we receive an
- * acknowledge, we can send the next frame from the buffer, if any.
- *
- * The moving of tx_queue to layer 1 may also trigger T200, if desired. Also it
- * will trigger next I frame, if possible.
- *
- * T203 is optional. It will be stated when entering MF EST state. It will also
- * be started when I or S frame is received in that state . It will be
- * restarted in the lapd_acknowledge() function, in case outstanding frames
- * will not trigger T200. It will be stoped, when T200 is started in MF EST
- * state. It will also be stoped when leaving MF EST state.
- *
- */
-
-/* Enable this to test content resolution on network side:
- * - The first SABM is received, UA is dropped.
- * - The phone repeats SABM, but it's content is wrong, so it is ignored
- * - The phone repeats SABM again, content is right, so UA is sent.
- */
-//#define TEST_CONTENT_RESOLUTION_NETWORK
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/gsm/lapd_core.h>
-
-/* TS 04.06 Table 4 / Section 3.8.1 */
-#define LAPD_U_SABM 0x7
-#define LAPD_U_SABME 0xf
-#define LAPD_U_DM 0x3
-#define LAPD_U_UI 0x0
-#define LAPD_U_DISC 0x8
-#define LAPD_U_UA 0xC
-#define LAPD_U_FRMR 0x11
-
-#define LAPD_S_RR 0x0
-#define LAPD_S_RNR 0x1
-#define LAPD_S_REJ 0x2
-
-#define CR_USER2NET_CMD 0
-#define CR_USER2NET_RESP 1
-#define CR_NET2USER_CMD 1
-#define CR_NET2USER_RESP 0
-
-#define LAPD_HEADROOM 56
-
-#define SBIT(a) (1 << a)
-#define ALL_STATES 0xffffffff
-
-static void lapd_t200_cb(void *data);
-static void lapd_t203_cb(void *data);
-static int lapd_send_i(struct lapd_msg_ctx *lctx, int line);
-static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);
-
-/* UTILITY FUNCTIONS */
-
-struct msgb *lapd_msgb_alloc(int length, const char *name)
-{
- /* adding space for padding, FIXME: add as an option */
- if (length < 21)
- length = 21;
- return msgb_alloc_headroom(length + LAPD_HEADROOM, LAPD_HEADROOM, name);
-}
-
-static inline uint8_t do_mod(uint8_t x, uint8_t m)
-{
- return x & (m - 1);
-}
-
-static inline uint8_t inc_mod(uint8_t x, uint8_t m)
-{
- return (x + 1) & (m - 1);
-}
-
-static inline uint8_t add_mod(uint8_t x, uint8_t y, uint8_t m)
-{
- return (x + y) & (m - 1);
-}
-
-static inline uint8_t sub_mod(uint8_t x, uint8_t y, uint8_t m)
-{
- return (x - y) & (m - 1); /* handle negative results correctly */
-}
-
-static void lapd_dl_flush_send(struct lapd_datalink *dl)
-{
- struct msgb *msg;
-
- /* Flush send-queue */
- while ((msg = msgb_dequeue(&dl->send_queue)))
- msgb_free(msg);
-
- /* Clear send-buffer */
- if (dl->send_buffer) {
- msgb_free(dl->send_buffer);
- dl->send_buffer = NULL;
- }
-}
-
-static void lapd_dl_flush_hist(struct lapd_datalink *dl)
-{
- unsigned int i;
-
- for (i = 0; i < dl->range_hist; i++) {
- if (dl->tx_hist[i].msg) {
- msgb_free(dl->tx_hist[i].msg);
- dl->tx_hist[i].msg = NULL;
- }
- }
-}
-
-static void lapd_dl_flush_tx(struct lapd_datalink *dl)
-{
- struct msgb *msg;
-
- while ((msg = msgb_dequeue(&dl->tx_queue)))
- msgb_free(msg);
- lapd_dl_flush_hist(dl);
-}
-
-/* Figure B.2/Q.921 */
-const char *lapd_state_names[] = {
- "LAPD_STATE_NULL",
- "LAPD_STATE_TEI_UNASS",
- "LAPD_STATE_ASS_TEI_WAIT",
- "LAPD_STATE_EST_TEI_WAIT",
- "LAPD_STATE_IDLE",
- "LAPD_STATE_SABM_SENT",
- "LAPD_STATE_DISC_SENT",
- "LAPD_STATE_MF_EST",
- "LAPD_STATE_TIMER_RECOV",
-
-};
-
-static void lapd_start_t200(struct lapd_datalink *dl)
-{
- if (osmo_timer_pending(&dl->t200))
- return;
- LOGP(DLLAPD, LOGL_INFO, "start T200\n");
- osmo_timer_schedule(&dl->t200, dl->t200_sec, dl->t200_usec);
-}
-
-static void lapd_start_t203(struct lapd_datalink *dl)
-{
- if (osmo_timer_pending(&dl->t203))
- return;
- LOGP(DLLAPD, LOGL_INFO, "start T203\n");
- osmo_timer_schedule(&dl->t203, dl->t203_sec, dl->t203_usec);
-}
-
-static void lapd_stop_t200(struct lapd_datalink *dl)
-{
- if (!osmo_timer_pending(&dl->t200))
- return;
- LOGP(DLLAPD, LOGL_INFO, "stop T200\n");
- osmo_timer_del(&dl->t200);
-}
-
-static void lapd_stop_t203(struct lapd_datalink *dl)
-{
- if (!osmo_timer_pending(&dl->t203))
- return;
- LOGP(DLLAPD, LOGL_INFO, "stop T203\n");
- osmo_timer_del(&dl->t203);
-}
-
-static void lapd_dl_newstate(struct lapd_datalink *dl, uint32_t state)
-{
- LOGP(DLLAPD, LOGL_INFO, "new state %s -> %s\n",
- lapd_state_names[dl->state], lapd_state_names[state]);
-
- if (state != LAPD_STATE_MF_EST && dl->state == LAPD_STATE_MF_EST) {
- /* stop T203 on leaving MF EST state, if running */
- lapd_stop_t203(dl);
- /* remove content res. (network side) on leaving MF EST state */
- if (dl->cont_res) {
- msgb_free(dl->cont_res);
- dl->cont_res = NULL;
- }
- }
-
- /* start T203 on entering MF EST state, if enabled */
- if ((dl->t203_sec || dl->t203_usec)
- && state == LAPD_STATE_MF_EST && dl->state != LAPD_STATE_MF_EST)
- lapd_start_t203(dl);
-
- dl->state = state;
-}
-
-static void *tall_lapd_ctx = NULL;
-
-/* init datalink instance and allocate history */
-void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range,
- int maxf)
-{
- int m;
-
- memset(dl, 0, sizeof(*dl));
- INIT_LLIST_HEAD(&dl->send_queue);
- INIT_LLIST_HEAD(&dl->tx_queue);
- dl->reestablish = 1;
- dl->n200_est_rel = 3;
- dl->n200 = 3;
- dl->t200_sec = 1;
- dl->t200_usec = 0;
- dl->t200.data = dl;
- dl->t200.cb = &lapd_t200_cb;
- dl->t203_sec = 10;
- dl->t203_usec = 0;
- dl->t203.data = dl;
- dl->t203.cb = &lapd_t203_cb;
- dl->maxf = maxf;
- if (k > v_range - 1)
- k = v_range - 1;
- dl->k = k;
- dl->v_range = v_range;
-
- /* Calculate modulo for history array:
- * - The history range must be at least k+1.
- * - The history range must be 2^x, where x is as low as possible.
- */
- k++;
- for (m = 0x80; m; m >>= 1) {
- if ((m & k)) {
- if (k > m)
- m <<= 1;
- dl->range_hist = m;
- break;
- }
- }
-
- LOGP(DLLAPD, LOGL_INFO, "Init DL layer: sequence range = %d, k = %d, "
- "history range = %d\n", dl->v_range, dl->k, dl->range_hist);
-
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
-
- if (!tall_lapd_ctx)
- tall_lapd_ctx = talloc_named_const(NULL, 1, "lapd context");
- dl->tx_hist = (struct lapd_history *) talloc_zero_array(tall_lapd_ctx,
- struct log_info, dl->range_hist);
-}
-
-/* reset to IDLE state */
-void lapd_dl_reset(struct lapd_datalink *dl)
-{
- if (dl->state == LAPD_STATE_IDLE)
- return;
- LOGP(DLLAPD, LOGL_INFO, "Resetting LAPDm instance\n");
- /* enter idle state (and remove eventual cont_res) */
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- /* flush buffer */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- /* Discard partly received L3 message */
- if (dl->rcv_buffer) {
- msgb_free(dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- }
- /* stop Timers */
- lapd_stop_t200(dl);
- lapd_stop_t203(dl);
-}
-
-/* reset and de-allocate history buffer */
-void lapd_dl_exit(struct lapd_datalink *dl)
-{
- /* free all ressources except history buffer */
- lapd_dl_reset(dl);
- /* free history buffer list */
- talloc_free(dl->tx_hist);
-}
-
-/*! \brief Set the \ref lapdm_mode of a LAPDm entity */
-int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode)
-{
- switch (mode) {
- case LAPD_MODE_USER:
- dl->cr.loc2rem.cmd = CR_USER2NET_CMD;
- dl->cr.loc2rem.resp = CR_USER2NET_RESP;
- dl->cr.rem2loc.cmd = CR_NET2USER_CMD;
- dl->cr.rem2loc.resp = CR_NET2USER_RESP;
- break;
- case LAPD_MODE_NETWORK:
- dl->cr.loc2rem.cmd = CR_NET2USER_CMD;
- dl->cr.loc2rem.resp = CR_NET2USER_RESP;
- dl->cr.rem2loc.cmd = CR_USER2NET_CMD;
- dl->cr.rem2loc.resp = CR_USER2NET_RESP;
- break;
- default:
- return -EINVAL;
- }
- dl->mode = mode;
-
- return 0;
-}
-
-/* send DL message with optional msgb */
-static int send_dl_l3(uint8_t prim, uint8_t op, struct lapd_msg_ctx *lctx,
- struct msgb *msg)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct osmo_dlsap_prim dp;
-
- osmo_prim_init(&dp.oph, 0, prim, op, msg);
- return dl->send_dlsap(&dp, lctx);
-}
-
-/* send simple DL message */
-static inline int send_dl_simple(uint8_t prim, uint8_t op,
- struct lapd_msg_ctx *lctx)
-{
- struct msgb *msg = lapd_msgb_alloc(0, "DUMMY");
-
- return send_dl_l3(prim, op, lctx, msg);
-}
-
-/* send MDL-ERROR INDICATION */
-static int mdl_error(uint8_t cause, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct osmo_dlsap_prim dp;
-
- LOGP(DLLAPD, LOGL_NOTICE, "sending MDL-ERROR-IND cause %d\n",
- cause);
- osmo_prim_init(&dp.oph, 0, PRIM_MDL_ERROR, PRIM_OP_INDICATION, NULL);
- dp.u.error_ind.cause = cause;
- return dl->send_dlsap(&dp, lctx);
-}
-
-/* send UA response */
-static int lapd_send_ua(struct lapd_msg_ctx *lctx, uint8_t len, uint8_t *data)
-{
- struct msgb *msg = lapd_msgb_alloc(len, "LAPD UA");
- struct lapd_msg_ctx nctx;
- struct lapd_datalink *dl = lctx->dl;
-
- memcpy(&nctx, lctx, sizeof(nctx));
- msg->l3h = msgb_put(msg, len);
- if (len)
- memcpy(msg->l3h, data, len);
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.resp;
- nctx.format = LAPD_FORM_U;
- nctx.s_u = LAPD_U_UA;
- /* keep nctx.p_f */
- nctx.length = len;
- nctx.more = 0;
-
- return dl->send_ph_data_req(&nctx, msg);
-}
-
-/* send DM response */
-static int lapd_send_dm(struct lapd_msg_ctx *lctx)
-{
- struct msgb *msg = lapd_msgb_alloc(0, "LAPD DM");
- struct lapd_msg_ctx nctx;
- struct lapd_datalink *dl = lctx->dl;
-
- memcpy(&nctx, lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.resp;
- nctx.format = LAPD_FORM_U;
- nctx.s_u = LAPD_U_DM;
- /* keep nctx.p_f */
- nctx.length = 0;
- nctx.more = 0;
-
- return dl->send_ph_data_req(&nctx, msg);
-}
-
-/* send RR response / command */
-static int lapd_send_rr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
-{
- struct msgb *msg = lapd_msgb_alloc(0, "LAPD RR");
- struct lapd_msg_ctx nctx;
- struct lapd_datalink *dl = lctx->dl;
-
- memcpy(&nctx, lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
- nctx.format = LAPD_FORM_S;
- nctx.s_u = LAPD_S_RR;
- nctx.p_f = f_bit;
- nctx.n_recv = dl->v_recv;
- nctx.length = 0;
- nctx.more = 0;
-
- return dl->send_ph_data_req(&nctx, msg);
-}
-
-/* send RNR response / command */
-static int lapd_send_rnr(struct lapd_msg_ctx *lctx, uint8_t f_bit, uint8_t cmd)
-{
- struct msgb *msg = lapd_msgb_alloc(0, "LAPD RNR");
- struct lapd_msg_ctx nctx;
- struct lapd_datalink *dl = lctx->dl;
-
- memcpy(&nctx, lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = (cmd) ? dl->cr.loc2rem.cmd : dl->cr.loc2rem.resp;
- nctx.format = LAPD_FORM_S;
- nctx.s_u = LAPD_S_RNR;
- nctx.p_f = f_bit;
- nctx.n_recv = dl->v_recv;
- nctx.length = 0;
- nctx.more = 0;
-
- return dl->send_ph_data_req(&nctx, msg);
-}
-
-/* send REJ response */
-static int lapd_send_rej(struct lapd_msg_ctx *lctx, uint8_t f_bit)
-{
- struct msgb *msg = lapd_msgb_alloc(0, "LAPD REJ");
- struct lapd_msg_ctx nctx;
- struct lapd_datalink *dl = lctx->dl;
-
- memcpy(&nctx, lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.resp;
- nctx.format = LAPD_FORM_S;
- nctx.s_u = LAPD_S_REJ;
- nctx.p_f = f_bit;
- nctx.n_recv = dl->v_recv;
- nctx.length = 0;
- nctx.more = 0;
-
- return dl->send_ph_data_req(&nctx, msg);
-}
-
-/* resend SABM or DISC message */
-static int lapd_send_resend(struct lapd_datalink *dl)
-{
- struct msgb *msg;
- uint8_t h = do_mod(dl->v_send, dl->range_hist);
- int length = dl->tx_hist[h].msg->len;
- struct lapd_msg_ctx nctx;
-
- /* assemble message */
- memcpy(&nctx, &dl->lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_U;
- if (dl->state == LAPD_STATE_SABM_SENT)
- nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
- else
- nctx.s_u = LAPD_U_DISC;
- nctx.p_f = 1;
- nctx.length = length;
- nctx.more = 0;
-
- /* Resend SABM/DISC from tx_hist */
- msg = lapd_msgb_alloc(length, "LAPD resend");
- msg->l3h = msgb_put(msg, length);
- if (length)
- memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
-
- return dl->send_ph_data_req(&nctx, msg);
-}
-
-/* reestablish link */
-static int lapd_reestablish(struct lapd_datalink *dl)
-{
- struct osmo_dlsap_prim dp;
- struct msgb *msg;
-
- msg = lapd_msgb_alloc(0, "DUMMY");
- osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
-
- return lapd_est_req(&dp, &dl->lctx);
-}
-
-/* Timer callback on T200 expiry */
-static void lapd_t200_cb(void *data)
-{
- struct lapd_datalink *dl = data;
-
- LOGP(DLLAPD, LOGL_INFO, "Timeout T200 (%p) state=%d\n", dl,
- (int) dl->state);
-
- switch (dl->state) {
- case LAPD_STATE_SABM_SENT:
- /* 5.4.1.3 */
- if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
- /* send RELEASE INDICATION to L3 */
- send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
- &dl->lctx);
- /* send MDL ERROR INIDCATION to L3 */
- mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
- /* flush tx and send buffers */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- /* go back to idle state */
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- /* NOTE: we must not change any other states or buffers
- * and queues, since we may reconnect after handover
- * failure. the buffered messages is replaced there */
- break;
- }
- /* retransmit SABM command */
- lapd_send_resend(dl);
- /* increment re-transmission counter */
- dl->retrans_ctr++;
- /* restart T200 (PH-READY-TO-SEND) */
- lapd_start_t200(dl);
- break;
- case LAPD_STATE_DISC_SENT:
- /* 5.4.4.3 */
- if (dl->retrans_ctr + 1 >= dl->n200_est_rel + 1) {
- /* send RELEASE INDICATION to L3 */
- send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
- /* send MDL ERROR INIDCATION to L3 */
- mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
- /* flush tx and send buffers */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- /* go back to idle state */
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- /* NOTE: we must not change any other states or buffers
- * and queues, since we may reconnect after handover
- * failure. the buffered messages is replaced there */
- break;
- }
- /* retransmit DISC command */
- lapd_send_resend(dl);
- /* increment re-transmission counter */
- dl->retrans_ctr++;
- /* restart T200 (PH-READY-TO-SEND) */
- lapd_start_t200(dl);
- break;
- case LAPD_STATE_MF_EST:
- /* 5.5.7 */
- dl->retrans_ctr = 0;
- lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
- /* fall through */
- case LAPD_STATE_TIMER_RECOV:
- dl->retrans_ctr++;
- if (dl->retrans_ctr < dl->n200) {
- uint8_t vs = sub_mod(dl->v_send, 1, dl->v_range);
- uint8_t h = do_mod(vs, dl->range_hist);
- /* retransmit I frame (V_s-1) with P=1, if any */
- if (dl->tx_hist[h].msg) {
- struct msgb *msg;
- int length = dl->tx_hist[h].msg->len;
- struct lapd_msg_ctx nctx;
-
- LOGP(DLLAPD, LOGL_INFO, "retransmit last frame"
- " V(S)=%d\n", vs);
- /* Create I frame (segment) from tx_hist */
- memcpy(&nctx, &dl->lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_I;
- nctx.p_f = 1;
- nctx.n_send = vs;
- nctx.n_recv = dl->v_recv;
- nctx.length = length;
- nctx.more = dl->tx_hist[h].more;
- msg = lapd_msgb_alloc(length, "LAPD I resend");
- msg->l3h = msgb_put(msg, length);
- memcpy(msg->l3h, dl->tx_hist[h].msg->data,
- length);
- dl->send_ph_data_req(&nctx, msg);
- } else {
- /* OR send appropriate supervision frame with P=1 */
- if (!dl->own_busy && !dl->seq_err_cond) {
- lapd_send_rr(&dl->lctx, 1, 1);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- lapd_send_rnr(&dl->lctx, 1, 1);
- } else {
- LOGP(DLLAPD, LOGL_INFO, "unhandled, "
- "pls. fix\n");
- }
- }
- /* restart T200 (PH-READY-TO-SEND) */
- lapd_start_t200(dl);
- } else {
- /* send MDL ERROR INIDCATION to L3 */
- mdl_error(MDL_CAUSE_T200_EXPIRED, &dl->lctx);
- /* reestablish */
- if (!dl->reestablish)
- break;
- LOGP(DLLAPD, LOGL_NOTICE, "N200 reached, performing "
- "reestablishment.\n");
- lapd_reestablish(dl);
- }
- break;
- default:
- LOGP(DLLAPD, LOGL_INFO, "T200 expired in unexpected "
- "dl->state %d\n", (int) dl->state);
- }
-}
-
-/* Timer callback on T203 expiry */
-static void lapd_t203_cb(void *data)
-{
- struct lapd_datalink *dl = data;
-
- LOGP(DLLAPD, LOGL_INFO, "Timeout T203 (%p) state=%d\n", dl,
- (int) dl->state);
-
- if (dl->state != LAPD_STATE_MF_EST) {
- LOGP(DLLAPD, LOGL_ERROR, "T203 fired outside MF EST state, "
- "please fix!\n");
- return;
- }
-
- /* set retransmission counter to 0 */
- dl->retrans_ctr = 0;
- /* enter timer recovery state */
- lapd_dl_newstate(dl, LAPD_STATE_TIMER_RECOV);
- /* transmit a supervisory command with P bit set to 1 as follows: */
- if (!dl->own_busy) {
- LOGP(DLLAPD, LOGL_INFO, "transmit an RR poll command\n");
- /* Send RR with P=1 */
- lapd_send_rr(&dl->lctx, 1, 1);
- } else {
- LOGP(DLLAPD, LOGL_INFO, "transmit an RNR poll command\n");
- /* Send RNR with P=1 */
- lapd_send_rnr(&dl->lctx, 1, 1);
- }
- /* start T200 */
- lapd_start_t200(dl);
-}
-
-/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
-static void lapd_acknowledge(struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- uint8_t nr = lctx->n_recv;
- int s = 0, rej = 0, t200_reset = 0;
- int i, h;
-
- /* supervisory frame ? */
- if (lctx->format == LAPD_FORM_S)
- s = 1;
- /* REJ frame ? */
- if (s && lctx->s_u == LAPD_S_REJ)
- rej = 1;
-
- /* Flush all transmit buffers of acknowledged frames */
- for (i = dl->v_ack; i != nr; i = inc_mod(i, dl->v_range)) {
- h = do_mod(i, dl->range_hist);
- if (dl->tx_hist[h].msg) {
- msgb_free(dl->tx_hist[h].msg);
- dl->tx_hist[h].msg = NULL;
- LOGP(DLLAPD, LOGL_INFO, "ack frame %d\n", i);
- }
- }
-
- if (dl->state != LAPD_STATE_TIMER_RECOV) {
- /* When not in the timer recovery condition, the data
- * link layer entity shall reset the timer T200 on
- * receipt of a valid I frame with N(R) higher than V(A),
- * or an REJ with an N(R) equal to V(A). */
- if ((!rej && nr != dl->v_ack)
- || (rej && nr == dl->v_ack)) {
- t200_reset = 1;
- lapd_stop_t200(dl);
- /* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
- }
- /* 5.7.4: N(R) sequence error
- * N(R) is called valid, if and only if
- * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
- */
- if (sub_mod(nr, dl->v_ack, dl->v_range)
- > sub_mod(dl->v_send, dl->v_ack, dl->v_range)) {
- LOGP(DLLAPD, LOGL_NOTICE, "N(R) sequence error\n");
- mdl_error(MDL_CAUSE_SEQ_ERR, lctx);
- }
- }
-
- /* V(A) shall be set to the value of N(R) */
- dl->v_ack = nr;
-
- /* If T200 has been stopped by the receipt of an I, RR or RNR frame,
- * and if there are outstanding I frames, restart T200 */
- if (t200_reset && !rej) {
- if (dl->tx_hist[sub_mod(dl->v_send, 1, dl->range_hist)].msg) {
- LOGP(DLLAPD, LOGL_INFO, "start T200, due to unacked I "
- "frame(s)\n");
- lapd_start_t200(dl);
- }
- }
-
- /* This also does a restart, when I or S frame is received */
-
- /* Stop T203, if running */
- lapd_stop_t203(dl);
- /* Start T203, if T200 is not running in MF EST state, if enabled */
- if (!osmo_timer_pending(&dl->t200)
- && (dl->t203_sec || dl->t203_usec)
- && (dl->state == LAPD_STATE_MF_EST)) {
- lapd_start_t203(dl);
- }
-}
-
-/* L1 -> L2 */
-
-/* Receive a LAPD U (Unnumbered) message from L1 */
-static int lapd_rx_u(struct msgb *msg, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- int length = lctx->length;
- int rc = 0;
- uint8_t prim, op;
-
- switch (lctx->s_u) {
- case LAPD_U_SABM:
- case LAPD_U_SABME:
- prim = PRIM_DL_EST;
- op = PRIM_OP_INDICATION;
-
- LOGP(DLLAPD, LOGL_INFO, "SABM(E) received in state %s\n",
- lapd_state_names[dl->state]);
- /* 5.7.1 */
- dl->seq_err_cond = 0;
- /* G.2.2 Wrong value of the C/R bit */
- if (lctx->cr == dl->cr.rem2loc.resp) {
- LOGP(DLLAPD, LOGL_NOTICE, "SABM response error\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
-
- /* G.4.5 If SABM is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
- if (lctx->more || length > lctx->n201) {
- LOGP(DLLAPD, LOGL_NOTICE, "SABM too large error\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
- return -EIO;
- }
-
- switch (dl->state) {
- case LAPD_STATE_IDLE:
- break;
- case LAPD_STATE_MF_EST:
- LOGP(DLLAPD, LOGL_INFO, "SABM command, multiple "
- "frame established state\n");
- /* If link is lost on the remote side, we start over
- * and send DL-ESTABLISH indication again. */
- if (dl->v_send != dl->v_recv) {
- LOGP(DLLAPD, LOGL_INFO, "Remote reestablish\n");
- mdl_error(MDL_CAUSE_SABM_MF, lctx);
- break;
- }
- /* Ignore SABM if content differs from first SABM. */
- if (dl->mode == LAPD_MODE_NETWORK && length
- && dl->cont_res) {
-#ifdef TEST_CONTENT_RESOLUTION_NETWORK
- dl->cont_res->data[0] ^= 0x01;
-#endif
- if (memcmp(dl->cont_res, msg->data, length)) {
- LOGP(DLLAPD, LOGL_INFO, "Another SABM "
- "with diffrent content - "
- "ignoring!\n");
- msgb_free(msg);
- return 0;
- }
- }
- /* send UA again */
- lapd_send_ua(lctx, length, msg->l3h);
- msgb_free(msg);
- return 0;
- case LAPD_STATE_DISC_SENT:
- /* 5.4.6.2 send DM with F=P */
- lapd_send_dm(lctx);
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- msgb_free(msg);
- return send_dl_simple(prim, op, lctx);
- default:
- /* collision: Send UA, but still wait for rx UA, then
- * change to MF_EST state.
- */
- /* check for contention resoultion */
- if (dl->tx_hist[0].msg && dl->tx_hist[0].msg->len) {
- LOGP(DLLAPD, LOGL_NOTICE, "SABM not allowed "
- "during contention resolution\n");
- mdl_error(MDL_CAUSE_SABM_INFO_NOTALL, lctx);
- }
- lapd_send_ua(lctx, length, msg->l3h);
- msgb_free(msg);
- return 0;
- }
- /* save message context for further use */
- memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
-#ifndef TEST_CONTENT_RESOLUTION_NETWORK
- /* send UA response */
- lapd_send_ua(lctx, length, msg->l3h);
-#endif
- /* set Vs, Vr and Va to 0 */
- dl->v_send = dl->v_recv = dl->v_ack = 0;
- /* clear tx_hist */
- lapd_dl_flush_hist(dl);
- /* enter multiple-frame-established state */
- lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
- /* store content resolution data on network side
- * Note: cont_res will be removed when changing state again,
- * so it must be allocated AFTER lapd_dl_newstate(). */
- if (dl->mode == LAPD_MODE_NETWORK && length) {
- dl->cont_res = lapd_msgb_alloc(length, "CONT RES");
- memcpy(msgb_put(dl->cont_res, length), msg->l3h,
- length);
- LOGP(DLLAPD, LOGL_NOTICE, "Store content res.\n");
- }
- /* send notification to L3 */
- if (length == 0) {
- /* 5.4.1.2 Normal establishment procedures */
- rc = send_dl_simple(prim, op, lctx);
- msgb_free(msg);
- } else {
- /* 5.4.1.4 Contention resolution establishment */
- rc = send_dl_l3(prim, op, lctx, msg);
- }
- break;
- case LAPD_U_DM:
- LOGP(DLLAPD, LOGL_INFO, "DM received in state %s\n",
- lapd_state_names[dl->state]);
- /* G.2.2 Wrong value of the C/R bit */
- if (lctx->cr == dl->cr.rem2loc.cmd) {
- LOGP(DLLAPD, LOGL_NOTICE, "DM command error\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
- if (!lctx->p_f) {
- /* 5.4.1.2 DM responses with the F bit set to "0"
- * shall be ignored.
- */
- msgb_free(msg);
- return 0;
- }
- switch (dl->state) {
- case LAPD_STATE_SABM_SENT:
- break;
- case LAPD_STATE_MF_EST:
- if (lctx->p_f) {
- LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
- "response\n");
- mdl_error(MDL_CAUSE_UNSOL_DM_RESP, lctx);
- } else {
- LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
- "response, multiple frame established "
- "state\n");
- mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
- /* reestablish */
- if (!dl->reestablish) {
- msgb_free(msg);
- return 0;
- }
- LOGP(DLLAPD, LOGL_NOTICE, "Performing "
- "reestablishment.\n");
- lapd_reestablish(dl);
- }
- msgb_free(msg);
- return 0;
- case LAPD_STATE_TIMER_RECOV:
- /* FP = 0 (DM is normal in case PF = 1) */
- if (!lctx->p_f) {
- LOGP(DLLAPD, LOGL_INFO, "unsolicited DM "
- "response, multiple frame established "
- "state\n");
- mdl_error(MDL_CAUSE_UNSOL_DM_RESP_MF, lctx);
- msgb_free(msg);
- /* reestablish */
- if (!dl->reestablish)
- return 0;
- LOGP(DLLAPD, LOGL_NOTICE, "Performing "
- "reestablishment.\n");
- return lapd_reestablish(dl);
- }
- break;
- case LAPD_STATE_DISC_SENT:
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* go to idle state */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
- msgb_free(msg);
- return 0;
- case LAPD_STATE_IDLE:
- /* 5.4.5 all other frame types shall be discarded */
- default:
- LOGP(DLLAPD, LOGL_INFO, "unsolicited DM response! "
- "(discarding)\n");
- msgb_free(msg);
- return 0;
- }
- /* stop timer T200 */
- lapd_stop_t200(dl);
- /* go to idle state */
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION, lctx);
- msgb_free(msg);
- break;
- case LAPD_U_UI:
- LOGP(DLLAPD, LOGL_INFO, "UI received\n");
- /* G.2.2 Wrong value of the C/R bit */
- if (lctx->cr == dl->cr.rem2loc.resp) {
- LOGP(DLLAPD, LOGL_NOTICE, "UI indicates response "
- "error\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
-
- /* G.4.5 If UI is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
- if (length > lctx->n201 || lctx->more) {
- LOGP(DLLAPD, LOGL_NOTICE, "UI too large error "
- "(%d > N201(%d) or M=%d)\n", length,
- lctx->n201, lctx->more);
- msgb_free(msg);
- mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
- return -EIO;
- }
-
- /* do some length checks */
- if (length == 0) {
- /* 5.3.3 UI frames received with the length indicator
- * set to "0" shall be ignored
- */
- LOGP(DLLAPD, LOGL_INFO, "length=0 (discarding)\n");
- msgb_free(msg);
- return 0;
- }
- rc = send_dl_l3(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION, lctx,
- msg);
- break;
- case LAPD_U_DISC:
- prim = PRIM_DL_REL;
- op = PRIM_OP_INDICATION;
-
- LOGP(DLLAPD, LOGL_INFO, "DISC received in state %s\n",
- lapd_state_names[dl->state]);
- /* flush tx and send buffers */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- /* 5.7.1 */
- dl->seq_err_cond = 0;
- /* G.2.2 Wrong value of the C/R bit */
- if (lctx->cr == dl->cr.rem2loc.resp) {
- LOGP(DLLAPD, LOGL_NOTICE, "DISC response error\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
- if (length > 0 || lctx->more) {
- /* G.4.4 If a DISC or DM frame is received with L>0 or
- * with the M bit set to "1", an MDL-ERROR-INDICATION
- * primitive with cause "U frame with incorrect
- * parameters" is sent to the mobile management entity.
- */
- LOGP(DLLAPD, LOGL_NOTICE,
- "U frame iwth incorrect parameters ");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
- return -EIO;
- }
- switch (dl->state) {
- case LAPD_STATE_IDLE:
- LOGP(DLLAPD, LOGL_INFO, "DISC in idle state\n");
- /* send DM with F=P */
- msgb_free(msg);
- return lapd_send_dm(lctx);
- case LAPD_STATE_SABM_SENT:
- LOGP(DLLAPD, LOGL_INFO, "DISC in SABM state\n");
- /* 5.4.6.2 send DM with F=P */
- lapd_send_dm(lctx);
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* go to idle state */
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- msgb_free(msg);
- return send_dl_simple(PRIM_DL_REL, PRIM_OP_INDICATION,
- lctx);
- case LAPD_STATE_MF_EST:
- case LAPD_STATE_TIMER_RECOV:
- LOGP(DLLAPD, LOGL_INFO, "DISC in est state\n");
- break;
- case LAPD_STATE_DISC_SENT:
- LOGP(DLLAPD, LOGL_INFO, "DISC in disc state\n");
- prim = PRIM_DL_REL;
- op = PRIM_OP_CONFIRM;
- break;
- default:
- lapd_send_ua(lctx, length, msg->l3h);
- msgb_free(msg);
- return 0;
- }
- /* send UA response */
- lapd_send_ua(lctx, length, msg->l3h);
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* enter idle state, keep tx-buffer with UA response */
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- /* send notification to L3 */
- rc = send_dl_simple(prim, op, lctx);
- msgb_free(msg);
- break;
- case LAPD_U_UA:
- LOGP(DLLAPD, LOGL_INFO, "UA received in state %s\n",
- lapd_state_names[dl->state]);
- /* G.2.2 Wrong value of the C/R bit */
- if (lctx->cr == dl->cr.rem2loc.cmd) {
- LOGP(DLLAPD, LOGL_NOTICE, "UA indicates command "
- "error\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
-
- /* G.4.5 If UA is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
- if (lctx->more || length > lctx->n201) {
- LOGP(DLLAPD, LOGL_NOTICE, "UA too large error\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_UFRM_INC_PARAM, lctx);
- return -EIO;
- }
-
- if (!lctx->p_f) {
- /* 5.4.1.2 A UA response with the F bit set to "0"
- * shall be ignored.
- */
- LOGP(DLLAPD, LOGL_INFO, "F=0 (discarding)\n");
- msgb_free(msg);
- return 0;
- }
- switch (dl->state) {
- case LAPD_STATE_SABM_SENT:
- break;
- case LAPD_STATE_MF_EST:
- case LAPD_STATE_TIMER_RECOV:
- LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
- "(discarding)\n");
- mdl_error(MDL_CAUSE_UNSOL_UA_RESP, lctx);
- msgb_free(msg);
- return 0;
- case LAPD_STATE_DISC_SENT:
- LOGP(DLLAPD, LOGL_INFO, "UA in disconnect state\n");
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* go to idle state */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- rc = send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, lctx);
- msgb_free(msg);
- return 0;
- case LAPD_STATE_IDLE:
- /* 5.4.5 all other frame types shall be discarded */
- default:
- LOGP(DLLAPD, LOGL_INFO, "unsolicited UA response! "
- "(discarding)\n");
- msgb_free(msg);
- return 0;
- }
- LOGP(DLLAPD, LOGL_INFO, "UA in SABM state\n");
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* compare UA with SABME if contention resolution is applied */
- if (dl->tx_hist[0].msg->len) {
- if (length != (dl->tx_hist[0].msg->len)
- || !!memcmp(dl->tx_hist[0].msg->data, msg->l3h,
- length)) {
- LOGP(DLLAPD, LOGL_INFO, "**** UA response "
- "mismatches ****\n");
- rc = send_dl_simple(PRIM_DL_REL,
- PRIM_OP_INDICATION, lctx);
- msgb_free(msg);
- /* go to idle state */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- return 0;
- }
- }
- /* set Vs, Vr and Va to 0 */
- dl->v_send = dl->v_recv = dl->v_ack = 0;
- /* clear tx_hist */
- lapd_dl_flush_hist(dl);
- /* enter multiple-frame-established state */
- lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
- /* send outstanding frames, if any (resume / reconnect) */
- lapd_send_i(lctx, __LINE__);
- /* send notification to L3 */
- rc = send_dl_simple(PRIM_DL_EST, PRIM_OP_CONFIRM, lctx);
- msgb_free(msg);
- break;
- case LAPD_U_FRMR:
- LOGP(DLLAPD, LOGL_NOTICE, "Frame reject received\n");
- /* send MDL ERROR INIDCATION to L3 */
- mdl_error(MDL_CAUSE_FRMR, lctx);
- msgb_free(msg);
- /* reestablish */
- if (!dl->reestablish)
- break;
- LOGP(DLLAPD, LOGL_NOTICE, "Performing reestablishment.\n");
- rc = lapd_reestablish(dl);
- break;
- default:
- /* G.3.1 */
- LOGP(DLLAPD, LOGL_NOTICE, "Unnumbered frame not allowed.\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
- return rc;
-}
-
-/* Receive a LAPD S (Supervisory) message from L1 */
-static int lapd_rx_s(struct msgb *msg, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- int length = lctx->length;
-
- if (length > 0 || lctx->more) {
- /* G.4.3 If a supervisory frame is received with L>0 or
- * with the M bit set to "1", an MDL-ERROR-INDICATION
- * primitive with cause "S frame with incorrect
- * parameters" is sent to the mobile management entity. */
- LOGP(DLLAPD, LOGL_NOTICE,
- "S frame with incorrect parameters\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_SFRM_INC_PARAM, lctx);
- return -EIO;
- }
-
- if (lctx->cr == dl->cr.rem2loc.resp
- && lctx->p_f
- && dl->state != LAPD_STATE_TIMER_RECOV) {
- /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
- LOGP(DLLAPD, LOGL_NOTICE, "S frame response with F=1 error\n");
- mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
- }
-
- switch (dl->state) {
- case LAPD_STATE_IDLE:
- /* if P=1, respond DM with F=1 (5.2.2) */
- /* 5.4.5 all other frame types shall be discarded */
- if (lctx->p_f)
- lapd_send_dm(lctx); /* F=P */
- /* fall though */
- case LAPD_STATE_SABM_SENT:
- case LAPD_STATE_DISC_SENT:
- LOGP(DLLAPD, LOGL_NOTICE, "S frame ignored in this state\n");
- msgb_free(msg);
- return 0;
- }
- switch (lctx->s_u) {
- case LAPD_S_RR:
- LOGP(DLLAPD, LOGL_INFO, "RR received in state %s\n",
- lapd_state_names[dl->state]);
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapd_acknowledge(lctx);
-
- /* 5.5.3.2 */
- if (lctx->cr == dl->cr.rem2loc.cmd
- && lctx->p_f) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLLAPD, LOGL_INFO, "RR frame command "
- "with polling bit set and we are not "
- "busy, so we reply with RR frame "
- "response\n");
- lapd_send_rr(lctx, 1, 0);
- /* NOTE: In case of sequence error condition,
- * the REJ frame has been transmitted when
- * entering the condition, so it has not be
- * done here
- */
- } else if (dl->own_busy) {
- LOGP(DLLAPD, LOGL_INFO, "RR frame command "
- "with polling bit set and we are busy, "
- "so we reply with RR frame response\n");
- lapd_send_rnr(lctx, 1, 0);
- }
- } else if (lctx->cr == dl->cr.rem2loc.resp
- && lctx->p_f
- && dl->state == LAPD_STATE_TIMER_RECOV) {
- LOGP(DLLAPD, LOGL_INFO, "RR response with F==1, "
- "and we are in timer recovery state, so "
- "we leave that state\n");
- /* V(S) to the N(R) in the RR frame */
- dl->v_send = lctx->n_recv;
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* 5.5.7 Clear timer recovery condition */
- lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
- }
- /* Send message, if possible due to acknowledged data */
- lapd_send_i(lctx, __LINE__);
-
- break;
- case LAPD_S_RNR:
- LOGP(DLLAPD, LOGL_INFO, "RNR received in state %s\n",
- lapd_state_names[dl->state]);
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapd_acknowledge(lctx);
-
- /* 5.5.5 */
- /* Set peer receiver busy condition */
- dl->peer_busy = 1;
-
- if (lctx->p_f) {
- if (lctx->cr == dl->cr.rem2loc.cmd) {
- if (!dl->own_busy) {
- LOGP(DLLAPD, LOGL_INFO, "RNR poll "
- "command and we are not busy, "
- "so we reply with RR final "
- "response\n");
- /* Send RR with F=1 */
- lapd_send_rr(lctx, 1, 0);
- } else {
- LOGP(DLLAPD, LOGL_INFO, "RNR poll "
- "command and we are busy, so "
- "we reply with RNR final "
- "response\n");
- /* Send RNR with F=1 */
- lapd_send_rnr(lctx, 1, 0);
- }
- } else if (dl->state == LAPD_STATE_TIMER_RECOV) {
- LOGP(DLLAPD, LOGL_INFO, "RNR poll response "
- "and we in timer recovery state, so "
- "we leave that state\n");
- /* 5.5.7 Clear timer recovery condition */
- lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
- /* V(S) to the N(R) in the RNR frame */
- dl->v_send = lctx->n_recv;
- }
- } else
- LOGP(DLLAPD, LOGL_INFO, "RNR not polling/final state "
- "received\n");
-
- /* Send message, if possible due to acknowledged data */
- lapd_send_i(lctx, __LINE__);
-
- break;
- case LAPD_S_REJ:
- LOGP(DLLAPD, LOGL_INFO, "REJ received in state %s\n",
- lapd_state_names[dl->state]);
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapd_acknowledge(lctx);
-
- /* 5.5.4.1 */
- if (dl->state != LAPD_STATE_TIMER_RECOV) {
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->v_send = dl->v_ack = lctx->n_recv;
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* 5.5.3.2 */
- if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLLAPD, LOGL_INFO, "REJ poll "
- "command not in timer recovery "
- "state and not in own busy "
- "condition received, so we "
- "respond with RR final "
- "response\n");
- lapd_send_rr(lctx, 1, 0);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- LOGP(DLLAPD, LOGL_INFO, "REJ poll "
- "command not in timer recovery "
- "state and in own busy "
- "condition received, so we "
- "respond with RNR final "
- "response\n");
- lapd_send_rnr(lctx, 1, 0);
- }
- } else
- LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
- "polling command not in timer recovery "
- "state received\n");
- /* send MDL ERROR INIDCATION to L3 */
- if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
- mdl_error(MDL_CAUSE_UNSOL_SPRV_RESP, lctx);
- }
-
- } else if (lctx->cr == dl->cr.rem2loc.resp && lctx->p_f) {
- LOGP(DLLAPD, LOGL_INFO, "REJ poll response in timer "
- "recovery state received\n");
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->v_send = dl->v_ack = lctx->n_recv;
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* 5.5.7 Clear timer recovery condition */
- lapd_dl_newstate(dl, LAPD_STATE_MF_EST);
- } else {
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->v_send = dl->v_ack = lctx->n_recv;
- /* 5.5.3.2 */
- if (lctx->cr == dl->cr.rem2loc.cmd && lctx->p_f) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLLAPD, LOGL_INFO, "REJ poll "
- "command in timer recovery "
- "state and not in own busy "
- "condition received, so we "
- "respond with RR final "
- "response\n");
- lapd_send_rr(lctx, 1, 0);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- LOGP(DLLAPD, LOGL_INFO, "REJ poll "
- "command in timer recovery "
- "state and in own busy "
- "condition received, so we "
- "respond with RNR final "
- "response\n");
- lapd_send_rnr(lctx, 1, 0);
- }
- } else
- LOGP(DLLAPD, LOGL_INFO, "REJ response or not "
- "polling command in timer recovery "
- "state received\n");
- }
-
- /* FIXME: 5.5.4.2 2) */
-
- /* Send message, if possible due to acknowledged data */
- lapd_send_i(lctx, __LINE__);
-
- break;
- default:
- /* G.3.1 */
- LOGP(DLLAPD, LOGL_NOTICE, "Supervisory frame not allowed.\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
- msgb_free(msg);
- return 0;
-}
-
-/* Receive a LAPD I (Information) message from L1 */
-static int lapd_rx_i(struct msgb *msg, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- //uint8_t nr = lctx->n_recv;
- uint8_t ns = lctx->n_send;
- int length = lctx->length;
- int rc;
-
- LOGP(DLLAPD, LOGL_INFO, "I received in state %s\n",
- lapd_state_names[dl->state]);
-
- /* G.2.2 Wrong value of the C/R bit */
- if (lctx->cr == dl->cr.rem2loc.resp) {
- LOGP(DLLAPD, LOGL_NOTICE, "I frame response not allowed\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_FRM_UNIMPL, lctx);
- return -EINVAL;
- }
-
- if (length == 0 || length > lctx->n201) {
- /* G.4.2 If the length indicator of an I frame is set
- * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
- * primitive with cause "I frame with incorrect length"
- * is sent to the mobile management entity. */
- LOGP(DLLAPD, LOGL_NOTICE, "I frame length not allowed\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_IFRM_INC_LEN, lctx);
- return -EIO;
- }
-
- /* G.4.2 If the numerical value of L is L<N201 and the M
- * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
- * cause "I frame with incorrect use of M bit" is sent to the
- * mobile management entity. */
- if (lctx->more && length < lctx->n201) {
- LOGP(DLLAPD, LOGL_NOTICE, "I frame with M bit too short\n");
- msgb_free(msg);
- mdl_error(MDL_CAUSE_IFRM_INC_MBITS, lctx);
- return -EIO;
- }
-
- switch (dl->state) {
- case LAPD_STATE_IDLE:
- /* if P=1, respond DM with F=1 (5.2.2) */
- /* 5.4.5 all other frame types shall be discarded */
- if (lctx->p_f)
- lapd_send_dm(lctx); /* F=P */
- /* fall though */
- case LAPD_STATE_SABM_SENT:
- case LAPD_STATE_DISC_SENT:
- LOGP(DLLAPD, LOGL_NOTICE, "I frame ignored in this state\n");
- msgb_free(msg);
- return 0;
- }
-
- /* 5.7.1: N(s) sequence error */
- if (ns != dl->v_recv) {
- LOGP(DLLAPD, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, "
- "V(R)=%u\n", ns, dl->v_recv);
- /* discard data */
- msgb_free(msg);
- if (dl->seq_err_cond != 1) {
- /* FIXME: help me understand what exactly todo here
- */
- dl->seq_err_cond = 1;
- lapd_send_rej(lctx, lctx->p_f);
- } else {
- /* If there are two subsequent sequence errors received,
- * ignore it. (Ignore every second subsequent error.)
- * This happens if our reply with the REJ is too slow,
- * so the remote gets a T200 timeout and sends another
- * frame with a sequence error.
- * Test showed that replying with two subsequent REJ
- * messages could the remote L2 process to abort.
- * Replying too slow shouldn't happen, but may happen
- * over serial link between BB and LAPD.
- */
- dl->seq_err_cond = 2;
- }
- /* Even if N(s) sequence error, acknowledge to N(R)-1 */
- /* 5.5.3.1: Acknowlege all transmitted frames up the N(R)-1 */
- lapd_acknowledge(lctx); /* V(A) is also set here */
-
- /* Send message, if possible due to acknowledged data */
- lapd_send_i(lctx, __LINE__);
-
- return 0;
- }
- dl->seq_err_cond = 0;
-
- /* Increment receiver state */
- dl->v_recv = inc_mod(dl->v_recv, dl->v_range);
- LOGP(DLLAPD, LOGL_INFO, "incrementing V(R) to %u\n", dl->v_recv);
-
- /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
- lapd_acknowledge(lctx); /* V(A) is also set here */
-
- /* Only if we are not in own receiver busy condition */
- if (!dl->own_busy) {
- /* if the frame carries a complete segment */
- if (!lctx->more && !dl->rcv_buffer) {
- LOGP(DLLAPD, LOGL_INFO, "message in single I frame\n");
- /* send a DATA INDICATION to L3 */
- msg->len = length;
- msg->tail = msg->data + length;
- rc = send_dl_l3(PRIM_DL_DATA, PRIM_OP_INDICATION, lctx,
- msg);
- } else {
- /* create rcv_buffer */
- if (!dl->rcv_buffer) {
- LOGP(DLLAPD, LOGL_INFO, "message in multiple "
- "I frames (first message)\n");
- dl->rcv_buffer = lapd_msgb_alloc(dl->maxf,
- "LAPD RX");
- dl->rcv_buffer->l3h = dl->rcv_buffer->data;
- }
- /* concat. rcv_buffer */
- if (msgb_l3len(dl->rcv_buffer) + length > dl->maxf) {
- LOGP(DLLAPD, LOGL_NOTICE, "Received frame "
- "overflow!\n");
- } else {
- memcpy(msgb_put(dl->rcv_buffer, length),
- msg->l3h, length);
- }
- /* if the last segment was received */
- if (!lctx->more) {
- LOGP(DLLAPD, LOGL_INFO, "message in multiple "
- "I frames (last message)\n");
- rc = send_dl_l3(PRIM_DL_DATA,
- PRIM_OP_INDICATION, lctx,
- dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- } else
- LOGP(DLLAPD, LOGL_INFO, "message in multiple "
- "I frames (next message)\n");
- msgb_free(msg);
-
- }
- } else
- LOGP(DLLAPD, LOGL_INFO, "I frame ignored during own receiver "
- "busy condition\n");
-
- /* Check for P bit */
- if (lctx->p_f) {
- /* 5.5.2.1 */
- /* check if we are not in own receiver busy */
- if (!dl->own_busy) {
- LOGP(DLLAPD, LOGL_INFO, "we are not busy, send RR\n");
- /* Send RR with F=1 */
- rc = lapd_send_rr(lctx, 1, 0);
- } else {
- LOGP(DLLAPD, LOGL_INFO, "we are busy, send RNR\n");
- /* Send RNR with F=1 */
- rc = lapd_send_rnr(lctx, 1, 0);
- }
- } else {
- /* 5.5.2.2 */
- /* check if we are not in own receiver busy */
- if (!dl->own_busy) {
- /* NOTE: V(R) is already set above */
- rc = lapd_send_i(lctx, __LINE__);
- if (rc) {
- LOGP(DLLAPD, LOGL_INFO, "we are not busy and "
- "have no pending data, send RR\n");
- /* Send RR with F=0 */
- return lapd_send_rr(lctx, 0, 0);
- }
- /* all I or one RR is sent, we are done */
- return 0;
- } else {
- LOGP(DLLAPD, LOGL_INFO, "we are busy, send RNR\n");
- /* Send RNR with F=0 */
- rc = lapd_send_rnr(lctx, 0, 0);
- }
- }
-
- /* Send message, if possible due to acknowledged data */
- lapd_send_i(lctx, __LINE__);
-
- return rc;
-}
-
-/* Receive a LAPD message from L1 */
-int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx)
-{
- int rc;
-
- switch (lctx->format) {
- case LAPD_FORM_U:
- rc = lapd_rx_u(msg, lctx);
- break;
- case LAPD_FORM_S:
- rc = lapd_rx_s(msg, lctx);
- break;
- case LAPD_FORM_I:
- rc = lapd_rx_i(msg, lctx);
- break;
- default:
- LOGP(DLLAPD, LOGL_NOTICE, "unknown LAPD format\n");
- msgb_free(msg);
- rc = -EINVAL;
- }
- return rc;
-}
-
-/* L3 -> L2 */
-
-/* send unit data */
-static int lapd_udata_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct msgb *msg = dp->oph.msg;
- struct lapd_msg_ctx nctx;
-
- memcpy(&nctx, lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_U;
- nctx.s_u = LAPD_U_UI;
- /* keep nctx.p_f */
- nctx.length = msg->len;
- nctx.more = 0;
-
- return dl->send_ph_data_req(&nctx, msg);
-}
-
-/* request link establishment */
-static int lapd_est_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct msgb *msg = dp->oph.msg;
- struct lapd_msg_ctx nctx;
-
- if (msg->len)
- LOGP(DLLAPD, LOGL_INFO, "perform establishment with content "
- "(SABM)\n");
- else
- LOGP(DLLAPD, LOGL_INFO, "perform normal establishm. (SABM)\n");
-
- /* Flush send-queue */
- /* Clear send-buffer */
- lapd_dl_flush_send(dl);
- /* be sure that history is empty */
- lapd_dl_flush_hist(dl);
-
- /* save message context for further use */
- memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
-
- /* Discard partly received L3 message */
- if (dl->rcv_buffer) {
- msgb_free(dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- }
-
- /* assemble message */
- memcpy(&nctx, &dl->lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_U;
- nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
- nctx.p_f = 1;
- nctx.length = msg->len;
- nctx.more = 0;
-
- /* Transmit-buffer carries exactly one segment */
- dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
- msgb_put(dl->tx_hist[0].msg, msg->len);
- if (msg->len)
- memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
- dl->tx_hist[0].more = 0;
- /* set Vs to 0, because it is used as index when resending SABM */
- dl->v_send = 0;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
-
- /* Tramsmit and start T200 */
- dl->send_ph_data_req(&nctx, msg);
- lapd_start_t200(dl);
-
- return 0;
-}
-
-/* send data */
-static int lapd_data_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct msgb *msg = dp->oph.msg;
-
- if (msgb_l3len(msg) == 0) {
- LOGP(DLLAPD, LOGL_ERROR,
- "writing an empty message is not possible.\n");
- msgb_free(msg);
- return -1;
- }
-
- LOGP(DLLAPD, LOGL_INFO,
- "writing message to send-queue: l3len: %d\n", msgb_l3len(msg));
-
- /* Write data into the send queue */
- msgb_enqueue(&dl->send_queue, msg);
-
- /* Send message, if possible */
- lapd_send_i(&dl->lctx, __LINE__);
-
- return 0;
-}
-
-/* Send next I frame from queued/buffered data */
-static int lapd_send_i(struct lapd_msg_ctx *lctx, int line)
-{
- struct lapd_datalink *dl = lctx->dl;
- uint8_t k = dl->k;
- uint8_t h;
- struct msgb *msg;
- int length, left;
- int rc = - 1; /* we sent nothing */
- struct lapd_msg_ctx nctx;
-
-
- LOGP(DLLAPD, LOGL_INFO, "%s() called from line %d\n", __func__, line);
-
- next_frame:
-
- if (dl->peer_busy) {
- LOGP(DLLAPD, LOGL_INFO, "peer busy, not sending\n");
- return rc;
- }
-
- if (dl->state == LAPD_STATE_TIMER_RECOV) {
- LOGP(DLLAPD, LOGL_INFO, "timer recovery, not sending\n");
- return rc;
- }
-
- /* If the send state variable V(S) is equal to V(A) plus k
- * (where k is the maximum number of outstanding I frames - see
- * subclause 5.8.4), the data link layer entity shall not transmit any
- * new I frames, but shall retransmit an I frame as a result
- * of the error recovery procedures as described in subclauses 5.5.4 and
- * 5.5.7. */
- if (dl->v_send == add_mod(dl->v_ack, k, dl->v_range)) {
- LOGP(DLLAPD, LOGL_INFO, "k frames outstanding, not sending "
- "more (k=%u V(S)=%u V(A)=%u)\n", k, dl->v_send,
- dl->v_ack);
- return rc;
- }
-
- h = do_mod(dl->v_send, dl->range_hist);
-
- /* if we have no tx_hist yet, we create it */
- if (!dl->tx_hist[h].msg) {
- /* Get next message into send-buffer, if any */
- if (!dl->send_buffer) {
- next_message:
- dl->send_out = 0;
- dl->send_buffer = msgb_dequeue(&dl->send_queue);
- /* No more data to be sent */
- if (!dl->send_buffer)
- return rc;
- LOGP(DLLAPD, LOGL_INFO, "get message from "
- "send-queue\n");
- }
-
- /* How much is left in the send-buffer? */
- left = msgb_l3len(dl->send_buffer) - dl->send_out;
- /* Segment, if data exceeds N201 */
- length = left;
- if (length > lctx->n201)
- length = lctx->n201;
- LOGP(DLLAPD, LOGL_INFO, "msg-len %d sent %d left %d N201 %d "
- "length %d first byte %02x\n",
- msgb_l3len(dl->send_buffer), dl->send_out, left,
- lctx->n201, length, dl->send_buffer->l3h[0]);
- /* If message in send-buffer is completely sent */
- if (left == 0) {
- msgb_free(dl->send_buffer);
- dl->send_buffer = NULL;
- goto next_message;
- }
-
- LOGP(DLLAPD, LOGL_INFO, "send I frame %sV(S)=%d\n",
- (left > length) ? "segment " : "", dl->v_send);
-
- /* Create I frame (segment) and transmit-buffer content */
- msg = lapd_msgb_alloc(length, "LAPD I");
- msg->l3h = msgb_put(msg, length);
- /* assemble message */
- memcpy(&nctx, &dl->lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_I;
- nctx.p_f = 0;
- nctx.n_send = dl->v_send;
- nctx.n_recv = dl->v_recv;
- nctx.length = length;
- if (left > length)
- nctx.more = 1;
- else
- nctx.more = 0;
- if (length)
- memcpy(msg->l3h, dl->send_buffer->l3h + dl->send_out,
- length);
- /* store in tx_hist */
- dl->tx_hist[h].msg = lapd_msgb_alloc(msg->len, "HIST");
- msgb_put(dl->tx_hist[h].msg, msg->len);
- if (length)
- memcpy(dl->tx_hist[h].msg->data, msg->l3h, msg->len);
- dl->tx_hist[h].more = nctx.more;
- /* Add length to track how much is already in the tx buffer */
- dl->send_out += length;
- } else {
- LOGP(DLLAPD, LOGL_INFO, "resend I frame from tx buffer "
- "V(S)=%d\n", dl->v_send);
-
- /* Create I frame (segment) from tx_hist */
- length = dl->tx_hist[h].msg->len;
- msg = lapd_msgb_alloc(length, "LAPD I resend");
- msg->l3h = msgb_put(msg, length);
- /* assemble message */
- memcpy(&nctx, &dl->lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_I;
- nctx.p_f = 0;
- nctx.n_send = dl->v_send;
- nctx.n_recv = dl->v_recv;
- nctx.length = length;
- nctx.more = dl->tx_hist[h].more;
- if (length)
- memcpy(msg->l3h, dl->tx_hist[h].msg->data, length);
- }
-
- /* The value of the send state variable V(S) shall be incremented by 1
- * at the end of the transmission of the I frame */
- dl->v_send = inc_mod(dl->v_send, dl->v_range);
-
- /* If timer T200 is not running at the time right before transmitting a
- * frame, when the PH-READY-TO-SEND primitive is received from the
- * physical layer., it shall be set. */
- if (!osmo_timer_pending(&dl->t200)) {
- /* stop Timer T203, if running */
- lapd_stop_t203(dl);
- /* start Timer T200 */
- lapd_start_t200(dl);
- }
-
- dl->send_ph_data_req(&nctx, msg);
-
- rc = 0; /* we sent something */
- goto next_frame;
-}
-
-/* request link suspension */
-static int lapd_susp_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct msgb *msg = dp->oph.msg;
-
- LOGP(DLLAPD, LOGL_INFO, "perform suspension\n");
-
- /* put back the send-buffer to the send-queue (first position) */
- if (dl->send_buffer) {
- LOGP(DLLAPD, LOGL_INFO, "put frame in sendbuffer back to "
- "queue\n");
- llist_add(&dl->send_buffer->list, &dl->send_queue);
- dl->send_buffer = NULL;
- } else
- LOGP(DLLAPD, LOGL_INFO, "no frame in sendbuffer\n");
-
- /* Clear transmit buffer, but keep send buffer */
- lapd_dl_flush_tx(dl);
- /* Stop timers (there is no state change, so we must stop all timers */
- lapd_stop_t200(dl);
- lapd_stop_t203(dl);
-
- msgb_free(msg);
-
- return send_dl_simple(PRIM_DL_SUSP, PRIM_OP_CONFIRM, &dl->lctx);
-}
-
-/* requesst resume or reconnect of link */
-static int lapd_res_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct msgb *msg = dp->oph.msg;
- struct lapd_msg_ctx nctx;
-
- LOGP(DLLAPD, LOGL_INFO, "perform re-establishment (SABM) length=%d\n",
- msg->len);
-
- /* be sure that history is empty */
- lapd_dl_flush_hist(dl);
-
- /* save message context for further use */
- memcpy(&dl->lctx, lctx, sizeof(dl->lctx));
-
- /* Replace message in the send-buffer (reconnect) */
- if (dl->send_buffer)
- msgb_free(dl->send_buffer);
- dl->send_out = 0;
- if (msg && msg->len)
- /* Write data into the send buffer, to be sent first */
- dl->send_buffer = msg;
- else
- dl->send_buffer = NULL;
-
- /* Discard partly received L3 message */
- if (dl->rcv_buffer) {
- msgb_free(dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- }
-
- /* Create new msgb (old one is now free) */
- msg = lapd_msgb_alloc(0, "LAPD SABM");
- msg->l3h = msg->data;
- /* assemble message */
- memcpy(&nctx, &dl->lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_U;
- nctx.s_u = (dl->use_sabme) ? LAPD_U_SABME : LAPD_U_SABM;
- nctx.p_f = 1;
- nctx.length = 0;
- nctx.more = 0;
-
- dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
- msgb_put(dl->tx_hist[0].msg, msg->len);
- if (msg->len)
- memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
- dl->tx_hist[0].more = 0;
- /* set Vs to 0, because it is used as index when resending SABM */
- dl->v_send = 0;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapd_dl_newstate(dl, LAPD_STATE_SABM_SENT);
-
- /* Tramsmit and start T200 */
- dl->send_ph_data_req(&nctx, msg);
- lapd_start_t200(dl);
-
- return 0;
-}
-
-/* requesst release of link */
-static int lapd_rel_req(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct msgb *msg = dp->oph.msg;
- struct lapd_msg_ctx nctx;
-
- /* local release */
- if (dp->u.rel_req.mode) {
- LOGP(DLLAPD, LOGL_INFO, "perform local release\n");
- msgb_free(msg);
- /* stop Timer T200 */
- lapd_stop_t200(dl);
- /* enter idle state, T203 is stopped here, if running */
- lapd_dl_newstate(dl, LAPD_STATE_IDLE);
- /* flush buffers */
- lapd_dl_flush_tx(dl);
- lapd_dl_flush_send(dl);
- /* send notification to L3 */
- return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
- }
-
- /* in case we are already disconnecting */
- if (dl->state == LAPD_STATE_DISC_SENT)
- return -EBUSY;
-
- /* flush tx_hist */
- lapd_dl_flush_hist(dl);
-
- LOGP(DLLAPD, LOGL_INFO, "perform normal release (DISC)\n");
-
- /* Push LAPD header on msgb */
- /* assemble message */
- memcpy(&nctx, &dl->lctx, sizeof(nctx));
- /* keep nctx.ldp */
- /* keep nctx.sapi */
- /* keep nctx.tei */
- nctx.cr = dl->cr.loc2rem.cmd;
- nctx.format = LAPD_FORM_U;
- nctx.s_u = LAPD_U_DISC;
- nctx.p_f = 1;
- nctx.length = 0;
- nctx.more = 0;
-
- dl->tx_hist[0].msg = lapd_msgb_alloc(msg->len, "HIST");
- msgb_put(dl->tx_hist[0].msg, msg->len);
- if (msg->len)
- memcpy(dl->tx_hist[0].msg->data, msg->l3h, msg->len);
- dl->tx_hist[0].more = 0;
- /* set Vs to 0, because it is used as index when resending DISC */
- dl->v_send = 0;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapd_dl_newstate(dl, LAPD_STATE_DISC_SENT);
-
- /* Tramsmit and start T200 */
- dl->send_ph_data_req(&nctx, msg);
- lapd_start_t200(dl);
-
- return 0;
-}
-
-/* request release of link in idle state */
-static int lapd_rel_req_idle(struct osmo_dlsap_prim *dp,
- struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct msgb *msg = dp->oph.msg;
-
- msgb_free(msg);
-
- /* send notification to L3 */
- return send_dl_simple(PRIM_DL_REL, PRIM_OP_CONFIRM, &dl->lctx);
-}
-
-/* statefull handling for DL SAP messages from L3 */
-static struct l2downstate {
- uint32_t states;
- int prim, op;
- const char *name;
- int (*rout) (struct osmo_dlsap_prim *dp,
- struct lapd_msg_ctx *lctx);
-} l2downstatelist[] = {
- /* create and send UI command */
- {ALL_STATES,
- PRIM_DL_UNIT_DATA, PRIM_OP_REQUEST,
- "DL-UNIT-DATA-REQUEST", lapd_udata_req},
-
- /* create and send SABM command */
- {SBIT(LAPD_STATE_IDLE),
- PRIM_DL_EST, PRIM_OP_REQUEST,
- "DL-ESTABLISH-REQUEST", lapd_est_req},
-
- /* create and send I command */
- {SBIT(LAPD_STATE_MF_EST) |
- SBIT(LAPD_STATE_TIMER_RECOV),
- PRIM_DL_DATA, PRIM_OP_REQUEST,
- "DL-DATA-REQUEST", lapd_data_req},
-
- /* suspend datalink */
- {SBIT(LAPD_STATE_MF_EST) |
- SBIT(LAPD_STATE_TIMER_RECOV),
- PRIM_DL_SUSP, PRIM_OP_REQUEST,
- "DL-SUSPEND-REQUEST", lapd_susp_req},
-
- /* create and send SABM command (resume) */
- {SBIT(LAPD_STATE_MF_EST) |
- SBIT(LAPD_STATE_TIMER_RECOV),
- PRIM_DL_RES, PRIM_OP_REQUEST,
- "DL-RESUME-REQUEST", lapd_res_req},
-
- /* create and send SABM command (reconnect) */
- {SBIT(LAPD_STATE_IDLE) |
- SBIT(LAPD_STATE_MF_EST) |
- SBIT(LAPD_STATE_TIMER_RECOV),
- PRIM_DL_RECON, PRIM_OP_REQUEST,
- "DL-RECONNECT-REQUEST", lapd_res_req},
-
- /* create and send DISC command */
- {SBIT(LAPD_STATE_SABM_SENT) |
- SBIT(LAPD_STATE_MF_EST) |
- SBIT(LAPD_STATE_TIMER_RECOV) |
- SBIT(LAPD_STATE_DISC_SENT),
- PRIM_DL_REL, PRIM_OP_REQUEST,
- "DL-RELEASE-REQUEST", lapd_rel_req},
-
- /* release in idle state */
- {SBIT(LAPD_STATE_IDLE),
- PRIM_DL_REL, PRIM_OP_REQUEST,
- "DL-RELEASE-REQUEST", lapd_rel_req_idle},
-};
-
-#define L2DOWNSLLEN \
- (sizeof(l2downstatelist) / sizeof(struct l2downstate))
-
-int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- int i, supported = 0;
- struct msgb *msg = dp->oph.msg;
- int rc;
-
- /* find function for current state and message */
- for (i = 0; i < L2DOWNSLLEN; i++) {
- if (dp->oph.primitive == l2downstatelist[i].prim
- && dp->oph.operation == l2downstatelist[i].op) {
- supported = 1;
- if ((SBIT(dl->state) & l2downstatelist[i].states))
- break;
- }
- }
- if (!supported) {
- LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unsupported.\n",
- dp->oph.primitive, dp->oph.operation);
- msgb_free(msg);
- return 0;
- }
- if (i == L2DOWNSLLEN) {
- LOGP(DLLAPD, LOGL_NOTICE, "Message %u/%u unhandled at this "
- "state %s.\n", dp->oph.primitive, dp->oph.operation,
- lapd_state_names[dl->state]);
- msgb_free(msg);
- return 0;
- }
-
- LOGP(DLLAPD, LOGL_INFO, "Message %s received in state %s\n",
- l2downstatelist[i].name, lapd_state_names[dl->state]);
-
- rc = l2downstatelist[i].rout(dp, lctx);
-
- return rc;
-}
-
diff --git a/src/shared/libosmocore/src/gsm/lapdm.c b/src/shared/libosmocore/src/gsm/lapdm.c
deleted file mode 100644
index 1c08113e..00000000
--- a/src/shared/libosmocore/src/gsm/lapdm.c
+++ /dev/null
@@ -1,1249 +0,0 @@
-/* GSM LAPDm (TS 04.06) implementation */
-
-/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010-2011 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/*! \addtogroup lapdm
- * @{
- */
-
-/*! \file lapdm.c */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/utils.h>
-
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/rsl.h>
-#include <osmocom/gsm/prim.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/lapdm.h>
-
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_08_58.h>
-
-/* TS 04.06 Figure 4 / Section 3.2 */
-#define LAPDm_LPD_NORMAL 0
-#define LAPDm_LPD_SMSCB 1
-#define LAPDm_SAPI_NORMAL 0
-#define LAPDm_SAPI_SMS 3
-#define LAPDm_ADDR(lpd, sapi, cr) ((((lpd) & 0x3) << 5) | (((sapi) & 0x7) << 2) | (((cr) & 0x1) << 1) | 0x1)
-
-#define LAPDm_ADDR_LPD(addr) (((addr) >> 5) & 0x3)
-#define LAPDm_ADDR_SAPI(addr) (((addr) >> 2) & 0x7)
-#define LAPDm_ADDR_CR(addr) (((addr) >> 1) & 0x1)
-#define LAPDm_ADDR_EA(addr) ((addr) & 0x1)
-
-/* TS 04.06 Table 3 / Section 3.4.3 */
-#define LAPDm_CTRL_I(nr, ns, p) ((((nr) & 0x7) << 5) | (((p) & 0x1) << 4) | (((ns) & 0x7) << 1))
-#define LAPDm_CTRL_S(nr, s, p) ((((nr) & 0x7) << 5) | (((p) & 0x1) << 4) | (((s) & 0x3) << 2) | 0x1)
-#define LAPDm_CTRL_U(u, p) ((((u) & 0x1c) << (5-2)) | (((p) & 0x1) << 4) | (((u) & 0x3) << 2) | 0x3)
-
-#define LAPDm_CTRL_is_I(ctrl) (((ctrl) & 0x1) == 0)
-#define LAPDm_CTRL_is_S(ctrl) (((ctrl) & 0x3) == 1)
-#define LAPDm_CTRL_is_U(ctrl) (((ctrl) & 0x3) == 3)
-
-#define LAPDm_CTRL_U_BITS(ctrl) ((((ctrl) & 0xC) >> 2) | ((ctrl) & 0xE0) >> 3)
-#define LAPDm_CTRL_PF_BIT(ctrl) (((ctrl) >> 4) & 0x1)
-
-#define LAPDm_CTRL_S_BITS(ctrl) (((ctrl) & 0xC) >> 2)
-
-#define LAPDm_CTRL_I_Ns(ctrl) (((ctrl) & 0xE) >> 1)
-#define LAPDm_CTRL_Nr(ctrl) (((ctrl) & 0xE0) >> 5)
-
-#define LAPDm_LEN(len) ((len << 2) | 0x1)
-#define LAPDm_MORE 0x2
-#define LAPDm_EL 0x1
-
-#define LAPDm_U_UI 0x0
-
-/* TS 04.06 Section 5.8.3 */
-#define N201_AB_SACCH 18
-#define N201_AB_SDCCH 20
-#define N201_AB_FACCH 20
-#define N201_Bbis 23
-#define N201_Bter_SACCH 21
-#define N201_Bter_SDCCH 23
-#define N201_Bter_FACCH 23
-#define N201_B4 19
-
-/* 5.8.2.1 N200 during establish and release */
-#define N200_EST_REL 5
-/* 5.8.2.1 N200 during timer recovery state */
-#define N200_TR_SACCH 5
-#define N200_TR_SDCCH 23
-#define N200_TR_FACCH_FR 34
-#define N200_TR_EFACCH_FR 48
-#define N200_TR_FACCH_HR 29
-/* FIXME: set N200 depending on chan_nr */
-#define N200 N200_TR_SDCCH
-
-enum lapdm_format {
- LAPDm_FMT_A,
- LAPDm_FMT_B,
- LAPDm_FMT_Bbis,
- LAPDm_FMT_Bter,
- LAPDm_FMT_B4,
-};
-
-static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg);
-static int send_rslms_dlsap(struct osmo_dlsap_prim *dp,
- struct lapd_msg_ctx *lctx);
-
-static void lapdm_dl_init(struct lapdm_datalink *dl,
- struct lapdm_entity *entity, int t200)
-{
- memset(dl, 0, sizeof(*dl));
- dl->entity = entity;
- lapd_dl_init(&dl->dl, 1, 8, 200);
- dl->dl.reestablish = 0; /* GSM uses no reestablish */
- dl->dl.send_ph_data_req = lapdm_send_ph_data_req;
- dl->dl.send_dlsap = send_rslms_dlsap;
- dl->dl.n200_est_rel = N200_EST_REL;
- dl->dl.n200 = N200;
- dl->dl.t203_sec = 0; dl->dl.t203_usec = 0;
- dl->dl.t200_sec = t200; dl->dl.t200_usec = 0;
-}
-
-/*! \brief initialize a LAPDm entity and all datalinks inside
- * \param[in] le LAPDm entity
- * \param[in] mode \ref lapdm_mode (BTS/MS)
- */
-void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(le->datalink); i++)
- lapdm_dl_init(&le->datalink[i], le, t200);
-
- lapdm_entity_set_mode(le, mode);
-}
-
-/*! \brief initialize a LAPDm channel and all its channels
- * \param[in] lc \ref lapdm_channel to be initialized
- * \param[in] mode \ref lapdm_mode (BTS/MS)
- *
- * This really is a convenience wrapper around calling \ref
- * lapdm_entity_init twice.
- */
-void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode)
-{
- lapdm_entity_init(&lc->lapdm_acch, mode, 2);
- /* FIXME: this depends on chan type */
- lapdm_entity_init(&lc->lapdm_dcch, mode, 1);
-}
-
-/*! \brief flush and release all resoures in LAPDm entity */
-void lapdm_entity_exit(struct lapdm_entity *le)
-{
- unsigned int i;
- struct lapdm_datalink *dl;
-
- for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
- dl = &le->datalink[i];
- lapd_dl_exit(&dl->dl);
- }
-}
-
-/* \brief lfush and release all resources in LAPDm channel
- *
- * A convenience wrapper calling \ref lapdm_entity_exit on both
- * entities inside the \ref lapdm_channel
- */
-void lapdm_channel_exit(struct lapdm_channel *lc)
-{
- lapdm_entity_exit(&lc->lapdm_acch);
- lapdm_entity_exit(&lc->lapdm_dcch);
-}
-
-static struct lapdm_datalink *datalink_for_sapi(struct lapdm_entity *le, uint8_t sapi)
-{
- switch (sapi) {
- case LAPDm_SAPI_NORMAL:
- return &le->datalink[0];
- case LAPDm_SAPI_SMS:
- return &le->datalink[1];
- default:
- return NULL;
- }
-}
-
-/* remove the L2 header from a MSGB */
-static inline unsigned char *msgb_pull_l2h(struct msgb *msg)
-{
- unsigned char *ret = msgb_pull(msg, msg->l3h - msg->l2h);
- msg->l2h = NULL;
- return ret;
-}
-
-/* Append padding (if required) */
-static void lapdm_pad_msgb(struct msgb *msg, uint8_t n201)
-{
- int pad_len = n201 - msgb_l2len(msg);
- uint8_t *data;
-
- if (pad_len < 0) {
- LOGP(DLLAPD, LOGL_ERROR,
- "cannot pad message that is already too big!\n");
- return;
- }
-
- data = msgb_put(msg, pad_len);
- memset(data, 0x2B, pad_len);
-}
-
-/* input function that L2 calls when sending messages up to L3 */
-static int rslms_sendmsg(struct msgb *msg, struct lapdm_entity *le)
-{
- if (!le->l3_cb) {
- msgb_free(msg);
- return -EIO;
- }
-
- /* call the layer2 message handler that is registered */
- return le->l3_cb(msg, le, le->l3_ctx);
-}
-
-/* write a frame into the tx queue */
-static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg,
- uint8_t chan_nr, uint8_t link_id, uint8_t pad)
-{
- struct lapdm_entity *le = dl->entity;
- struct osmo_phsap_prim pp;
-
- /* if there is a pending message, queue it */
- if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) {
- *msgb_push(msg, 1) = pad;
- *msgb_push(msg, 1) = link_id;
- *msgb_push(msg, 1) = chan_nr;
- msgb_enqueue(&dl->dl.tx_queue, msg);
- return -EBUSY;
- }
-
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA,
- PRIM_OP_REQUEST, msg);
- pp.u.data.chan_nr = chan_nr;
- pp.u.data.link_id = link_id;
-
- /* send the frame now */
- le->tx_pending = 0; /* disabled flow control */
- lapdm_pad_msgb(msg, pad);
-
- return le->l1_prim_cb(&pp.oph, le->l1_ctx);
-}
-
-static struct msgb *tx_dequeue_msgb(struct lapdm_entity *le)
-{
- struct lapdm_datalink *dl;
- int last = le->last_tx_dequeue;
- int i = last, n = ARRAY_SIZE(le->datalink);
- struct msgb *msg = NULL;
-
- /* round-robin dequeue */
- do {
- /* next */
- i = (i + 1) % n;
- dl = &le->datalink[i];
- if ((msg = msgb_dequeue(&dl->dl.tx_queue)))
- break;
- } while (i != last);
-
- if (msg) {
- /* Set last dequeue position */
- le->last_tx_dequeue = i;
- }
-
- return msg;
-}
-
-/*! \brief dequeue a msg that's pending transmission via L1 and wrap it into
- * a osmo_phsap_prim */
-int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp)
-{
- struct msgb *msg;
- uint8_t pad;
-
- msg = tx_dequeue_msgb(le);
- if (!msg)
- return -ENODEV;
-
- /* if we have a message, send PH-DATA.req */
- osmo_prim_init(&pp->oph, SAP_GSM_PH, PRIM_PH_DATA,
- PRIM_OP_REQUEST, msg);
-
- /* Pull chan_nr and link_id */
- pp->u.data.chan_nr = *msg->data;
- msgb_pull(msg, 1);
- pp->u.data.link_id = *msg->data;
- msgb_pull(msg, 1);
- pad = *msg->data;
- msgb_pull(msg, 1);
-
- /* Pad the frame, we can transmit now */
- lapdm_pad_msgb(msg, pad);
-
- return 0;
-}
-
-/* get next frame from the tx queue. because the ms has multiple datalinks,
- * each datalink's queue is read round-robin.
- */
-static int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
-{
- struct osmo_phsap_prim pp;
-
- /* we may send again */
- le->tx_pending = 0;
-
- /* free confirm message */
- if (msg)
- msgb_free(msg);
-
- if (lapdm_phsap_dequeue_prim(le, &pp) < 0) {
- /* no message in all queues */
-
- /* If user didn't request PH-EMPTY_FRAME.req, abort */
- if (!(le->flags & LAPDM_ENT_F_EMPTY_FRAME))
- return 0;
-
- /* otherwise, send PH-EMPTY_FRAME.req */
- osmo_prim_init(&pp.oph, SAP_GSM_PH,
- PRIM_PH_EMPTY_FRAME,
- PRIM_OP_REQUEST, NULL);
- } else {
- le->tx_pending = 1;
- }
-
- return le->l1_prim_cb(&pp.oph, le->l1_ctx);
-}
-
-/* Create RSLms various RSLms messages */
-static int send_rslms_rll_l3(uint8_t msg_type, struct lapdm_msg_ctx *mctx,
- struct msgb *msg)
-{
- /* Add the RSL + RLL header */
- rsl_rll_push_l3(msg, msg_type, mctx->chan_nr, mctx->link_id, 1);
-
- /* send off the RSLms message to L3 */
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-/* Take a B4 format message from L1 and create RSLms UNIT DATA IND */
-static int send_rslms_rll_l3_ui(struct lapdm_msg_ctx *mctx, struct msgb *msg)
-{
- uint8_t l3_len = msg->tail - (uint8_t *)msgb_l3(msg);
- struct abis_rsl_rll_hdr *rllh;
-
- /* Add the RSL + RLL header */
- msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
- msgb_push(msg, 2 + 2);
- rsl_rll_push_hdr(msg, RSL_MT_UNIT_DATA_IND, mctx->chan_nr,
- mctx->link_id, 1);
- rllh = (struct abis_rsl_rll_hdr *)msgb_l2(msg);
-
- rllh->data[0] = RSL_IE_TIMING_ADVANCE;
- rllh->data[1] = mctx->ta_ind;
-
- rllh->data[2] = RSL_IE_MS_POWER;
- rllh->data[3] = mctx->tx_power_ind;
-
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-static int send_rll_simple(uint8_t msg_type, struct lapdm_msg_ctx *mctx)
-{
- struct msgb *msg;
-
- msg = rsl_rll_simple(msg_type, mctx->chan_nr, mctx->link_id, 1);
-
- /* send off the RSLms message to L3 */
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-static int rsl_rll_error(uint8_t cause, struct lapdm_msg_ctx *mctx)
-{
- struct msgb *msg;
-
- LOGP(DLLAPD, LOGL_NOTICE, "sending MDL-ERROR-IND %d\n", cause);
- msg = rsl_rll_simple(RSL_MT_ERROR_IND, mctx->chan_nr, mctx->link_id, 1);
- msgb_tlv_put(msg, RSL_IE_RLM_CAUSE, 1, &cause);
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-/* DLSAP L2 -> L3 (RSLms) */
-static int send_rslms_dlsap(struct osmo_dlsap_prim *dp,
- struct lapd_msg_ctx *lctx)
-{
- struct lapd_datalink *dl = lctx->dl;
- struct lapdm_datalink *mdl =
- container_of(dl, struct lapdm_datalink, dl);
- struct lapdm_msg_ctx *mctx = &mdl->mctx;
- uint8_t rll_msg = 0;
-
- switch (OSMO_PRIM_HDR(&dp->oph)) {
- case OSMO_PRIM(PRIM_DL_EST, PRIM_OP_INDICATION):
- rll_msg = RSL_MT_EST_IND;
- break;
- case OSMO_PRIM(PRIM_DL_EST, PRIM_OP_CONFIRM):
- rll_msg = RSL_MT_EST_CONF;
- break;
- case OSMO_PRIM(PRIM_DL_DATA, PRIM_OP_INDICATION):
- rll_msg = RSL_MT_DATA_IND;
- break;
- case OSMO_PRIM(PRIM_DL_UNIT_DATA, PRIM_OP_INDICATION):
- return send_rslms_rll_l3_ui(mctx, dp->oph.msg);
- case OSMO_PRIM(PRIM_DL_REL, PRIM_OP_INDICATION):
- rll_msg = RSL_MT_REL_IND;
- break;
- case OSMO_PRIM(PRIM_DL_REL, PRIM_OP_CONFIRM):
- rll_msg = RSL_MT_REL_CONF;
- break;
- case OSMO_PRIM(PRIM_DL_SUSP, PRIM_OP_CONFIRM):
- rll_msg = RSL_MT_SUSP_CONF;
- break;
- case OSMO_PRIM(PRIM_MDL_ERROR, PRIM_OP_INDICATION):
- rsl_rll_error(dp->u.error_ind.cause, mctx);
- if (dp->oph.msg)
- msgb_free(dp->oph.msg);
- return 0;
- }
-
- if (!rll_msg) {
- LOGP(DLLAPD, LOGL_ERROR, "Unsupported op %d, prim %d. Please "
- "fix!\n", dp->oph.primitive, dp->oph.operation);
- return -EINVAL;
- }
-
- if (!dp->oph.msg)
- return send_rll_simple(rll_msg, mctx);
-
- return send_rslms_rll_l3(rll_msg, mctx, dp->oph.msg);
-}
-
-/* send a data frame to layer 1 */
-static int lapdm_send_ph_data_req(struct lapd_msg_ctx *lctx, struct msgb *msg)
-{
- uint8_t l3_len = msg->tail - msg->data;
- struct lapd_datalink *dl = lctx->dl;
- struct lapdm_datalink *mdl =
- container_of(dl, struct lapdm_datalink, dl);
- struct lapdm_msg_ctx *mctx = &mdl->mctx;
- int format = lctx->format;
-
- /* prepend l2 header */
- msg->l2h = msgb_push(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(lctx->lpd, lctx->sapi, lctx->cr);
- /* EA is set here too */
- switch (format) {
- case LAPD_FORM_I:
- msg->l2h[1] = LAPDm_CTRL_I(lctx->n_recv, lctx->n_send,
- lctx->p_f);
- break;
- case LAPD_FORM_S:
- msg->l2h[1] = LAPDm_CTRL_S(lctx->n_recv, lctx->s_u, lctx->p_f);
- break;
- case LAPD_FORM_U:
- msg->l2h[1] = LAPDm_CTRL_U(lctx->s_u, lctx->p_f);
- break;
- default:
- msgb_free(msg);
- return -EINVAL;
- }
- msg->l2h[2] = LAPDm_LEN(l3_len); /* EL is set here too */
- if (lctx->more)
- msg->l2h[2] |= LAPDm_MORE;
-
- /* add ACCH header with last indicated tx-power and TA */
- if ((mctx->link_id & 0x40)) {
- struct lapdm_entity *le = mdl->entity;
-
- msg->l2h = msgb_push(msg, 2);
- msg->l2h[0] = le->tx_power;
- msg->l2h[1] = le->ta;
- }
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- 23);
-}
-
-/* input into layer2 (from layer 1) */
-static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le,
- uint8_t chan_nr, uint8_t link_id)
-{
- uint8_t cbits = chan_nr >> 3;
- uint8_t sapi; /* we cannot take SAPI from link_id, as L1 has no clue */
- struct lapdm_msg_ctx mctx;
- struct lapd_msg_ctx lctx;
- int rc = 0;
- int n201;
-
- /* when we reach here, we have a msgb with l2h pointing to the raw
- * 23byte mac block. The l1h has already been purged. */
-
- memset(&mctx, 0, sizeof(mctx));
- mctx.chan_nr = chan_nr;
- mctx.link_id = link_id;
-
- /* check for L1 chan_nr/link_id and determine LAPDm hdr format */
- if (cbits == 0x10 || cbits == 0x12) {
- /* Format Bbis is used on BCCH and CCCH(PCH, NCH and AGCH) */
- mctx.lapdm_fmt = LAPDm_FMT_Bbis;
- n201 = N201_Bbis;
- sapi = 0;
- } else {
- if (mctx.link_id & 0x40) {
- /* It was received from network on SACCH */
-
- /* If UI on SACCH sent by BTS, lapdm_fmt must be B4 */
- if (le->mode == LAPDM_MODE_MS
- && LAPDm_CTRL_is_U(msg->l2h[3])
- && LAPDm_CTRL_U_BITS(msg->l2h[3]) == 0) {
- mctx.lapdm_fmt = LAPDm_FMT_B4;
- n201 = N201_B4;
- LOGP(DLLAPD, LOGL_INFO, "fmt=B4\n");
- } else {
- mctx.lapdm_fmt = LAPDm_FMT_B;
- n201 = N201_AB_SACCH;
- LOGP(DLLAPD, LOGL_INFO, "fmt=B\n");
- }
- /* SACCH frames have a two-byte L1 header that
- * OsmocomBB L1 doesn't strip */
- mctx.tx_power_ind = msg->l2h[0] & 0x1f;
- mctx.ta_ind = msg->l2h[1];
- msgb_pull(msg, 2);
- msg->l2h += 2;
- sapi = (msg->l2h[0] >> 2) & 7;
- } else {
- mctx.lapdm_fmt = LAPDm_FMT_B;
- LOGP(DLLAPD, LOGL_INFO, "fmt=B\n");
- n201 = N201_AB_SDCCH;
- sapi = (msg->l2h[0] >> 2) & 7;
- }
- }
-
- mctx.dl = datalink_for_sapi(le, sapi);
- /* G.2.1 No action on frames containing an unallocated SAPI. */
- if (!mctx.dl) {
- LOGP(DLLAPD, LOGL_NOTICE, "Received frame for unsupported "
- "SAPI %d!\n", sapi);
- msgb_free(msg);
- return -EIO;
- }
-
- switch (mctx.lapdm_fmt) {
- case LAPDm_FMT_A:
- case LAPDm_FMT_B:
- case LAPDm_FMT_B4:
- lctx.dl = &mctx.dl->dl;
- /* obtain SAPI from address field */
- mctx.link_id |= LAPDm_ADDR_SAPI(msg->l2h[0]);
- /* G.2.3 EA bit set to "0" is not allowed in GSM */
- if (!LAPDm_ADDR_EA(msg->l2h[0])) {
- LOGP(DLLAPD, LOGL_NOTICE, "EA bit 0 is not allowed in "
- "GSM\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, &mctx);
- return -EINVAL;
- }
- /* adress field */
- lctx.lpd = LAPDm_ADDR_LPD(msg->l2h[0]);
- lctx.sapi = LAPDm_ADDR_SAPI(msg->l2h[0]);
- lctx.cr = LAPDm_ADDR_CR(msg->l2h[0]);
- /* command field */
- if (LAPDm_CTRL_is_I(msg->l2h[1])) {
- lctx.format = LAPD_FORM_I;
- lctx.n_send = LAPDm_CTRL_I_Ns(msg->l2h[1]);
- lctx.n_recv = LAPDm_CTRL_Nr(msg->l2h[1]);
- } else if (LAPDm_CTRL_is_S(msg->l2h[1])) {
- lctx.format = LAPD_FORM_S;
- lctx.n_recv = LAPDm_CTRL_Nr(msg->l2h[1]);
- lctx.s_u = LAPDm_CTRL_S_BITS(msg->l2h[1]);
- } else if (LAPDm_CTRL_is_U(msg->l2h[1])) {
- lctx.format = LAPD_FORM_U;
- lctx.s_u = LAPDm_CTRL_U_BITS(msg->l2h[1]);
- } else
- lctx.format = LAPD_FORM_UKN;
- lctx.p_f = LAPDm_CTRL_PF_BIT(msg->l2h[1]);
- if (lctx.sapi != LAPDm_SAPI_NORMAL
- && lctx.sapi != LAPDm_SAPI_SMS
- && lctx.format == LAPD_FORM_U
- && lctx.s_u == LAPDm_U_UI) {
- /* 5.3.3 UI frames with invalid SAPI values shall be
- * discarded
- */
- LOGP(DLLAPD, LOGL_INFO, "sapi=%u (discarding)\n",
- lctx.sapi);
- msgb_free(msg);
- return 0;
- }
- if (mctx.lapdm_fmt == LAPDm_FMT_B4) {
- lctx.n201 = n201;
- lctx.length = n201;
- lctx.more = 0;
- msg->l3h = msg->l2h + 2;
- msgb_pull_l2h(msg);
- } else {
- /* length field */
- if (!(msg->l2h[2] & LAPDm_EL)) {
- /* G.4.1 If the EL bit is set to "0", an
- * MDL-ERROR-INDICATION primitive with cause
- * "frame not implemented" is sent to the
- * mobile management entity. */
- LOGP(DLLAPD, LOGL_NOTICE, "we don't support "
- "multi-octet length\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, &mctx);
- return -EINVAL;
- }
- lctx.n201 = n201;
- lctx.length = msg->l2h[2] >> 2;
- lctx.more = !!(msg->l2h[2] & LAPDm_MORE);
- msg->l3h = msg->l2h + 3;
- msgb_pull_l2h(msg);
- }
- /* store context for messages from lapd */
- memcpy(&mctx.dl->mctx, &mctx, sizeof(mctx.dl->mctx));
- /* send to LAPD */
- rc = lapd_ph_data_ind(msg, &lctx);
- break;
- case LAPDm_FMT_Bter:
- /* FIXME */
- msgb_free(msg);
- break;
- case LAPDm_FMT_Bbis:
- /* directly pass up to layer3 */
- LOGP(DLLAPD, LOGL_INFO, "fmt=Bbis UI\n");
- msg->l3h = msg->l2h;
- msgb_pull_l2h(msg);
- rc = send_rslms_rll_l3(RSL_MT_UNIT_DATA_IND, &mctx, msg);
- break;
- default:
- msgb_free(msg);
- }
-
- return rc;
-}
-
-/* input into layer2 (from layer 1) */
-static int l2_ph_rach_ind(struct lapdm_entity *le, uint8_t ra, uint32_t fn, uint8_t acc_delay)
-{
- struct abis_rsl_cchan_hdr *ch;
- struct gsm48_req_ref req_ref;
- struct gsm_time gt;
- struct msgb *msg = msgb_alloc_headroom(512, 64, "RSL CHAN RQD");
-
- msg->l2h = msgb_push(msg, sizeof(*ch));
- ch = (struct abis_rsl_cchan_hdr *)msg->l2h;
- rsl_init_cchan_hdr(ch, RSL_MT_CHAN_RQD);
- ch->chan_nr = RSL_CHAN_RACH;
-
- /* generate a RSL CHANNEL REQUIRED message */
- gsm_fn2gsmtime(&gt, fn);
- req_ref.ra = ra;
- req_ref.t1 = gt.t1; /* FIXME: modulo? */
- req_ref.t2 = gt.t2;
- req_ref.t3_low = gt.t3 & 7;
- req_ref.t3_high = gt.t3 >> 3;
-
- msgb_tv_fixed_put(msg, RSL_IE_REQ_REFERENCE, 3, (uint8_t *) &req_ref);
- msgb_tv_put(msg, RSL_IE_ACCESS_DELAY, acc_delay);
-
- return rslms_sendmsg(msg, le);
-}
-
-static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t frame_nr);
-
-/*! \brief Receive a PH-SAP primitive from L1 */
-int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
-{
- struct osmo_phsap_prim *pp = (struct osmo_phsap_prim *) oph;
- int rc = 0;
-
- if (oph->sap != SAP_GSM_PH) {
- LOGP(DLLAPD, LOGL_ERROR, "primitive for unknown SAP %u\n",
- oph->sap);
- return -ENODEV;
- }
-
- switch (oph->primitive) {
- case PRIM_PH_DATA:
- if (oph->operation != PRIM_OP_INDICATION) {
- LOGP(DLLAPD, LOGL_ERROR, "PH_DATA is not INDICATION %u\n",
- oph->operation);
- return -ENODEV;
- }
- rc = l2_ph_data_ind(oph->msg, le, pp->u.data.chan_nr,
- pp->u.data.link_id);
- break;
- case PRIM_PH_RTS:
- if (oph->operation != PRIM_OP_INDICATION) {
- LOGP(DLLAPD, LOGL_ERROR, "PH_RTS is not INDICATION %u\n",
- oph->operation);
- return -ENODEV;
- }
- rc = l2_ph_data_conf(oph->msg, le);
- break;
- case PRIM_PH_RACH:
- switch (oph->operation) {
- case PRIM_OP_INDICATION:
- rc = l2_ph_rach_ind(le, pp->u.rach_ind.ra, pp->u.rach_ind.fn,
- pp->u.rach_ind.acc_delay);
- break;
- case PRIM_OP_CONFIRM:
- rc = l2_ph_chan_conf(oph->msg, le, pp->u.rach_ind.fn);
- break;
- default:
- return -EIO;
- }
- break;
- }
-
- return rc;
-}
-
-
-/* L3 -> L2 / RSLMS -> LAPDm */
-
-/* Set LAPDm context for established connection */
-static int set_lapdm_context(struct lapdm_datalink *dl, uint8_t chan_nr,
- uint8_t link_id, int n201, uint8_t sapi)
-{
- memset(&dl->mctx, 0, sizeof(dl->mctx));
- dl->mctx.dl = dl;
- dl->mctx.chan_nr = chan_nr;
- dl->mctx.link_id = link_id;
- dl->dl.lctx.dl = &dl->dl;
- dl->dl.lctx.n201 = n201;
- dl->dl.lctx.sapi = sapi;
-
- return 0;
-}
-
-/* L3 requests establishment of data link */
-static int rslms_rx_rll_est_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = rllh->link_id & 7;
- struct tlv_parsed tv;
- uint8_t length;
- uint8_t n201 = (rllh->link_id & 0x40) ? N201_AB_SACCH : N201_AB_SDCCH;
- struct osmo_dlsap_prim dp;
-
- /* Set LAPDm context for established connection */
- set_lapdm_context(dl, chan_nr, link_id, n201, sapi);
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg) - sizeof(*rllh));
- if (TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
- /* contention resolution establishment procedure */
- if (sapi != 0) {
- /* According to clause 6, the contention resolution
- * procedure is only permitted with SAPI value 0 */
- LOGP(DLLAPD, LOGL_ERROR, "SAPI != 0 but contention"
- "resolution (discarding)\n");
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- }
- /* transmit a SABM command with the P bit set to "1". The SABM
- * command shall contain the layer 3 message unit */
- length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- } else {
- /* normal establishment procedure */
- msg->l3h = msg->l2h + sizeof(*rllh);
- length = 0;
- }
-
- /* check if the layer3 message length exceeds N201 */
- if (length > n201) {
- LOGP(DLLAPD, LOGL_ERROR, "frame too large: %d > N201(%d) "
- "(discarding)\n", length, n201);
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- }
-
- /* Remove RLL header from msgb and set length to L3-info */
- msgb_pull_l2h(msg);
- msg->len = length;
- msg->tail = msg->l3h + length;
-
- /* prepare prim */
- osmo_prim_init(&dp.oph, 0, PRIM_DL_EST, PRIM_OP_REQUEST, msg);
-
- /* send to L2 */
- return lapd_recv_dlsap(&dp, &dl->dl.lctx);
-}
-
-/* L3 requests transfer of unnumbered information */
-static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct lapdm_entity *le = dl->entity;
- int ui_bts = (le->mode == LAPDM_MODE_BTS);
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = link_id & 7;
- struct tlv_parsed tv;
- int length;
-
- /* check if the layer3 message length exceeds N201 */
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
-
- if (TLVP_PRESENT(&tv, RSL_IE_TIMING_ADVANCE)) {
- le->ta = *TLVP_VAL(&tv, RSL_IE_TIMING_ADVANCE);
- }
- if (TLVP_PRESENT(&tv, RSL_IE_MS_POWER)) {
- le->tx_power = *TLVP_VAL(&tv, RSL_IE_MS_POWER);
- }
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLLAPD, LOGL_ERROR, "unit data request without message "
- "error\n");
- msgb_free(msg);
- return -EINVAL;
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
- length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- /* check if the layer3 message length exceeds N201 */
- if (length + 4 + !ui_bts > 23) {
- LOGP(DLLAPD, LOGL_ERROR, "frame too large: %d > N201(%d) "
- "(discarding)\n", length, 18 + ui_bts);
- msgb_free(msg);
- return -EIO;
- }
-
- LOGP(DLLAPD, LOGL_INFO, "sending unit data (tx_power=%d, ta=%d)\n",
- le->tx_power, le->ta);
-
- /* Remove RLL header from msgb and set length to L3-info */
- msgb_pull_l2h(msg);
- msg->len = length;
- msg->tail = msg->l3h + length;
-
- /* Push L1 + LAPDm header on msgb */
- msg->l2h = msgb_push(msg, 4 + !ui_bts);
- msg->l2h[0] = le->tx_power;
- msg->l2h[1] = le->ta;
- msg->l2h[2] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, dl->dl.cr.loc2rem.cmd);
- msg->l2h[3] = LAPDm_CTRL_U(LAPDm_U_UI, 0);
- if (!ui_bts)
- msg->l2h[4] = LAPDm_LEN(length);
-
- /* Tramsmit */
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, 23);
-}
-
-/* L3 requests transfer of acknowledged information */
-static int rslms_rx_rll_data_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct tlv_parsed tv;
- int length;
- struct osmo_dlsap_prim dp;
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLLAPD, LOGL_ERROR, "data request without message "
- "error\n");
- msgb_free(msg);
- return -EINVAL;
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
- length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
-
- /* Remove RLL header from msgb and set length to L3-info */
- msgb_pull_l2h(msg);
- msg->len = length;
- msg->tail = msg->l3h + length;
-
- /* prepare prim */
- osmo_prim_init(&dp.oph, 0, PRIM_DL_DATA, PRIM_OP_REQUEST, msg);
-
- /* send to L2 */
- return lapd_recv_dlsap(&dp, &dl->dl.lctx);
-}
-
-/* L3 requests suspension of data link */
-static int rslms_rx_rll_susp_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t sapi = rllh->link_id & 7;
- struct osmo_dlsap_prim dp;
-
- if (sapi != 0) {
- LOGP(DLLAPD, LOGL_ERROR, "SAPI != 0 while suspending\n");
- msgb_free(msg);
- return -EINVAL;
- }
-
- /* prepare prim */
- osmo_prim_init(&dp.oph, 0, PRIM_DL_SUSP, PRIM_OP_REQUEST, msg);
-
- /* send to L2 */
- return lapd_recv_dlsap(&dp, &dl->dl.lctx);
-}
-
-/* L3 requests resume of data link */
-static int rslms_rx_rll_res_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int msg_type = rllh->c.msg_type;
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = rllh->link_id & 7;
- struct tlv_parsed tv;
- uint8_t length;
- uint8_t n201 = (rllh->link_id & 0x40) ? N201_AB_SACCH : N201_AB_SDCCH;
- struct osmo_dlsap_prim dp;
-
- /* Set LAPDm context for established connection */
- set_lapdm_context(dl, chan_nr, link_id, n201, sapi);
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLLAPD, LOGL_ERROR, "resume without message error\n");
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
- length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
-
- /* Remove RLL header from msgb and set length to L3-info */
- msgb_pull_l2h(msg);
- msg->len = length;
- msg->tail = msg->l3h + length;
-
- /* prepare prim */
- osmo_prim_init(&dp.oph, 0, (msg_type == RSL_MT_RES_REQ) ? PRIM_DL_RES
- : PRIM_DL_RECON, PRIM_OP_REQUEST, msg);
-
- /* send to L2 */
- return lapd_recv_dlsap(&dp, &dl->dl.lctx);
-}
-
-/* L3 requests release of data link */
-static int rslms_rx_rll_rel_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t mode = 0;
- struct osmo_dlsap_prim dp;
-
- /* get release mode */
- if (rllh->data[0] == RSL_IE_RELEASE_MODE)
- mode = rllh->data[1] & 1;
-
- /* Pull rllh */
- msgb_pull_l2h(msg);
-
- /* 04.06 3.8.3: No information field is permitted with the DISC
- * command. */
- msg->len = 0;
- msg->tail = msg->l3h = msg->data;
-
- /* prepare prim */
- osmo_prim_init(&dp.oph, 0, PRIM_DL_REL, PRIM_OP_REQUEST, msg);
- dp.u.rel_req.mode = mode;
-
- /* send to L2 */
- return lapd_recv_dlsap(&dp, &dl->dl.lctx);
-}
-
-/* L3 requests channel in idle state */
-static int rslms_rx_chan_rqd(struct lapdm_channel *lc, struct msgb *msg)
-{
- struct abis_rsl_cchan_hdr *cch = msgb_l2(msg);
- void *l1ctx = lc->lapdm_dcch.l1_ctx;
- struct osmo_phsap_prim pp;
-
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_RACH,
- PRIM_OP_REQUEST, NULL);
-
- if (msgb_l2len(msg) < sizeof(*cch) + 4 + 2 + 2) {
- LOGP(DLLAPD, LOGL_ERROR, "Message too short for CHAN RQD!\n");
- return -EINVAL;
- }
- if (cch->data[0] != RSL_IE_REQ_REFERENCE) {
- LOGP(DLLAPD, LOGL_ERROR, "Missing REQ REFERENCE IE\n");
- return -EINVAL;
- }
- pp.u.rach_req.ra = cch->data[1];
- pp.u.rach_req.offset = ((cch->data[2] & 0x7f) << 8) | cch->data[3];
- pp.u.rach_req.is_combined_ccch = cch->data[2] >> 7;
-
- if (cch->data[4] != RSL_IE_ACCESS_DELAY) {
- LOGP(DLLAPD, LOGL_ERROR, "Missing ACCESS_DELAY IE\n");
- return -EINVAL;
- }
- /* TA = 0 - delay */
- pp.u.rach_req.ta = 0 - cch->data[5];
-
- if (cch->data[6] != RSL_IE_MS_POWER) {
- LOGP(DLLAPD, LOGL_ERROR, "Missing MS POWER IE\n");
- return -EINVAL;
- }
- pp.u.rach_req.tx_power = cch->data[7];
-
- msgb_free(msg);
-
- return lc->lapdm_dcch.l1_prim_cb(&pp.oph, l1ctx);
-}
-
-/* L1 confirms channel request */
-static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t frame_nr)
-{
- struct abis_rsl_cchan_hdr *ch;
- struct gsm_time tm;
- struct gsm48_req_ref *ref;
-
- gsm_fn2gsmtime(&tm, frame_nr);
-
- msgb_pull_l2h(msg);
- msg->l2h = msgb_push(msg, sizeof(*ch) + sizeof(*ref));
- ch = (struct abis_rsl_cchan_hdr *)msg->l2h;
- rsl_init_cchan_hdr(ch, RSL_MT_CHAN_CONF);
- ch->chan_nr = RSL_CHAN_RACH;
- ch->data[0] = RSL_IE_REQ_REFERENCE;
- ref = (struct gsm48_req_ref *) (ch->data + 1);
- ref->t1 = tm.t1;
- ref->t2 = tm.t2;
- ref->t3_low = tm.t3 & 0x7;
- ref->t3_high = tm.t3 >> 3;
-
- return rslms_sendmsg(msg, le);
-}
-
-/* incoming RSLms RLL message from L3 */
-static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int msg_type = rllh->c.msg_type;
- uint8_t sapi = rllh->link_id & 7;
- struct lapdm_entity *le;
- struct lapdm_datalink *dl;
- int rc = 0;
-
- if (msgb_l2len(msg) < sizeof(*rllh)) {
- LOGP(DLLAPD, LOGL_ERROR, "Message too short for RLL hdr!\n");
- msgb_free(msg);
- return -EINVAL;
- }
-
- if (rllh->link_id & 0x40)
- le = &lc->lapdm_acch;
- else
- le = &lc->lapdm_dcch;
-
- /* G.2.1 No action schall be taken on frames containing an unallocated
- * SAPI.
- */
- dl = datalink_for_sapi(le, sapi);
- if (!dl) {
- LOGP(DLLAPD, LOGL_ERROR, "No instance for SAPI %d!\n", sapi);
- msgb_free(msg);
- return -EINVAL;
- }
-
- LOGP(DLLAPD, LOGL_INFO, "(%p) RLL Message '%s' received. (sapi %d)\n",
- lc->name, rsl_msg_name(msg_type), sapi);
-
- switch (msg_type) {
- case RSL_MT_UNIT_DATA_REQ:
- rc = rslms_rx_rll_udata_req(msg, dl);
- break;
- case RSL_MT_EST_REQ:
- rc = rslms_rx_rll_est_req(msg, dl);
- break;
- case RSL_MT_DATA_REQ:
- rc = rslms_rx_rll_data_req(msg, dl);
- break;
- case RSL_MT_SUSP_REQ:
- rc = rslms_rx_rll_susp_req(msg, dl);
- break;
- case RSL_MT_RES_REQ:
- rc = rslms_rx_rll_res_req(msg, dl);
- break;
- case RSL_MT_RECON_REQ:
- rc = rslms_rx_rll_res_req(msg, dl);
- break;
- case RSL_MT_REL_REQ:
- rc = rslms_rx_rll_rel_req(msg, dl);
- break;
- default:
- LOGP(DLLAPD, LOGL_NOTICE, "Message unsupported.\n");
- msgb_free(msg);
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-/* incoming RSLms COMMON CHANNEL message from L3 */
-static int rslms_rx_com_chan(struct msgb *msg, struct lapdm_channel *lc)
-{
- struct abis_rsl_cchan_hdr *cch = msgb_l2(msg);
- int msg_type = cch->c.msg_type;
- int rc = 0;
-
- if (msgb_l2len(msg) < sizeof(*cch)) {
- LOGP(DLLAPD, LOGL_ERROR, "Message too short for COM CHAN hdr!\n");
- return -EINVAL;
- }
-
- switch (msg_type) {
- case RSL_MT_CHAN_RQD:
- /* create and send RACH request */
- rc = rslms_rx_chan_rqd(lc, msg);
- break;
- default:
- LOGP(DLLAPD, LOGL_NOTICE, "Unknown COMMON CHANNEL msg %d!\n",
- msg_type);
- msgb_free(msg);
- return 0;
- }
-
- return rc;
-}
-
-/*! \brief Receive a RSLms \ref msgb from Layer 3 */
-int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc)
-{
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
- int rc = 0;
-
- if (msgb_l2len(msg) < sizeof(*rslh)) {
- LOGP(DLLAPD, LOGL_ERROR, "Message too short RSL hdr!\n");
- return -EINVAL;
- }
-
- switch (rslh->msg_discr & 0xfe) {
- case ABIS_RSL_MDISC_RLL:
- rc = rslms_rx_rll(msg, lc);
- break;
- case ABIS_RSL_MDISC_COM_CHAN:
- rc = rslms_rx_com_chan(msg, lc);
- break;
- default:
- LOGP(DLLAPD, LOGL_ERROR, "unknown RSLms message "
- "discriminator 0x%02x", rslh->msg_discr);
- msgb_free(msg);
- return -EINVAL;
- }
-
- return rc;
-}
-
-/*! \brief Set the \ref lapdm_mode of a LAPDm entity */
-int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode)
-{
- int i;
- enum lapd_mode lm;
-
- switch (mode) {
- case LAPDM_MODE_MS:
- lm = LAPD_MODE_USER;
- break;
- case LAPDM_MODE_BTS:
- lm = LAPD_MODE_NETWORK;
- break;
- default:
- return -EINVAL;
- }
-
- for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
- lapd_set_mode(&le->datalink[i].dl, lm);
- }
-
- le->mode = mode;
-
- return 0;
-}
-
-/*! \brief Set the \ref lapdm_mode of a LAPDm channel*/
-int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode)
-{
- int rc;
-
- rc = lapdm_entity_set_mode(&lc->lapdm_dcch, mode);
- if (rc < 0)
- return rc;
-
- return lapdm_entity_set_mode(&lc->lapdm_acch, mode);
-}
-
-/*! \brief Set the L1 callback and context of a LAPDm channel */
-void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx)
-{
- lc->lapdm_dcch.l1_prim_cb = cb;
- lc->lapdm_acch.l1_prim_cb = cb;
- lc->lapdm_dcch.l1_ctx = ctx;
- lc->lapdm_acch.l1_ctx = ctx;
-}
-
-/*! \brief Set the L3 callback and context of a LAPDm channel */
-void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx)
-{
- lc->lapdm_dcch.l3_cb = cb;
- lc->lapdm_acch.l3_cb = cb;
- lc->lapdm_dcch.l3_ctx = ctx;
- lc->lapdm_acch.l3_ctx = ctx;
-}
-
-/*! \brief Reset an entire LAPDm entity and all its datalinks */
-void lapdm_entity_reset(struct lapdm_entity *le)
-{
- struct lapdm_datalink *dl;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
- dl = &le->datalink[i];
- lapd_dl_reset(&dl->dl);
- }
-}
-
-/*! \brief Reset a LAPDm channel with all its entities */
-void lapdm_channel_reset(struct lapdm_channel *lc)
-{
- lapdm_entity_reset(&lc->lapdm_dcch);
- lapdm_entity_reset(&lc->lapdm_acch);
-}
-
-/*! \brief Set the flags of a LAPDm entity */
-void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags)
-{
- le->flags = flags;
-}
-
-/*! \brief Set the flags of all LAPDm entities in a LAPDm channel */
-void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags)
-{
- lapdm_entity_set_flags(&lc->lapdm_dcch, flags);
- lapdm_entity_set_flags(&lc->lapdm_acch, flags);
-}
-
-/*! @} */
diff --git a/src/shared/libosmocore/src/gsm/libosmogsm.map b/src/shared/libosmocore/src/gsm/libosmogsm.map
deleted file mode 100644
index 33738881..00000000
--- a/src/shared/libosmocore/src/gsm/libosmogsm.map
+++ /dev/null
@@ -1,236 +0,0 @@
-LIBOSMOGSM_1.0 {
-global:
-
-abis_nm_adm_state_names;
-abis_nm_att_settable;
-abis_nm_avail_name;
-abis_nm_chcomb4pchan;
-abis_nm_debugp_foh;
-abis_nm_event_type_name;
-abis_nm_nack_cause_name;
-abis_nm_nack_name;
-abis_nm_att_tlvdef;
-abis_nm_obj_class_names;
-abis_nm_opstate_name;
-abis_nm_nacks;
-abis_nm_no_ack_nack;
-abis_nm_pchan4chcomb;
-abis_nm_reports;
-abis_nm_severity_name;
-abis_nm_sw_load_msgs;
-abis_nm_test_name;
-
-osmo_sitype_strs;
-
-comp128;
-dbm2rxlev;
-
-gprs_cipher_gen_input_i;
-gprs_cipher_gen_input_ui;
-gprs_cipher_load;
-gprs_cipher_register;
-gprs_cipher_run;
-gprs_cipher_supported;
-gprs_tlli_type;
-gprs_tmsi2tlli;
-
-gsm0480_create_notifySS;
-gsm0480_create_unstructuredSS_Notify;
-gsm0480_create_ussd_resp;
-gsm0480_decode_ussd_request;
-gsm0480_wrap_facility;
-gsm0480_wrap_invoke;
-
-gsm0502_calc_paging_group;
-
-gsm0808_att_tlvdef;
-gsm0808_bssap_name;
-gsm0808_bssmap_name;
-gsm0808_create_assignment_completed;
-gsm0808_create_assignment_failure;
-gsm0808_create_cipher_complete;
-gsm0808_create_cipher_reject;
-gsm0808_create_classmark_update;
-gsm0808_create_clear_command;
-gsm0808_create_clear_complete;
-gsm0808_create_clear_rqst;
-gsm0808_create_dtap;
-gsm0808_create_layer3;
-gsm0808_create_reset;
-gsm0808_create_sapi_reject;
-gsm0808_prepend_dtap_header;
-
-gsm338_get_sms_alphabet;
-
-gsm340_gen_oa;
-gsm340_gen_scts;
-gsm340_scts;
-gsm340_validity_period;
-
-gsm411_bcdify;
-gsm411_msgb_alloc;
-gsm411_push_cp_header;
-gsm411_push_rp_header;
-gsm411_smc_clear;
-gsm411_smc_init;
-gsm411_smc_recv;
-gsm411_smc_send;
-gsm411_smr_clear;
-gsm411_smr_init;
-gsm411_smr_recv;
-gsm411_smr_send;
-gsm411_unbcdify;
-gsm411_cp_cause_strs;
-gsm411_rp_cause_strs;
-
-gsm48_att_tlvdef;
-gsm48_cc_msg_name;
-gsm48_cc_state_name;
-gsm48_construct_ra;
-gsm48_decode_bcd_number;
-gsm48_decode_bearer_cap;
-gsm48_decode_called;
-gsm48_decode_callerid;
-gsm48_decode_calling;
-gsm48_decode_cause;
-gsm48_decode_cccap;
-gsm48_decode_connected;
-gsm48_decode_facility;
-gsm48_decode_freq_list;
-gsm48_decode_keypad;
-gsm48_decode_lai;
-gsm48_decode_notify;
-gsm48_decode_progress;
-gsm48_decode_redirecting;
-gsm48_decode_signal;
-gsm48_decode_ssversion;
-gsm48_decode_useruser;
-gsm48_encode_bcd_number;
-gsm48_encode_bearer_cap;
-gsm48_encode_called;
-gsm48_encode_callerid;
-gsm48_encode_calling;
-gsm48_encode_cause;
-gsm48_encode_cccap;
-gsm48_encode_connected;
-gsm48_encode_facility;
-gsm48_encode_keypad;
-gsm48_encode_more;
-gsm48_encode_notify;
-gsm48_encode_progress;
-gsm48_encode_redirecting;
-gsm48_encode_signal;
-gsm48_encode_ssversion;
-gsm48_encode_useruser;
-gsm48_generate_lai;
-gsm48_generate_mid_from_imsi;
-gsm48_generate_mid_from_tmsi;
-gsm48_mi_to_string;
-gsm48_mm_att_tlvdef;
-gsm48_number_of_paging_subchannels;
-gsm48_parse_ra;
-gsm48_rr_att_tlvdef;
-
-gsm_7bit_decode;
-gsm_7bit_decode_hdr;
-gsm_7bit_encode;
-
-gsm_arfcn2band;
-gsm_arfcn2freq10;
-gsm_band_name;
-gsm_band_parse;
-gsm_fn2gsmtime;
-gsm_get_octet_len;
-gsm_gsmtime2fn;
-
-gsm_milenage;
-gsm_septet_encode;
-gsm_septets2octets;
-
-lapd_dl_exit;
-lapd_dl_init;
-lapd_dl_reset;
-lapd_msgb_alloc;
-lapd_ph_data_ind;
-lapd_recv_dlsap;
-lapd_set_mode;
-lapd_state_names;
-
-lapdm_channel_exit;
-lapdm_channel_init;
-lapdm_channel_reset;
-lapdm_channel_set_flags;
-lapdm_channel_set_l1;
-lapdm_channel_set_l3;
-lapdm_channel_set_mode;
-lapdm_entity_exit;
-lapdm_entity_init;
-lapdm_entity_reset;
-lapdm_entity_set_flags;
-lapdm_entity_set_mode;
-lapdm_phsap_dequeue_prim;
-lapdm_phsap_up;
-lapdm_rslms_recvmsg;
-
-milenage_auts;
-milenage_check;
-milenage_f1;
-milenage_f2345;
-milenage_generate;
-milenage_opc_gen;
-
-ms_class_gmsk_dbm;
-ms_pwr_ctl_lvl;
-ms_pwr_dbm;
-
-osmo_a5;
-osmo_a5_1;
-osmo_a5_2;
-
-osmo_auth_alg_name;
-osmo_auth_alg_parse;
-osmo_auth_gen_vec;
-osmo_auth_gen_vec_auts;
-osmo_auth_load;
-osmo_auth_register;
-osmo_auth_supported;
-
-osmo_rsl2sitype;
-osmo_sitype2rsl;
-
-rr_cause_name;
-
-rsl_att_tlvdef;
-rsl_ccch_conf_to_bs_cc_chans;
-rsl_ccch_conf_to_bs_ccch_sdcch_comb;
-rsl_chan_nr_str;
-rsl_dec_chan_nr;
-rsl_enc_chan_nr;
-rsl_err_name;
-rsl_init_cchan_hdr;
-rsl_init_rll_hdr;
-rsl_ipac_msg_name;
-rsl_msg_name;
-rsl_rll_push_hdr;
-rsl_rll_push_l3;
-rsl_rll_simple;
-rsl_rlm_cause_name;
-
-rxlev2dbm;
-rxlev_stat_dump;
-rxlev_stat_get_next;
-rxlev_stat_input;
-rxlev_stat_reset;
-
-tlv_def_patch;
-tlv_dump;
-tlv_parse;
-tlv_parse_one;
-tvlv_att_def;
-vtvlv_gan_att_def;
-
-gan_msgt_vals;
-gan_pdisc_vals;
-
-local: *;
-};
diff --git a/src/shared/libosmocore/src/gsm/milenage/aes-encblock.c b/src/shared/libosmocore/src/gsm/milenage/aes-encblock.c
deleted file mode 100644
index 8f35caa2..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/aes-encblock.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * AES encrypt_block
- *
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "aes.h"
-#include "aes_wrap.h"
-
-/**
- * aes_128_encrypt_block - Perform one AES 128-bit block operation
- * @key: Key for AES
- * @in: Input data (16 bytes)
- * @out: Output of the AES block operation (16 bytes)
- * Returns: 0 on success, -1 on failure
- */
-int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out)
-{
- void *ctx;
- ctx = aes_encrypt_init(key, 16);
- if (ctx == NULL)
- return -1;
- aes_encrypt(ctx, in, out);
- aes_encrypt_deinit(ctx);
- return 0;
-}
diff --git a/src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c b/src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c
deleted file mode 100644
index 8726aa72..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/aes-internal-enc.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * AES (Rijndael) cipher - encrypt
- *
- * Modifications to public domain implementation:
- * - support only 128-bit keys
- * - cleanup
- * - use C pre-processor to make it easier to change S table access
- * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
- * cost of reduced throughput (quite small difference on Pentium 4,
- * 10-25% when using -O1 or -O2 optimization)
- *
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "crypto.h"
-#include "aes_i.h"
-
-static void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16])
-{
- u32 s0, s1, s2, s3, t0, t1, t2, t3;
- const int Nr = 10;
-#ifndef FULL_UNROLL
- int r;
-#endif /* ?FULL_UNROLL */
-
- /*
- * map byte array block to cipher state
- * and add initial round key:
- */
- s0 = GETU32(pt ) ^ rk[0];
- s1 = GETU32(pt + 4) ^ rk[1];
- s2 = GETU32(pt + 8) ^ rk[2];
- s3 = GETU32(pt + 12) ^ rk[3];
-
-#define ROUND(i,d,s) \
-d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[4 * i]; \
-d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[4 * i + 1]; \
-d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[4 * i + 2]; \
-d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[4 * i + 3]
-
-#ifdef FULL_UNROLL
-
- ROUND(1,t,s);
- ROUND(2,s,t);
- ROUND(3,t,s);
- ROUND(4,s,t);
- ROUND(5,t,s);
- ROUND(6,s,t);
- ROUND(7,t,s);
- ROUND(8,s,t);
- ROUND(9,t,s);
-
- rk += Nr << 2;
-
-#else /* !FULL_UNROLL */
-
- /* Nr - 1 full rounds: */
- r = Nr >> 1;
- for (;;) {
- ROUND(1,t,s);
- rk += 8;
- if (--r == 0)
- break;
- ROUND(0,s,t);
- }
-
-#endif /* ?FULL_UNROLL */
-
-#undef ROUND
-
- /*
- * apply last round and
- * map cipher state to byte array block:
- */
- s0 = TE41(t0) ^ TE42(t1) ^ TE43(t2) ^ TE44(t3) ^ rk[0];
- PUTU32(ct , s0);
- s1 = TE41(t1) ^ TE42(t2) ^ TE43(t3) ^ TE44(t0) ^ rk[1];
- PUTU32(ct + 4, s1);
- s2 = TE41(t2) ^ TE42(t3) ^ TE43(t0) ^ TE44(t1) ^ rk[2];
- PUTU32(ct + 8, s2);
- s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
- PUTU32(ct + 12, s3);
-}
-
-
-void * aes_encrypt_init(const u8 *key, size_t len)
-{
- u32 *rk;
- if (len != 16)
- return NULL;
- rk = os_malloc(AES_PRIV_SIZE);
- if (rk == NULL)
- return NULL;
- rijndaelKeySetupEnc(rk, key);
- return rk;
-}
-
-
-void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
-{
- rijndaelEncrypt(ctx, plain, crypt);
-}
-
-
-void aes_encrypt_deinit(void *ctx)
-{
- os_memset(ctx, 0, AES_PRIV_SIZE);
- os_free(ctx);
-}
diff --git a/src/shared/libosmocore/src/gsm/milenage/aes-internal.c b/src/shared/libosmocore/src/gsm/milenage/aes-internal.c
deleted file mode 100644
index 41612202..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/aes-internal.c
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * AES (Rijndael) cipher
- *
- * Modifications to public domain implementation:
- * - support only 128-bit keys
- * - cleanup
- * - use C pre-processor to make it easier to change S table access
- * - added option (AES_SMALL_TABLES) for reducing code size by about 8 kB at
- * cost of reduced throughput (quite small difference on Pentium 4,
- * 10-25% when using -O1 or -O2 optimization)
- *
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "crypto.h"
-#include "aes_i.h"
-
-/*
- * rijndael-alg-fst.c
- *
- * @version 3.0 (December 2000)
- *
- * Optimised ANSI C code for the Rijndael cipher (now AES)
- *
- * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * This code is hereby placed in the public domain.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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.
- */
-
-
-/*
-Te0[x] = S [x].[02, 01, 01, 03];
-Te1[x] = S [x].[03, 02, 01, 01];
-Te2[x] = S [x].[01, 03, 02, 01];
-Te3[x] = S [x].[01, 01, 03, 02];
-Te4[x] = S [x].[01, 01, 01, 01];
-
-Td0[x] = Si[x].[0e, 09, 0d, 0b];
-Td1[x] = Si[x].[0b, 0e, 09, 0d];
-Td2[x] = Si[x].[0d, 0b, 0e, 09];
-Td3[x] = Si[x].[09, 0d, 0b, 0e];
-Td4[x] = Si[x].[01, 01, 01, 01];
-*/
-
-const u32 Te0[256] = {
- 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
- 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
- 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
- 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
- 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
- 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
- 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
- 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
- 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
- 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
- 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
- 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
- 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
- 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
- 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
- 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
- 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
- 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
- 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
- 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
- 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
- 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
- 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
- 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
- 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
- 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
- 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
- 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
- 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
- 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
- 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
- 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
- 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
- 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
- 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
- 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
- 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
- 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
- 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
- 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
- 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
- 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
- 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
- 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
- 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
- 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
- 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
- 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
- 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
- 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
- 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
- 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
- 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
- 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
- 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
- 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
- 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
- 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
- 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
- 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
- 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
- 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
- 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
- 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-};
-#ifndef AES_SMALL_TABLES
-const u32 Te1[256] = {
- 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
- 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
- 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
- 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
- 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
- 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
- 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
- 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
- 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
- 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
- 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
- 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
- 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
- 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
- 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
- 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
- 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
- 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
- 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
- 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
- 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
- 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
- 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
- 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
- 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
- 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
- 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
- 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
- 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
- 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
- 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
- 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
- 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
- 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
- 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
- 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
- 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
- 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
- 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
- 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
- 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
- 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
- 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
- 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
- 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
- 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
- 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
- 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
- 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
- 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
- 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
- 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
- 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
- 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
- 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
- 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
- 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
- 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
- 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
- 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
- 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
- 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
- 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
- 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-};
-const u32 Te2[256] = {
- 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
- 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
- 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
- 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
- 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
- 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
- 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
- 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
- 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
- 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
- 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
- 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
- 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
- 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
- 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
- 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
- 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
- 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
- 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
- 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
- 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
- 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
- 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
- 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
- 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
- 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
- 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
- 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
- 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
- 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
- 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
- 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
- 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
- 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
- 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
- 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
- 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
- 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
- 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
- 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
- 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
- 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
- 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
- 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
- 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
- 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
- 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
- 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
- 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
- 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
- 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
- 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
- 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
- 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
- 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
- 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
- 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
- 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
- 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
- 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
- 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
- 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
- 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
- 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-};
-const u32 Te3[256] = {
-
- 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
- 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
- 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
- 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
- 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
- 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
- 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
- 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
- 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
- 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
- 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
- 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
- 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
- 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
- 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
- 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
- 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
- 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
- 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
- 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
- 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
- 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
- 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
- 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
- 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
- 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
- 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
- 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
- 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
- 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
- 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
- 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
- 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
- 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
- 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
- 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
- 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
- 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
- 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
- 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
- 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
- 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
- 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
- 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
- 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
- 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
- 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
- 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
- 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
- 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
- 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
- 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
- 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
- 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
- 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
- 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
- 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
- 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
- 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
- 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
- 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
- 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
- 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
- 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-};
-const u32 Te4[256] = {
- 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
- 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
- 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
- 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
- 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
- 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
- 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
- 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
- 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
- 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
- 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
- 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
- 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
- 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
- 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
- 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
- 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
- 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
- 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
- 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
- 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
- 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
- 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
- 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
- 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
- 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
- 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
- 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
- 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
- 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
- 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
- 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
- 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
- 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
- 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
- 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
- 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
- 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
- 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
- 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
- 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
- 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
- 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
- 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
- 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
- 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
- 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
- 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
- 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
- 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
- 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
- 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
- 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
- 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
- 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
- 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
- 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
- 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
- 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
- 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
- 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
- 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
- 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
- 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-};
-#endif /* AES_SMALL_TABLES */
-const u32 Td0[256] = {
- 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
- 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
- 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
- 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
- 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
- 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
- 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
- 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
- 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
- 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
- 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
- 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
- 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
- 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
- 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
- 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
- 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
- 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
- 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
- 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
- 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
- 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
- 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
- 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
- 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
- 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
- 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
- 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
- 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
- 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
- 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
- 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
- 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
- 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
- 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
- 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
- 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
- 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
- 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
- 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
- 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
- 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
- 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
- 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
- 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
- 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
- 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
- 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
- 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
- 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
- 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
- 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
- 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
- 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
- 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
- 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
- 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
- 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
- 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
- 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
- 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
- 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
- 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
- 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-};
-#ifndef AES_SMALL_TABLES
-const u32 Td1[256] = {
- 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
- 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
- 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
- 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
- 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
- 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
- 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
- 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
- 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
- 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
- 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
- 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
- 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
- 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
- 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
- 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
- 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
- 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
- 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
- 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
- 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
- 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
- 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
- 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
- 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
- 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
- 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
- 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
- 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
- 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
- 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
- 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
- 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
- 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
- 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
- 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
- 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
- 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
- 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
- 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
- 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
- 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
- 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
- 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
- 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
- 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
- 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
- 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
- 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
- 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
- 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
- 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
- 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
- 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
- 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
- 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
- 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
- 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
- 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
- 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
- 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
- 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
- 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
- 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-};
-const u32 Td2[256] = {
- 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
- 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
- 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
- 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
- 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
- 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
- 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
- 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
- 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
- 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
- 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
- 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
- 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
- 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
- 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
- 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
- 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
- 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
- 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
- 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
- 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
- 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
- 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
- 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
- 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
- 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
- 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
- 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
- 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
- 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
- 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
- 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
- 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
- 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
- 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
- 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
- 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
- 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
- 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
- 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
- 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
- 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
- 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
- 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
- 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
- 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
- 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
- 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
- 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
- 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
- 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
- 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
- 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
- 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
- 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
- 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
- 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
- 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
- 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
- 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
- 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
- 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
- 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
- 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-};
-const u32 Td3[256] = {
- 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
- 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
- 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
- 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
- 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
- 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
- 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
- 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
- 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
- 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
- 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
- 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
- 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
- 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
- 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
- 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
- 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
- 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
- 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
- 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
- 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
- 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
- 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
- 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
- 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
- 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
- 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
- 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
- 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
- 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
- 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
- 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
- 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
- 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
- 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
- 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
- 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
- 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
- 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
- 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
- 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
- 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
- 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
- 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
- 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
- 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
- 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
- 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
- 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
- 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
- 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
- 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
- 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
- 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
- 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
- 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
- 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
- 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
- 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
- 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
- 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
- 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
- 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
- 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-};
-const u32 Td4[256] = {
- 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
- 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
- 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
- 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
- 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
- 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
- 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
- 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
- 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
- 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
- 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
- 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
- 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
- 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
- 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
- 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
- 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
- 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
- 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
- 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
- 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
- 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
- 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
- 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
- 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
- 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
- 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
- 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
- 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
- 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
- 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
- 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
- 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
- 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
- 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
- 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
- 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
- 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
- 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
- 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
- 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
- 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
- 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
- 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
- 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
- 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
- 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
- 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
- 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
- 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
- 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
- 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
- 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
- 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
- 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
- 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
- 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
- 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
- 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
- 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
- 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
- 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
- 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
- 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-};
-const u32 rcon[] = {
- 0x01000000, 0x02000000, 0x04000000, 0x08000000,
- 0x10000000, 0x20000000, 0x40000000, 0x80000000,
- 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-#else /* AES_SMALL_TABLES */
-const u8 Td4s[256] = {
- 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
- 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
- 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
- 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
- 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
- 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
- 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
- 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
- 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
- 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
- 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
- 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
- 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
- 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
- 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
- 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
- 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
- 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
- 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
- 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
- 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
- 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
- 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
- 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
- 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
- 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
- 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
- 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
- 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
- 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
- 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
- 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
-};
-const u8 rcons[] = {
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
- /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-#endif /* AES_SMALL_TABLES */
-/**
- * Expand the cipher key into the encryption key schedule.
- *
- * @return the number of rounds for the given cipher key size.
- */
-void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[])
-{
- int i;
- u32 temp;
-
- rk[0] = GETU32(cipherKey );
- rk[1] = GETU32(cipherKey + 4);
- rk[2] = GETU32(cipherKey + 8);
- rk[3] = GETU32(cipherKey + 12);
- for (i = 0; i < 10; i++) {
- temp = rk[3];
- rk[4] = rk[0] ^
- TE421(temp) ^ TE432(temp) ^ TE443(temp) ^ TE414(temp) ^
- RCON(i);
- rk[5] = rk[1] ^ rk[4];
- rk[6] = rk[2] ^ rk[5];
- rk[7] = rk[3] ^ rk[6];
- rk += 4;
- }
-}
diff --git a/src/shared/libosmocore/src/gsm/milenage/aes.h b/src/shared/libosmocore/src/gsm/milenage/aes.h
deleted file mode 100644
index ba384a9d..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/aes.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * AES functions
- * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef AES_H
-#define AES_H
-
-#define AES_BLOCK_SIZE 16
-
-void * aes_encrypt_init(const u8 *key, size_t len);
-void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt);
-void aes_encrypt_deinit(void *ctx);
-void * aes_decrypt_init(const u8 *key, size_t len);
-void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain);
-void aes_decrypt_deinit(void *ctx);
-
-#endif /* AES_H */
diff --git a/src/shared/libosmocore/src/gsm/milenage/aes_i.h b/src/shared/libosmocore/src/gsm/milenage/aes_i.h
deleted file mode 100644
index 6b40bc78..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/aes_i.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * AES (Rijndael) cipher
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef AES_I_H
-#define AES_I_H
-
-#include "aes.h"
-
-/* #define FULL_UNROLL */
-#define AES_SMALL_TABLES
-
-extern const u32 Te0[256];
-extern const u32 Te1[256];
-extern const u32 Te2[256];
-extern const u32 Te3[256];
-extern const u32 Te4[256];
-extern const u32 Td0[256];
-extern const u32 Td1[256];
-extern const u32 Td2[256];
-extern const u32 Td3[256];
-extern const u32 Td4[256];
-extern const u32 rcon[10];
-extern const u8 Td4s[256];
-extern const u8 rcons[10];
-
-#ifndef AES_SMALL_TABLES
-
-#define RCON(i) rcon[(i)]
-
-#define TE0(i) Te0[((i) >> 24) & 0xff]
-#define TE1(i) Te1[((i) >> 16) & 0xff]
-#define TE2(i) Te2[((i) >> 8) & 0xff]
-#define TE3(i) Te3[(i) & 0xff]
-#define TE41(i) (Te4[((i) >> 24) & 0xff] & 0xff000000)
-#define TE42(i) (Te4[((i) >> 16) & 0xff] & 0x00ff0000)
-#define TE43(i) (Te4[((i) >> 8) & 0xff] & 0x0000ff00)
-#define TE44(i) (Te4[(i) & 0xff] & 0x000000ff)
-#define TE421(i) (Te4[((i) >> 16) & 0xff] & 0xff000000)
-#define TE432(i) (Te4[((i) >> 8) & 0xff] & 0x00ff0000)
-#define TE443(i) (Te4[(i) & 0xff] & 0x0000ff00)
-#define TE414(i) (Te4[((i) >> 24) & 0xff] & 0x000000ff)
-#define TE4(i) (Te4[(i)] & 0x000000ff)
-
-#define TD0(i) Td0[((i) >> 24) & 0xff]
-#define TD1(i) Td1[((i) >> 16) & 0xff]
-#define TD2(i) Td2[((i) >> 8) & 0xff]
-#define TD3(i) Td3[(i) & 0xff]
-#define TD41(i) (Td4[((i) >> 24) & 0xff] & 0xff000000)
-#define TD42(i) (Td4[((i) >> 16) & 0xff] & 0x00ff0000)
-#define TD43(i) (Td4[((i) >> 8) & 0xff] & 0x0000ff00)
-#define TD44(i) (Td4[(i) & 0xff] & 0x000000ff)
-#define TD0_(i) Td0[(i) & 0xff]
-#define TD1_(i) Td1[(i) & 0xff]
-#define TD2_(i) Td2[(i) & 0xff]
-#define TD3_(i) Td3[(i) & 0xff]
-
-#else /* AES_SMALL_TABLES */
-
-#define RCON(i) (rcons[(i)] << 24)
-
-static inline u32 rotr(u32 val, int bits)
-{
- return (val >> bits) | (val << (32 - bits));
-}
-
-#define TE0(i) Te0[((i) >> 24) & 0xff]
-#define TE1(i) rotr(Te0[((i) >> 16) & 0xff], 8)
-#define TE2(i) rotr(Te0[((i) >> 8) & 0xff], 16)
-#define TE3(i) rotr(Te0[(i) & 0xff], 24)
-#define TE41(i) ((Te0[((i) >> 24) & 0xff] << 8) & 0xff000000)
-#define TE42(i) (Te0[((i) >> 16) & 0xff] & 0x00ff0000)
-#define TE43(i) (Te0[((i) >> 8) & 0xff] & 0x0000ff00)
-#define TE44(i) ((Te0[(i) & 0xff] >> 8) & 0x000000ff)
-#define TE421(i) ((Te0[((i) >> 16) & 0xff] << 8) & 0xff000000)
-#define TE432(i) (Te0[((i) >> 8) & 0xff] & 0x00ff0000)
-#define TE443(i) (Te0[(i) & 0xff] & 0x0000ff00)
-#define TE414(i) ((Te0[((i) >> 24) & 0xff] >> 8) & 0x000000ff)
-#define TE4(i) ((Te0[(i)] >> 8) & 0x000000ff)
-
-#define TD0(i) Td0[((i) >> 24) & 0xff]
-#define TD1(i) rotr(Td0[((i) >> 16) & 0xff], 8)
-#define TD2(i) rotr(Td0[((i) >> 8) & 0xff], 16)
-#define TD3(i) rotr(Td0[(i) & 0xff], 24)
-#define TD41(i) (Td4s[((i) >> 24) & 0xff] << 24)
-#define TD42(i) (Td4s[((i) >> 16) & 0xff] << 16)
-#define TD43(i) (Td4s[((i) >> 8) & 0xff] << 8)
-#define TD44(i) (Td4s[(i) & 0xff])
-#define TD0_(i) Td0[(i) & 0xff]
-#define TD1_(i) rotr(Td0[(i) & 0xff], 8)
-#define TD2_(i) rotr(Td0[(i) & 0xff], 16)
-#define TD3_(i) rotr(Td0[(i) & 0xff], 24)
-
-#endif /* AES_SMALL_TABLES */
-
-#ifdef _MSC_VER
-#define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
-#define GETU32(p) SWAP(*((u32 *)(p)))
-#define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
-#else
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
-((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
-#define PUTU32(ct, st) { \
-(ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \
-(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
-#endif
-
-#define AES_PRIV_SIZE (4 * 44)
-
-void rijndaelKeySetupEnc(u32 rk[/*44*/], const u8 cipherKey[]);
-
-#endif /* AES_I_H */
diff --git a/src/shared/libosmocore/src/gsm/milenage/aes_wrap.h b/src/shared/libosmocore/src/gsm/milenage/aes_wrap.h
deleted file mode 100644
index 4b1c7b08..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/aes_wrap.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * AES-based functions
- *
- * - AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
- * - One-Key CBC MAC (OMAC1) hash with AES-128
- * - AES-128 CTR mode encryption
- * - AES-128 EAX mode encryption/decryption
- * - AES-128 CBC
- *
- * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef AES_WRAP_H
-#define AES_WRAP_H
-
-int __must_check aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
-int __must_check aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
-int __must_check omac1_aes_128_vector(const u8 *key, size_t num_elem,
- const u8 *addr[], const size_t *len,
- u8 *mac);
-int __must_check omac1_aes_128(const u8 *key, const u8 *data, size_t data_len,
- u8 *mac);
-int __must_check aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
-int __must_check aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
- u8 *data, size_t data_len);
-int __must_check aes_128_eax_encrypt(const u8 *key,
- const u8 *nonce, size_t nonce_len,
- const u8 *hdr, size_t hdr_len,
- u8 *data, size_t data_len, u8 *tag);
-int __must_check aes_128_eax_decrypt(const u8 *key,
- const u8 *nonce, size_t nonce_len,
- const u8 *hdr, size_t hdr_len,
- u8 *data, size_t data_len, const u8 *tag);
-int __must_check aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data,
- size_t data_len);
-int __must_check aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data,
- size_t data_len);
-
-#endif /* AES_WRAP_H */
diff --git a/src/shared/libosmocore/src/gsm/milenage/common.h b/src/shared/libosmocore/src/gsm/milenage/common.h
deleted file mode 100644
index aaf82b97..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/common.h
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define MSG_DEBUG
-#define wpa_hexdump(x, args...)
-#define wpa_hexdump_key(x, args...)
-#define wpa_printf(x, args...)
-
-#define os_memcpy(x, y, z) memcpy(x, y, z)
-#define os_memcmp(x, y, z) memcmp(x, y, z)
-#define os_memset(x, y, z) memset(x, y, z)
-#define os_malloc(x) malloc(x)
-#define os_free(x) free(x)
-
-typedef uint8_t u8;
-typedef uint32_t u32;
-
-#define __must_check
diff --git a/src/shared/libosmocore/src/gsm/milenage/crypto.h b/src/shared/libosmocore/src/gsm/milenage/crypto.h
deleted file mode 100644
index e69de29b..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/crypto.h
+++ /dev/null
diff --git a/src/shared/libosmocore/src/gsm/milenage/includes.h b/src/shared/libosmocore/src/gsm/milenage/includes.h
deleted file mode 100644
index e69de29b..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/includes.h
+++ /dev/null
diff --git a/src/shared/libosmocore/src/gsm/milenage/milenage.c b/src/shared/libosmocore/src/gsm/milenage/milenage.c
deleted file mode 100644
index b43f986a..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/milenage.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * 3GPP AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208)
- * Copyright (c) 2006-2007 <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- *
- * This file implements an example authentication algorithm defined for 3GPP
- * AKA. This can be used to implement a simple HLR/AuC into hlr_auc_gw to allow
- * EAP-AKA to be tested properly with real USIM cards.
- *
- * This implementations assumes that the r1..r5 and c1..c5 constants defined in
- * TS 35.206 are used, i.e., r1=64, r2=0, r3=32, r4=64, r5=96, c1=00..00,
- * c2=00..01, c3=00..02, c4=00..04, c5=00..08. The block cipher is assumed to
- * be AES (Rijndael).
- */
-
-#include "includes.h"
-
-#include "common.h"
-#include "aes_wrap.h"
-#include "milenage.h"
-
-
-/**
- * milenage_f1 - Milenage f1 and f1* algorithms
- * @opc: OPc = 128-bit value derived from OP and K
- * @k: K = 128-bit subscriber key
- * @_rand: RAND = 128-bit random challenge
- * @sqn: SQN = 48-bit sequence number
- * @amf: AMF = 16-bit authentication management field
- * @mac_a: Buffer for MAC-A = 64-bit network authentication code, or %NULL
- * @mac_s: Buffer for MAC-S = 64-bit resync authentication code, or %NULL
- * Returns: 0 on success, -1 on failure
- */
-int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
- const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s)
-{
- u8 tmp1[16], tmp2[16], tmp3[16];
- int i;
-
- /* tmp1 = TEMP = E_K(RAND XOR OP_C) */
- for (i = 0; i < 16; i++)
- tmp1[i] = _rand[i] ^ opc[i];
- if (aes_128_encrypt_block(k, tmp1, tmp1))
- return -1;
-
- /* tmp2 = IN1 = SQN || AMF || SQN || AMF */
- os_memcpy(tmp2, sqn, 6);
- os_memcpy(tmp2 + 6, amf, 2);
- os_memcpy(tmp2 + 8, tmp2, 8);
-
- /* OUT1 = E_K(TEMP XOR rot(IN1 XOR OP_C, r1) XOR c1) XOR OP_C */
-
- /* rotate (tmp2 XOR OP_C) by r1 (= 0x40 = 8 bytes) */
- for (i = 0; i < 16; i++)
- tmp3[(i + 8) % 16] = tmp2[i] ^ opc[i];
- /* XOR with TEMP = E_K(RAND XOR OP_C) */
- for (i = 0; i < 16; i++)
- tmp3[i] ^= tmp1[i];
- /* XOR with c1 (= ..00, i.e., NOP) */
-
- /* f1 || f1* = E_K(tmp3) XOR OP_c */
- if (aes_128_encrypt_block(k, tmp3, tmp1))
- return -1;
- for (i = 0; i < 16; i++)
- tmp1[i] ^= opc[i];
- if (mac_a)
- os_memcpy(mac_a, tmp1, 8); /* f1 */
- if (mac_s)
- os_memcpy(mac_s, tmp1 + 8, 8); /* f1* */
- return 0;
-}
-
-
-/**
- * milenage_f2345 - Milenage f2, f3, f4, f5, f5* algorithms
- * @opc: OPc = 128-bit value derived from OP and K
- * @k: K = 128-bit subscriber key
- * @_rand: RAND = 128-bit random challenge
- * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
- * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
- * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
- * @ak: Buffer for AK = 48-bit anonymity key (f5), or %NULL
- * @akstar: Buffer for AK = 48-bit anonymity key (f5*), or %NULL
- * Returns: 0 on success, -1 on failure
- */
-int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
- u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar)
-{
- u8 tmp1[16], tmp2[16], tmp3[16];
- int i;
-
- /* tmp2 = TEMP = E_K(RAND XOR OP_C) */
- for (i = 0; i < 16; i++)
- tmp1[i] = _rand[i] ^ opc[i];
- if (aes_128_encrypt_block(k, tmp1, tmp2))
- return -1;
-
- /* OUT2 = E_K(rot(TEMP XOR OP_C, r2) XOR c2) XOR OP_C */
- /* OUT3 = E_K(rot(TEMP XOR OP_C, r3) XOR c3) XOR OP_C */
- /* OUT4 = E_K(rot(TEMP XOR OP_C, r4) XOR c4) XOR OP_C */
- /* OUT5 = E_K(rot(TEMP XOR OP_C, r5) XOR c5) XOR OP_C */
-
- /* f2 and f5 */
- /* rotate by r2 (= 0, i.e., NOP) */
- for (i = 0; i < 16; i++)
- tmp1[i] = tmp2[i] ^ opc[i];
- tmp1[15] ^= 1; /* XOR c2 (= ..01) */
- /* f5 || f2 = E_K(tmp1) XOR OP_c */
- if (aes_128_encrypt_block(k, tmp1, tmp3))
- return -1;
- for (i = 0; i < 16; i++)
- tmp3[i] ^= opc[i];
- if (res)
- os_memcpy(res, tmp3 + 8, 8); /* f2 */
- if (ak)
- os_memcpy(ak, tmp3, 6); /* f5 */
-
- /* f3 */
- if (ck) {
- /* rotate by r3 = 0x20 = 4 bytes */
- for (i = 0; i < 16; i++)
- tmp1[(i + 12) % 16] = tmp2[i] ^ opc[i];
- tmp1[15] ^= 2; /* XOR c3 (= ..02) */
- if (aes_128_encrypt_block(k, tmp1, ck))
- return -1;
- for (i = 0; i < 16; i++)
- ck[i] ^= opc[i];
- }
-
- /* f4 */
- if (ik) {
- /* rotate by r4 = 0x40 = 8 bytes */
- for (i = 0; i < 16; i++)
- tmp1[(i + 8) % 16] = tmp2[i] ^ opc[i];
- tmp1[15] ^= 4; /* XOR c4 (= ..04) */
- if (aes_128_encrypt_block(k, tmp1, ik))
- return -1;
- for (i = 0; i < 16; i++)
- ik[i] ^= opc[i];
- }
-
- /* f5* */
- if (akstar) {
- /* rotate by r5 = 0x60 = 12 bytes */
- for (i = 0; i < 16; i++)
- tmp1[(i + 4) % 16] = tmp2[i] ^ opc[i];
- tmp1[15] ^= 8; /* XOR c5 (= ..08) */
- if (aes_128_encrypt_block(k, tmp1, tmp1))
- return -1;
- for (i = 0; i < 6; i++)
- akstar[i] = tmp1[i] ^ opc[i];
- }
-
- return 0;
-}
-
-
-/**
- * milenage_generate - Generate AKA AUTN,IK,CK,RES
- * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
- * @amf: AMF = 16-bit authentication management field
- * @k: K = 128-bit subscriber key
- * @sqn: SQN = 48-bit sequence number
- * @_rand: RAND = 128-bit random challenge
- * @autn: Buffer for AUTN = 128-bit authentication token
- * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
- * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
- * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
- * @res_len: Max length for res; set to used length or 0 on failure
- */
-void milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
- const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
- u8 *ck, u8 *res, size_t *res_len)
-{
- int i;
- u8 mac_a[8], ak[6];
-
- if (*res_len < 8) {
- *res_len = 0;
- return;
- }
- if (milenage_f1(opc, k, _rand, sqn, amf, mac_a, NULL) ||
- milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL)) {
- *res_len = 0;
- return;
- }
- *res_len = 8;
-
- /* AUTN = (SQN ^ AK) || AMF || MAC */
- for (i = 0; i < 6; i++)
- autn[i] = sqn[i] ^ ak[i];
- os_memcpy(autn + 6, amf, 2);
- os_memcpy(autn + 8, mac_a, 8);
-}
-
-
-/**
- * milenage_auts - Milenage AUTS validation
- * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
- * @k: K = 128-bit subscriber key
- * @_rand: RAND = 128-bit random challenge
- * @auts: AUTS = 112-bit authentication token from client
- * @sqn: Buffer for SQN = 48-bit sequence number
- * Returns: 0 = success (sqn filled), -1 on failure
- */
-int milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
- u8 *sqn)
-{
- u8 amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
- u8 ak[6], mac_s[8];
- int i;
-
- if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
- return -1;
- for (i = 0; i < 6; i++)
- sqn[i] = auts[i] ^ ak[i];
- if (milenage_f1(opc, k, _rand, sqn, amf, NULL, mac_s) ||
- memcmp(mac_s, auts + 6, 8) != 0)
- return -1;
- return 0;
-}
-
-
-/**
- * gsm_milenage - Generate GSM-Milenage (3GPP TS 55.205) authentication triplet
- * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
- * @k: K = 128-bit subscriber key
- * @_rand: RAND = 128-bit random challenge
- * @sres: Buffer for SRES = 32-bit SRES
- * @kc: Buffer for Kc = 64-bit Kc
- * Returns: 0 on success, -1 on failure
- */
-int gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres, u8 *kc)
-{
- u8 res[8], ck[16], ik[16];
- int i;
-
- if (milenage_f2345(opc, k, _rand, res, ck, ik, NULL, NULL))
- return -1;
-
- for (i = 0; i < 8; i++)
- kc[i] = ck[i] ^ ck[i + 8] ^ ik[i] ^ ik[i + 8];
-
-#ifdef GSM_MILENAGE_ALT_SRES
- os_memcpy(sres, res, 4);
-#else /* GSM_MILENAGE_ALT_SRES */
- for (i = 0; i < 4; i++)
- sres[i] = res[i] ^ res[i + 4];
-#endif /* GSM_MILENAGE_ALT_SRES */
- return 0;
-}
-
-
-/**
- * milenage_generate - Generate AKA AUTN,IK,CK,RES
- * @opc: OPc = 128-bit operator variant algorithm configuration field (encr.)
- * @k: K = 128-bit subscriber key
- * @sqn: SQN = 48-bit sequence number
- * @_rand: RAND = 128-bit random challenge
- * @autn: AUTN = 128-bit authentication token
- * @ik: Buffer for IK = 128-bit integrity key (f4), or %NULL
- * @ck: Buffer for CK = 128-bit confidentiality key (f3), or %NULL
- * @res: Buffer for RES = 64-bit signed response (f2), or %NULL
- * @res_len: Variable that will be set to RES length
- * @auts: 112-bit buffer for AUTS
- * Returns: 0 on success, -1 on failure, or -2 on synchronization failure
- */
-int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
- const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
- u8 *auts)
-{
- int i;
- u8 mac_a[8], ak[6], rx_sqn[6];
- const u8 *amf;
-
- wpa_hexdump(MSG_DEBUG, "Milenage: AUTN", autn, 16);
- wpa_hexdump(MSG_DEBUG, "Milenage: RAND", _rand, 16);
-
- if (milenage_f2345(opc, k, _rand, res, ck, ik, ak, NULL))
- return -1;
-
- *res_len = 8;
- wpa_hexdump_key(MSG_DEBUG, "Milenage: RES", res, *res_len);
- wpa_hexdump_key(MSG_DEBUG, "Milenage: CK", ck, 16);
- wpa_hexdump_key(MSG_DEBUG, "Milenage: IK", ik, 16);
- wpa_hexdump_key(MSG_DEBUG, "Milenage: AK", ak, 6);
-
- /* AUTN = (SQN ^ AK) || AMF || MAC */
- for (i = 0; i < 6; i++)
- rx_sqn[i] = autn[i] ^ ak[i];
- wpa_hexdump(MSG_DEBUG, "Milenage: SQN", rx_sqn, 6);
-
- if (os_memcmp(rx_sqn, sqn, 6) <= 0) {
- u8 auts_amf[2] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */
- if (milenage_f2345(opc, k, _rand, NULL, NULL, NULL, NULL, ak))
- return -1;
- wpa_hexdump_key(MSG_DEBUG, "Milenage: AK*", ak, 6);
- for (i = 0; i < 6; i++)
- auts[i] = sqn[i] ^ ak[i];
- if (milenage_f1(opc, k, _rand, sqn, auts_amf, NULL, auts + 6))
- return -1;
- wpa_hexdump(MSG_DEBUG, "Milenage: AUTS", auts, 14);
- return -2;
- }
-
- amf = autn + 6;
- wpa_hexdump(MSG_DEBUG, "Milenage: AMF", amf, 2);
- if (milenage_f1(opc, k, _rand, rx_sqn, amf, mac_a, NULL))
- return -1;
-
- wpa_hexdump(MSG_DEBUG, "Milenage: MAC_A", mac_a, 8);
-
- if (os_memcmp(mac_a, autn + 8, 8) != 0) {
- wpa_printf(MSG_DEBUG, "Milenage: MAC mismatch");
- wpa_hexdump(MSG_DEBUG, "Milenage: Received MAC_A",
- autn + 8, 8);
- return -1;
- }
-
- return 0;
-}
-
-int milenage_opc_gen(u8 *opc, const u8 *k, const u8 *op)
-{
- int i;
-
- /* Encrypt OP using K */
- if (aes_128_encrypt_block(k, op, opc))
- return -1;
-
- /* XOR the resulting Ek(OP) with OP */
- for (i = 0; i < 16; i++)
- opc[i] = opc[i] ^ op[i];
-
- return 0;
-}
diff --git a/src/shared/libosmocore/src/gsm/milenage/milenage.h b/src/shared/libosmocore/src/gsm/milenage/milenage.h
deleted file mode 100644
index a91e946a..00000000
--- a/src/shared/libosmocore/src/gsm/milenage/milenage.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * UMTS AKA - Milenage algorithm (3GPP TS 35.205, .206, .207, .208)
- * Copyright (c) 2006-2007 <j@w1.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#ifndef MILENAGE_H
-#define MILENAGE_H
-
-void milenage_generate(const u8 *opc, const u8 *amf, const u8 *k,
- const u8 *sqn, const u8 *_rand, u8 *autn, u8 *ik,
- u8 *ck, u8 *res, size_t *res_len);
-int milenage_auts(const u8 *opc, const u8 *k, const u8 *_rand, const u8 *auts,
- u8 *sqn);
-int gsm_milenage(const u8 *opc, const u8 *k, const u8 *_rand, u8 *sres,
- u8 *kc);
-int milenage_check(const u8 *opc, const u8 *k, const u8 *sqn, const u8 *_rand,
- const u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
- u8 *auts);
-int milenage_f1(const u8 *opc, const u8 *k, const u8 *_rand,
- const u8 *sqn, const u8 *amf, u8 *mac_a, u8 *mac_s);
-int milenage_f2345(const u8 *opc, const u8 *k, const u8 *_rand,
- u8 *res, u8 *ck, u8 *ik, u8 *ak, u8 *akstar);
-
-int milenage_opc_gen(u8 *opc, const u8 *k, const u8 *op);
-
-#endif /* MILENAGE_H */
diff --git a/src/shared/libosmocore/src/gsm/rsl.c b/src/shared/libosmocore/src/gsm/rsl.c
deleted file mode 100644
index 5693b4f0..00000000
--- a/src/shared/libosmocore/src/gsm/rsl.c
+++ /dev/null
@@ -1,507 +0,0 @@
-/* GSM Radio Signalling Link messages on the A-bis interface
- * 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
-
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/rsl.h>
-
-/*! \addtogroup rsl
- * @{
- */
-
-/*! \file rsl.c */
-
-/*! \brief Size for RSL \ref msgb_alloc */
-#define RSL_ALLOC_SIZE 200
-/*! \brief Headroom size for RSL \ref msgb_alloc */
-#define RSL_ALLOC_HEADROOM 56
-
-/*! \brief Initialize a RSL RLL header */
-void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type)
-{
- dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
- dh->c.msg_type = msg_type;
- dh->ie_chan = RSL_IE_CHAN_NR;
- dh->ie_link_id = RSL_IE_LINK_IDENT;
-}
-
-/*! \brief Initialize a RSL Common Channel header */
-void rsl_init_cchan_hdr(struct abis_rsl_cchan_hdr *ch, uint8_t msg_type)
-{
- ch->c.msg_discr = ABIS_RSL_MDISC_COM_CHAN;
- ch->c.msg_type = msg_type;
- ch->ie_chan = RSL_IE_CHAN_NR;
-}
-
-/* \brief TLV parser definition for RSL */
-const struct tlv_definition rsl_att_tlvdef = {
- .def = {
- [RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
- [RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
- [RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
- [RSL_IE_BS_POWER] = { TLV_TYPE_TV },
- [RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
- [RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
- [RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
- [RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
- [RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
- [RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
- [RSL_IE_MS_POWER] = { TLV_TYPE_TV },
- [RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
- [RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
- [RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
- [RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
- [RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
- [RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
- [RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
- [RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
- [RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
- [RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
- [RSL_IE_CAUSE] = { TLV_TYPE_TLV },
- [RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
- [RSL_IE_MSG_ID] = { TLV_TYPE_TV },
- [RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
- [RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
- [RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
- [RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
- [RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
- [RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
- [RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
- [RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
- [RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
- [RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
- [RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
- [RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
- [RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
- [RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
- [RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
- [RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
- [RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
- [RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
- [RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
- [RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
- [RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
- [RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
- [RSL_IE_UIC] = { TLV_TYPE_TLV },
- [RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
- [RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
- [RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
- [RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
- [RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
- [RSL_IE_RTD] = { TLV_TYPE_TV },
- [RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
- [RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
- [RSL_IE_SIEMENS_MRPCI] = { TLV_TYPE_TV },
- [RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
- [RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
- [RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
- [RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
- [RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
- [RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
- [RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
- [RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
- [RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
- [RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
- [RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
- },
-};
-
-/*! \brief Encode channel number as per Section 9.3.1 */
-uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot)
-{
- uint8_t ret;
-
- ret = (timeslot & 0x07) | type;
-
- switch (type) {
- case RSL_CHAN_Lm_ACCHs:
- subch &= 0x01;
- break;
- case RSL_CHAN_SDCCH4_ACCH:
- subch &= 0x03;
- break;
- case RSL_CHAN_SDCCH8_ACCH:
- subch &= 0x07;
- break;
- default:
- /* no subchannels allowed */
- subch = 0x00;
- break;
- }
- ret |= (subch << 3);
-
- return ret;
-}
-
-/*! \brief Decode RSL channel number
- * \param[in] chan_nr Channel Number
- * \param[out] type Channel Type
- * \param[out] subch Sub-channel Number
- * \param[out] timeslot Timeslot
- */
-int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot)
-{
- *timeslot = chan_nr & 0x7;
-
- if ((chan_nr & 0xf8) == RSL_CHAN_Bm_ACCHs) {
- *type = RSL_CHAN_Bm_ACCHs;
- *subch = 0;
- } else if ((chan_nr & 0xf0) == RSL_CHAN_Lm_ACCHs) {
- *type = RSL_CHAN_Lm_ACCHs;
- *subch = (chan_nr >> 3) & 0x1;
- } else if ((chan_nr & 0xe0) == RSL_CHAN_SDCCH4_ACCH) {
- *type = RSL_CHAN_SDCCH4_ACCH;
- *subch = (chan_nr >> 3) & 0x3;
- } else if ((chan_nr & 0xc0) == RSL_CHAN_SDCCH8_ACCH) {
- *type = RSL_CHAN_SDCCH8_ACCH;
- *subch = (chan_nr >> 3) & 0x7;
- } else if ((chan_nr & 0xf8) == RSL_CHAN_BCCH) {
- *type = RSL_CHAN_BCCH;
- *subch = 0;
- } else if ((chan_nr & 0xf8) == RSL_CHAN_RACH) {
- *type = RSL_CHAN_RACH;
- *subch = 0;
- } else if ((chan_nr & 0xf8) == RSL_CHAN_PCH_AGCH) {
- *type = RSL_CHAN_PCH_AGCH;
- *subch = 0;
- } else
- return -EINVAL;
-
- return 0;
-}
-
-/*! \brief Get human-readable string for RSL channel number */
-const char *rsl_chan_nr_str(uint8_t chan_nr)
-{
- static char str[20];
- int ts = chan_nr & 7;
- uint8_t cbits = chan_nr >> 3;
-
- if (cbits == 0x01)
- sprintf(str, "TCH/F on TS%d", ts);
- else if ((cbits & 0x1e) == 0x02)
- sprintf(str, "TCH/H(%u) on TS%d", cbits & 0x01, ts);
- else if ((cbits & 0x1c) == 0x04)
- sprintf(str, "SDCCH/4(%u) on TS%d", cbits & 0x03, ts);
- else if ((cbits & 0x18) == 0x08)
- sprintf(str, "SDCCH/8(%u) on TS%d", cbits & 0x07, ts);
- else if (cbits == 0x10)
- sprintf(str, "BCCH on TS%d", ts);
- else if (cbits == 0x11)
- sprintf(str, "RACH on TS%d", ts);
- else if (cbits == 0x12)
- sprintf(str, "PCH/AGCH on TS%d", ts);
- else
- sprintf(str, "UNKNOWN on TS%d", ts);
-
- return str;
-}
-
-static const struct value_string rsl_err_vals[] = {
- { RSL_ERR_RADIO_IF_FAIL, "Radio Interface Failure" },
- { RSL_ERR_RADIO_LINK_FAIL, "Radio Link Failure" },
- { RSL_ERR_HANDOVER_ACC_FAIL, "Handover Access Failure" },
- { RSL_ERR_TALKER_ACC_FAIL, "Talker Access Failure" },
- { RSL_ERR_OM_INTERVENTION, "O&M Intervention" },
- { RSL_ERR_NORMAL_UNSPEC, "Normal event, unspecified" },
- { RSL_ERR_T_MSRFPCI_EXP, "Siemens: T_MSRFPCI Expired" },
- { RSL_ERR_EQUIPMENT_FAIL, "Equipment Failure" },
- { RSL_ERR_RR_UNAVAIL, "Radio Resource not available" },
- { RSL_ERR_TERR_CH_FAIL, "Terrestrial Channel Failure" },
- { RSL_ERR_CCCH_OVERLOAD, "CCCH Overload" },
- { RSL_ERR_ACCH_OVERLOAD, "ACCH Overload" },
- { RSL_ERR_PROCESSOR_OVERLOAD, "Processor Overload" },
- { RSL_ERR_RES_UNAVAIL, "Resource not available, unspecified" },
- { RSL_ERR_TRANSC_UNAVAIL, "Transcoding not available" },
- { RSL_ERR_SERV_OPT_UNAVAIL, "Service or Option not available" },
- { RSL_ERR_ENCR_UNIMPL, "Encryption algorithm not implemented" },
- { RSL_ERR_SERV_OPT_UNIMPL, "Service or Option not implemented" },
- { RSL_ERR_RCH_ALR_ACTV_ALLOC, "Radio channel already activated" },
- { RSL_ERR_INVALID_MESSAGE, "Invalid Message, unspecified" },
- { RSL_ERR_MSG_DISCR, "Message Discriminator Error" },
- { RSL_ERR_MSG_TYPE, "Message Type Error" },
- { RSL_ERR_MSG_SEQ, "Message Sequence Error" },
- { RSL_ERR_IE_ERROR, "General IE error" },
- { RSL_ERR_MAND_IE_ERROR, "Mandatory IE error" },
- { RSL_ERR_OPT_IE_ERROR, "Optional IE error" },
- { RSL_ERR_IE_NONEXIST, "IE non-existent" },
- { RSL_ERR_IE_LENGTH, "IE length error" },
- { RSL_ERR_IE_CONTENT, "IE content error" },
- { RSL_ERR_PROTO, "Protocol error, unspecified" },
- { RSL_ERR_INTERWORKING, "Interworking error, unspecified" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable name for RSL Error */
-const char *rsl_err_name(uint8_t err)
-{
- return get_value_string(rsl_err_vals, err);
-}
-
-/* Names for Radio Link Layer Management */
-static const struct value_string rsl_msgt_names[] = {
- { RSL_MT_DATA_REQ, "DATA_REQ" },
- { RSL_MT_DATA_IND, "DATA_IND" },
- { RSL_MT_ERROR_IND, "ERROR_IND" },
- { RSL_MT_EST_REQ, "EST_REQ" },
- { RSL_MT_EST_CONF, "EST_CONF" },
- { RSL_MT_EST_IND, "EST_IND" },
- { RSL_MT_REL_REQ, "REL_REQ" },
- { RSL_MT_REL_CONF, "REL_CONF" },
- { RSL_MT_REL_IND, "REL_IND" },
- { RSL_MT_UNIT_DATA_REQ, "UNIT_DATA_REQ" },
- { RSL_MT_UNIT_DATA_IND, "UNIT_DATA_IND" },
- { RSL_MT_SUSP_REQ, "SUSP_REQ" },
- { RSL_MT_SUSP_CONF, "SUSP_CONF" },
- { RSL_MT_RES_REQ, "RES_REQ" },
- { RSL_MT_RECON_REQ, "RECON_REQ" },
-
- { RSL_MT_BCCH_INFO, "BCCH_INFO" },
- { RSL_MT_CCCH_LOAD_IND, "CCCH_LOAD_IND" },
- { RSL_MT_CHAN_RQD, "CHAN_RQD" },
- { RSL_MT_DELETE_IND, "DELETE_IND" },
- { RSL_MT_PAGING_CMD, "PAGING_CMD" },
- { RSL_MT_IMMEDIATE_ASSIGN_CMD, "IMM_ASS_CMD" },
- { RSL_MT_SMS_BC_REQ, "SMS_BC_REQ" },
- { RSL_MT_CHAN_CONF, "CHAN_CONF" },
-
- { RSL_MT_RF_RES_IND, "RF_RES_IND" },
- { RSL_MT_SACCH_FILL, "SACCH_FILL" },
- { RSL_MT_OVERLOAD, "OVERLOAD" },
- { RSL_MT_ERROR_REPORT, "ERROR_REPORT" },
- { RSL_MT_SMS_BC_CMD, "SMS_BC_CMD" },
- { RSL_MT_CBCH_LOAD_IND, "CBCH_LOAD_IND" },
- { RSL_MT_NOT_CMD, "NOTIFY_CMD" },
-
- { RSL_MT_CHAN_ACTIV, "CHAN_ACTIV" },
- { RSL_MT_CHAN_ACTIV_ACK, "CHAN_ACTIV_ACK" },
- { RSL_MT_CHAN_ACTIV_NACK, "CHAN_ACTIV_NACK" },
- { RSL_MT_CONN_FAIL, "CONN_FAIL" },
- { RSL_MT_DEACTIVATE_SACCH, "DEACTIVATE_SACCH" },
- { RSL_MT_ENCR_CMD, "ENCR_CMD" },
- { RSL_MT_HANDO_DET, "HANDOVER_DETECT" },
- { RSL_MT_MEAS_RES, "MEAS_RES" },
- { RSL_MT_MODE_MODIFY_REQ, "MODE_MODIFY_REQ" },
- { RSL_MT_MODE_MODIFY_ACK, "MODE_MODIFY_ACK" },
- { RSL_MT_MODE_MODIFY_NACK, "MODE_MODIFY_NACK" },
- { RSL_MT_PHY_CONTEXT_REQ, "PHY_CONTEXT_REQ" },
- { RSL_MT_PHY_CONTEXT_CONF, "PHY_CONTEXT_CONF" },
- { RSL_MT_RF_CHAN_REL, "RF_CHAN_REL" },
- { RSL_MT_MS_POWER_CONTROL, "MS_POWER_CONTROL" },
- { RSL_MT_BS_POWER_CONTROL, "BS_POWER_CONTROL" },
- { RSL_MT_PREPROC_CONFIG, "PREPROC_CONFIG" },
- { RSL_MT_PREPROC_MEAS_RES, "PREPROC_MEAS_RES" },
- { RSL_MT_RF_CHAN_REL_ACK, "RF_CHAN_REL_ACK" },
- { RSL_MT_SACCH_INFO_MODIFY, "SACCH_INFO_MODIFY" },
- { RSL_MT_TALKER_DET, "TALKER_DETECT" },
- { RSL_MT_LISTENER_DET, "LISTENER_DETECT" },
- { RSL_MT_REMOTE_CODEC_CONF_REP, "REM_CODEC_CONF_REP" },
- { RSL_MT_RTD_REP, "RTD_REQ" },
- { RSL_MT_PRE_HANDO_NOTIF, "HANDO_NOTIF" },
- { RSL_MT_MR_CODEC_MOD_REQ, "CODEC_MOD_REQ" },
- { RSL_MT_MR_CODEC_MOD_ACK, "CODEC_MOD_ACK" },
- { RSL_MT_MR_CODEC_MOD_NACK, "CODEC_MOD_NACK" },
- { RSL_MT_MR_CODEC_MOD_PER, "CODEC_MODE_PER" },
- { RSL_MT_TFO_REP, "TFO_REP" },
- { RSL_MT_TFO_MOD_REQ, "TFO_MOD_REQ" },
- { RSL_MT_LOCATION_INFO, "LOCATION_INFO" },
- { 0, NULL }
-};
-
-
-/*! \brief Get human-readable string for RSL Message Type */
-const char *rsl_msg_name(uint8_t msg_type)
-{
- return get_value_string(rsl_msgt_names, msg_type);
-}
-
-/*! \brief ip.access specific */
-static const struct value_string rsl_ipac_msgt_names[] = {
- { RSL_MT_IPAC_PDCH_ACT, "IPAC_PDCH_ACT" },
- { RSL_MT_IPAC_PDCH_ACT_ACK, "IPAC_PDCH_ACT_ACK" },
- { RSL_MT_IPAC_PDCH_ACT_NACK, "IPAC_PDCH_ACT_NACK" },
- { RSL_MT_IPAC_PDCH_DEACT, "IPAC_PDCH_DEACT" },
- { RSL_MT_IPAC_PDCH_DEACT_ACK, "IPAC_PDCH_DEACT_ACK" },
- { RSL_MT_IPAC_PDCH_DEACT_NACK, "IPAC_PDCH_DEACT_NACK" },
- { RSL_MT_IPAC_CONNECT_MUX, "IPAC_CONNECT_MUX" },
- { RSL_MT_IPAC_CONNECT_MUX_ACK, "IPAC_CONNECT_MUX_ACK" },
- { RSL_MT_IPAC_CONNECT_MUX_NACK, "IPAC_CONNECT_MUX_NACK" },
- { RSL_MT_IPAC_BIND_MUX, "IPAC_BIND_MUX" },
- { RSL_MT_IPAC_BIND_MUX_ACK, "IPAC_BIND_MUX_ACK" },
- { RSL_MT_IPAC_BIND_MUX_NACK, "IPAC_BIND_MUX_NACK" },
- { RSL_MT_IPAC_DISC_MUX, "IPAC_DISC_MUX" },
- { RSL_MT_IPAC_DISC_MUX_ACK, "IPAC_DISC_MUX_ACK" },
- { RSL_MT_IPAC_DISC_MUX_NACK, "IPAC_DISC_MUX_NACK" },
- { RSL_MT_IPAC_CRCX, "IPAC_CRCX" },
- { RSL_MT_IPAC_CRCX_ACK, "IPAC_CRCX_ACK" },
- { RSL_MT_IPAC_CRCX_NACK, "IPAC_CRCX_NACK" },
- { RSL_MT_IPAC_MDCX, "IPAC_MDCX" },
- { RSL_MT_IPAC_MDCX_ACK, "IPAC_MDCX_ACK" },
- { RSL_MT_IPAC_MDCX_NACK, "IPAC_MDCX_NACK" },
- { RSL_MT_IPAC_DLCX_IND, "IPAC_DLCX_IND" },
- { RSL_MT_IPAC_DLCX, "IPAC_DLCX" },
- { RSL_MT_IPAC_DLCX_ACK, "IPAC_DLCX_ACK" },
- { RSL_MT_IPAC_DLCX_NACK, "IPAC_DLCX_NACK" },
- { 0, NULL }
-};
-
-/*! \brief Get human-readable name of ip.access RSL msg type */
-const char *rsl_ipac_msg_name(uint8_t msg_type)
-{
- return get_value_string(rsl_ipac_msgt_names, msg_type);
-}
-
-static const struct value_string rsl_rlm_cause_strs[] = {
- { RLL_CAUSE_T200_EXPIRED, "Timer T200 expired (N200+1) times" },
- { RLL_CAUSE_REEST_REQ, "Re-establishment request" },
- { RLL_CAUSE_UNSOL_UA_RESP, "Unsolicited UA response" },
- { RLL_CAUSE_UNSOL_DM_RESP, "Unsolicited DM response" },
- { RLL_CAUSE_UNSOL_DM_RESP_MF, "Unsolicited DM response, multiple frame" },
- { RLL_CAUSE_UNSOL_SPRV_RESP, "Unsolicited supervisory response" },
- { RLL_CAUSE_SEQ_ERR, "Sequence Error" },
- { RLL_CAUSE_UFRM_INC_PARAM, "U-Frame with incorrect parameters" },
- { RLL_CAUSE_SFRM_INC_PARAM, "S-Frame with incorrect parameters" },
- { RLL_CAUSE_IFRM_INC_MBITS, "I-Frame with incorrect use of M bit" },
- { RLL_CAUSE_IFRM_INC_LEN, "I-Frame with incorrect length" },
- { RLL_CAUSE_FRM_UNIMPL, "Fraeme not implemented" },
- { RLL_CAUSE_SABM_MF, "SABM command, multiple frame established state" },
- { RLL_CAUSE_SABM_INFO_NOTALL, "SABM frame with information not allowed in this state" },
- { 0, NULL },
-};
-
-/*! \brief Get human-readable string for RLM cause */
-const char *rsl_rlm_cause_name(uint8_t err)
-{
- return get_value_string(rsl_rlm_cause_strs, err);
-}
-
-/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
-int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
-{
- switch (ccch_conf) {
- case RSL_BCCH_CCCH_CONF_1_NC:
- return 1;
- case RSL_BCCH_CCCH_CONF_1_C:
- return 1;
- case RSL_BCCH_CCCH_CONF_2_NC:
- return 2;
- case RSL_BCCH_CCCH_CONF_3_NC:
- return 3;
- case RSL_BCCH_CCCH_CONF_4_NC:
- return 4;
- default:
- return -1;
- }
-}
-
-/* Section 3.3.2.3 TS 05.02 */
-int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
-{
- switch (ccch_conf) {
- case RSL_BCCH_CCCH_CONF_1_NC:
- return 0;
- case RSL_BCCH_CCCH_CONF_1_C:
- return 1;
- case RSL_BCCH_CCCH_CONF_2_NC:
- return 0;
- case RSL_BCCH_CCCH_CONF_3_NC:
- return 0;
- case RSL_BCCH_CCCH_CONF_4_NC:
- return 0;
- default:
- return -1;
- }
-}
-
-/*! \brief Push a RSL RLL header onto an existing msgb */
-void rsl_rll_push_hdr(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr,
- uint8_t link_id, int transparent)
-{
- struct abis_rsl_rll_hdr *rh;
-
- rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
- rsl_init_rll_hdr(rh, msg_type);
- if (transparent)
- rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
- rh->chan_nr = chan_nr;
- rh->link_id = link_id;
-
- /* set the l2 header pointer */
- msg->l2h = (uint8_t *)rh;
-}
-
-/*! \brief Push a RSL RLL header with L3_INFO IE */
-void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr,
- uint8_t link_id, int transparent)
-{
- uint8_t l3_len = msg->tail - (uint8_t *)msgb_l3(msg);
-
- /* construct a RSLms RLL message (DATA INDICATION, UNIT DATA
- * INDICATION) and send it off via RSLms */
-
- /* Push the L3 IE tag and lengh */
- msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
-
- /* Then push the RSL header */
- rsl_rll_push_hdr(msg, msg_type, chan_nr, link_id, transparent);
-}
-
-/*! \brief Create msgb with RSL RLL header */
-struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr,
- uint8_t link_id, int transparent)
-{
- struct abis_rsl_rll_hdr *rh;
- struct msgb *msg;
-
- msg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
- RSL_ALLOC_HEADROOM, "rsl_rll_simple");
-
- if (!msg)
- return NULL;
-
- /* put the RSL header */
- rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
- rsl_init_rll_hdr(rh, msg_type);
- if (transparent)
- rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
- rh->chan_nr = chan_nr;
- rh->link_id = link_id;
-
- /* set the l2 header pointer */
- msg->l2h = (uint8_t *)rh;
-
- return msg;
-}
-
-/*! @} */
diff --git a/src/shared/libosmocore/src/gsm/rxlev_stat.c b/src/shared/libosmocore/src/gsm/rxlev_stat.c
deleted file mode 100644
index d226861e..00000000
--- a/src/shared/libosmocore/src/gsm/rxlev_stat.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Rx Level statistics */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdint.h>
-
-#include <osmocom/core/bitvec.h>
-#include <osmocom/gsm/rxlev_stat.h>
-
-void rxlev_stat_input(struct rxlev_stats *st, uint16_t arfcn, uint8_t rxlev)
-{
- struct bitvec bv;
-
- if (rxlev >= NUM_RXLEVS)
- rxlev = NUM_RXLEVS-1;
-
- bv.data_len = NUM_ARFCNS/8;
- bv.data = st->rxlev_buckets[rxlev];
-
- bitvec_set_bit_pos(&bv, arfcn, ONE);
-}
-
-/* get the next ARFCN that has the specified Rxlev */
-int16_t rxlev_stat_get_next(const struct rxlev_stats *st, uint8_t rxlev, int16_t arfcn)
-{
- struct bitvec bv;
-
- if (rxlev >= NUM_RXLEVS)
- rxlev = NUM_RXLEVS-1;
-
- bv.data_len = NUM_ARFCNS/8;
-
- if (arfcn < 0)
- arfcn = -1;
-
- bv.data = (uint8_t *) st->rxlev_buckets[rxlev];
-
- return bitvec_find_bit_pos(&bv, arfcn+1, ONE);
-}
-
-void rxlev_stat_reset(struct rxlev_stats *st)
-{
- memset(st, 0, sizeof(*st));
-}
-
-void rxlev_stat_dump(const struct rxlev_stats *st)
-{
- int i;
-
- for (i = NUM_RXLEVS-1; i >= 0; i--) {
- int16_t arfcn = -1;
-
- printf("ARFCN with RxLev %u: ", i);
- while ((arfcn = rxlev_stat_get_next(st, i, arfcn)) >= 0) {
- printf("%u ", arfcn);
- }
- printf("\n");
- }
-}
diff --git a/src/shared/libosmocore/src/gsm/sysinfo.c b/src/shared/libosmocore/src/gsm/sysinfo.c
deleted file mode 100644
index 1408f6bf..00000000
--- a/src/shared/libosmocore/src/gsm/sysinfo.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* GSM 04.08 System Information (SI) encoding and decoding
- * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
-
-/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <osmocom/core/bitvec.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/sysinfo.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_08_58.h>
-
-/* verify the sizes of the system information type structs */
-
-/* rest octets are not part of the struct */
-osmo_static_assert(sizeof(struct gsm48_system_information_type_header) == 3, _si_header_size);
-osmo_static_assert(sizeof(struct gsm48_rach_control) == 3, _si_rach_control);
-osmo_static_assert(sizeof(struct gsm48_system_information_type_1) == 22, _si1_size);
-osmo_static_assert(sizeof(struct gsm48_system_information_type_2) == 23, _si2_size);
-osmo_static_assert(sizeof(struct gsm48_system_information_type_3) == 19, _si3_size);
-osmo_static_assert(sizeof(struct gsm48_system_information_type_4) == 13, _si4_size);
-
-/* bs11 forgot the l2 len, 0-6 rest octets */
-osmo_static_assert(sizeof(struct gsm48_system_information_type_5) == 18, _si5_size);
-osmo_static_assert(sizeof(struct gsm48_system_information_type_6) == 11, _si6_size);
-
-osmo_static_assert(sizeof(struct gsm48_system_information_type_13) == 3, _si13_size);
-
-static const uint8_t sitype2rsl[_MAX_SYSINFO_TYPE] = {
- [SYSINFO_TYPE_1] = RSL_SYSTEM_INFO_1,
- [SYSINFO_TYPE_2] = RSL_SYSTEM_INFO_2,
- [SYSINFO_TYPE_3] = RSL_SYSTEM_INFO_3,
- [SYSINFO_TYPE_4] = RSL_SYSTEM_INFO_4,
- [SYSINFO_TYPE_5] = RSL_SYSTEM_INFO_5,
- [SYSINFO_TYPE_6] = RSL_SYSTEM_INFO_6,
- [SYSINFO_TYPE_7] = RSL_SYSTEM_INFO_7,
- [SYSINFO_TYPE_8] = RSL_SYSTEM_INFO_8,
- [SYSINFO_TYPE_9] = RSL_SYSTEM_INFO_9,
- [SYSINFO_TYPE_10] = RSL_SYSTEM_INFO_10,
- [SYSINFO_TYPE_13] = RSL_SYSTEM_INFO_13,
- [SYSINFO_TYPE_16] = RSL_SYSTEM_INFO_16,
- [SYSINFO_TYPE_17] = RSL_SYSTEM_INFO_17,
- [SYSINFO_TYPE_18] = RSL_SYSTEM_INFO_18,
- [SYSINFO_TYPE_19] = RSL_SYSTEM_INFO_19,
- [SYSINFO_TYPE_20] = RSL_SYSTEM_INFO_20,
- [SYSINFO_TYPE_2bis] = RSL_SYSTEM_INFO_2bis,
- [SYSINFO_TYPE_2ter] = RSL_SYSTEM_INFO_2ter,
- [SYSINFO_TYPE_2quater] = RSL_SYSTEM_INFO_2quater,
- [SYSINFO_TYPE_5bis] = RSL_SYSTEM_INFO_5bis,
- [SYSINFO_TYPE_5ter] = RSL_SYSTEM_INFO_5ter,
- [SYSINFO_TYPE_EMO] = RSL_EXT_MEAS_ORDER,
- [SYSINFO_TYPE_MEAS_INFO]= RSL_MEAS_INFO,
-};
-
-static const uint8_t rsl2sitype[256] = {
- [RSL_SYSTEM_INFO_1] = SYSINFO_TYPE_1,
- [RSL_SYSTEM_INFO_2] = SYSINFO_TYPE_2,
- [RSL_SYSTEM_INFO_3] = SYSINFO_TYPE_3,
- [RSL_SYSTEM_INFO_4] = SYSINFO_TYPE_4,
- [RSL_SYSTEM_INFO_5] = SYSINFO_TYPE_5,
- [RSL_SYSTEM_INFO_6] = SYSINFO_TYPE_6,
- [RSL_SYSTEM_INFO_7] = SYSINFO_TYPE_7,
- [RSL_SYSTEM_INFO_8] = SYSINFO_TYPE_8,
- [RSL_SYSTEM_INFO_9] = SYSINFO_TYPE_9,
- [RSL_SYSTEM_INFO_10] = SYSINFO_TYPE_10,
- [RSL_SYSTEM_INFO_13] = SYSINFO_TYPE_13,
- [RSL_SYSTEM_INFO_16] = SYSINFO_TYPE_16,
- [RSL_SYSTEM_INFO_17] = SYSINFO_TYPE_17,
- [RSL_SYSTEM_INFO_18] = SYSINFO_TYPE_18,
- [RSL_SYSTEM_INFO_19] = SYSINFO_TYPE_19,
- [RSL_SYSTEM_INFO_20] = SYSINFO_TYPE_20,
- [RSL_SYSTEM_INFO_2bis] = SYSINFO_TYPE_2bis,
- [RSL_SYSTEM_INFO_2ter] = SYSINFO_TYPE_2ter,
- [RSL_SYSTEM_INFO_2quater] = SYSINFO_TYPE_2quater,
- [RSL_SYSTEM_INFO_5bis] = SYSINFO_TYPE_5bis,
- [RSL_SYSTEM_INFO_5ter] = SYSINFO_TYPE_5ter,
- [RSL_EXT_MEAS_ORDER] = SYSINFO_TYPE_EMO,
- [RSL_MEAS_INFO] = SYSINFO_TYPE_MEAS_INFO,
-};
-
-const struct value_string osmo_sitype_strs[_MAX_SYSINFO_TYPE] = {
- { SYSINFO_TYPE_1, "1" },
- { SYSINFO_TYPE_2, "2" },
- { SYSINFO_TYPE_3, "3" },
- { SYSINFO_TYPE_4, "4" },
- { SYSINFO_TYPE_5, "5" },
- { SYSINFO_TYPE_6, "6" },
- { SYSINFO_TYPE_7, "7" },
- { SYSINFO_TYPE_8, "8" },
- { SYSINFO_TYPE_9, "9" },
- { SYSINFO_TYPE_10, "10" },
- { SYSINFO_TYPE_13, "13" },
- { SYSINFO_TYPE_16, "16" },
- { SYSINFO_TYPE_17, "17" },
- { SYSINFO_TYPE_18, "18" },
- { SYSINFO_TYPE_19, "19" },
- { SYSINFO_TYPE_20, "20" },
- { SYSINFO_TYPE_2bis, "2bis" },
- { SYSINFO_TYPE_2ter, "2ter" },
- { SYSINFO_TYPE_2quater, "2quater" },
- { SYSINFO_TYPE_5bis, "5bis" },
- { SYSINFO_TYPE_5ter, "5ter" },
- { SYSINFO_TYPE_EMO, "EMO" },
- { SYSINFO_TYPE_MEAS_INFO, "MI" },
- { 0, NULL }
-};
-
-uint8_t osmo_sitype2rsl(enum osmo_sysinfo_type si_type)
-{
- return sitype2rsl[si_type];
-}
-
-enum osmo_sysinfo_type osmo_rsl2sitype(uint8_t rsl_si)
-{
- return rsl2sitype[rsl_si];
-}
diff --git a/src/shared/libosmocore/src/gsm/tlv_parser.c b/src/shared/libosmocore/src/gsm/tlv_parser.c
deleted file mode 100644
index d18a6bfd..00000000
--- a/src/shared/libosmocore/src/gsm/tlv_parser.c
+++ /dev/null
@@ -1,209 +0,0 @@
-#include <stdio.h>
-#include <stdint.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/tlv.h>
-
-/*! \addtogroup tlv
- * @{
- */
-/*! \file tlv.c */
-
-struct tlv_definition tvlv_att_def;
-struct tlv_definition vtvlv_gan_att_def;
-
-/*! \brief Dump pasred TLV structure to stdout */
-int tlv_dump(struct tlv_parsed *dec)
-{
- int i;
-
- for (i = 0; i <= 0xff; i++) {
- if (!dec->lv[i].val)
- continue;
- printf("T=%02x L=%d\n", i, dec->lv[i].len);
- }
- return 0;
-}
-
-/*! \brief Parse a single TLV encoded IE
- * \param[out] o_tag the tag of the IE that was found
- * \param[out] o_len length of the IE that was found
- * \param[out] o_val pointer to the data of the IE that was found
- * \param[in] def structure defining the valid TLV tags / configurations
- * \param[in] buf the input data buffer to be parsed
- * \param[in] buf_len length of the input data buffer
- * \returns number of bytes consumed by the TLV entry / IE parsed
- */
-int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val,
- const struct tlv_definition *def,
- const uint8_t *buf, int buf_len)
-{
- uint8_t tag;
- int len;
-
- tag = *buf;
- *o_tag = tag;
-
- /* single octet TV IE */
- if (def->def[tag & 0xf0].type == TLV_TYPE_SINGLE_TV) {
- *o_tag = tag & 0xf0;
- *o_val = buf;
- *o_len = 1;
- return 1;
- }
-
- /* FIXME: use tables for knwon IEI */
- switch (def->def[tag].type) {
- case TLV_TYPE_T:
- /* GSM TS 04.07 11.2.4: Type 1 TV or Type 2 T */
- *o_val = buf;
- *o_len = 0;
- len = 1;
- break;
- case TLV_TYPE_TV:
- *o_val = buf+1;
- *o_len = 1;
- len = 2;
- break;
- case TLV_TYPE_FIXED:
- *o_val = buf+1;
- *o_len = def->def[tag].fixed_len;
- len = def->def[tag].fixed_len + 1;
- break;
- case TLV_TYPE_TLV:
-tlv: /* GSM TS 04.07 11.2.4: Type 4 TLV */
- if (buf + 1 > buf + buf_len)
- return -1;
- *o_val = buf+2;
- *o_len = *(buf+1);
- len = *o_len + 2;
- if (len > buf_len)
- return -2;
- break;
- case TLV_TYPE_vTvLV_GAN: /* 44.318 / 11.1.4 */
- /* FIXME: variable-length TAG! */
- if (*(buf+1) & 0x80) {
- /* like TL16Vbut without highest bit of len */
- if (2 > buf_len)
- return -1;
- *o_val = buf+3;
- *o_len = (*(buf+1) & 0x7F) << 8 | *(buf+2);
- len = *o_len + 3;
- if (len > buf_len)
- return -2;
- } else {
- /* like TLV */
- goto tlv;
- }
- break;
- case TLV_TYPE_TvLV:
- if (*(buf+1) & 0x80) {
- /* like TLV, but without highest bit of len */
- if (buf + 1 > buf + buf_len)
- return -1;
- *o_val = buf+2;
- *o_len = *(buf+1) & 0x7f;
- len = *o_len + 2;
- if (len > buf_len)
- return -2;
- break;
- }
- /* like TL16V, fallthrough */
- case TLV_TYPE_TL16V:
- if (2 > buf_len)
- return -1;
- *o_val = buf+3;
- *o_len = *(buf+1) << 8 | *(buf+2);
- len = *o_len + 3;
- if (len > buf_len)
- return -2;
- break;
- default:
- return -3;
- }
-
- return len;
-}
-
-/*! \brief Parse an entire buffer of TLV encoded Information Eleemnts
- * \param[out] dec caller-allocated pointer to \ref tlv_parsed
- * \param[in] def structure defining the valid TLV tags / configurations
- * \param[in] buf the input data buffer to be parsed
- * \param[in] buf_len length of the input data buffer
- * \param[in] lv_tag an initial LV tag at the start of the buffer
- * \param[in] lv_tag2 a second initial LV tag following the \a lv_tag
- * \returns number of bytes consumed by the TLV entry / IE parsed
- */
-int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
- const uint8_t *buf, int buf_len, uint8_t lv_tag,
- uint8_t lv_tag2)
-{
- int ofs = 0, num_parsed = 0;
- uint16_t len;
-
- memset(dec, 0, sizeof(*dec));
-
- if (lv_tag) {
- if (ofs > buf_len)
- return -1;
- dec->lv[lv_tag].val = &buf[ofs+1];
- dec->lv[lv_tag].len = buf[ofs];
- len = dec->lv[lv_tag].len + 1;
- if (ofs + len > buf_len)
- return -2;
- num_parsed++;
- ofs += len;
- }
- if (lv_tag2) {
- if (ofs > buf_len)
- return -1;
- dec->lv[lv_tag2].val = &buf[ofs+1];
- dec->lv[lv_tag2].len = buf[ofs];
- len = dec->lv[lv_tag2].len + 1;
- if (ofs + len > buf_len)
- return -2;
- num_parsed++;
- ofs += len;
- }
-
- while (ofs < buf_len) {
- int rv;
- uint8_t tag;
- const uint8_t *val;
-
- rv = tlv_parse_one(&tag, &len, &val, def,
- &buf[ofs], buf_len-ofs);
- if (rv < 0)
- return rv;
- dec->lv[tag].val = val;
- dec->lv[tag].len = len;
- ofs += rv;
- num_parsed++;
- }
- //tlv_dump(dec);
- return num_parsed;
-}
-
-/*! \brief take a master (src) tlvdev and fill up all empty slots in 'dst' */
-void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(dst->def); i++) {
- if (src->def[i].type == TLV_TYPE_NONE)
- continue;
- if (dst->def[i].type == TLV_TYPE_NONE)
- dst->def[i] = src->def[i];
- }
-}
-
-static __attribute__((constructor)) void on_dso_load_tlv(void)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++)
- tvlv_att_def.def[i].type = TLV_TYPE_TvLV;
-
- for (i = 0; i < ARRAY_SIZE(vtvlv_gan_att_def.def); i++)
- vtvlv_gan_att_def.def[i].type = TLV_TYPE_vTvLV_GAN;
-}
-
-/*! @} */