Change in osmo-sgsn[master]: remove libcommon

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Mon Jul 30 16:29:20 UTC 2018


Harald Welte has uploaded this change for review. ( https://gerrit.osmocom.org/10260


Change subject: remove libcommon
......................................................................

remove libcommon

This seems to b remaining from ancient days. The code
in there is either no longer needed, or has been moved to libosmocore.

Change-Id: I9307f9da7f48dd0a2e1cb213072068736e569722
---
D src/libcommon/Makefile.am
D src/libcommon/debug.c
D src/libcommon/gsm_data.c
D src/libcommon/gsm_data_shared.c
D src/libcommon/gsm_subscriber_base.c
D src/libcommon/gsup_client.c
D src/libcommon/gsup_test_client.c
D src/libcommon/socket.c
D src/libcommon/talloc_ctx.c
9 files changed, 0 insertions(+), 2,446 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/60/10260/1

diff --git a/src/libcommon/Makefile.am b/src/libcommon/Makefile.am
deleted file mode 100644
index 69fb37d..0000000
--- a/src/libcommon/Makefile.am
+++ /dev/null
@@ -1,45 +0,0 @@
-AM_CPPFLAGS = \
-	$(all_includes) \
-	-I$(top_srcdir)/include \
-	-I$(top_builddir) \
-	$(NULL)
-
-AM_CFLAGS = \
-	-Wall \
-	$(LIBOSMOCORE_CFLAGS) \
-	$(LIBOSMOGSM_CFLAGS) \
-	$(LIBOSMOVTY_CFLAGS) \
-	$(LIBOSMOABIS_CFLAGS) \
-	$(COVERAGE_CFLAGS) \
-	$(NULL)
-
-noinst_LIBRARIES = \
-	libcommon.a \
-	$(NULL)
-
-libcommon_a_SOURCES = \
-	debug.c \
-	gsm_data.c \
-	gsm_data_shared.c \
-	gsup_client.c \
-	oap_client.c \
-	socket.c \
-	talloc_ctx.c \
-	gsm_subscriber_base.c \
-	$(NULL)
-
-noinst_PROGRAMS = \
-	gsup_test_client \
-	$(NULL)
-
-gsup_test_client_SOURCES = \
-	gsup_test_client.c \
-	$(NULL)
-gsup_test_client_LDADD = \
-	libcommon.a \
-	$(LIBOSMOCORE_LIBS) \
-	$(LIBOSMOGSM_LIBS) \
-	$(LIBOSMOVTY_LIBS) \
-	$(LIBOSMOABIS_LIBS) \
-	-lrt \
-	$(NULL)
diff --git a/src/libcommon/debug.c b/src/libcommon/debug.c
deleted file mode 100644
index 27d7575..0000000
--- a/src/libcommon/debug.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/* OpenBSC Debugging/Logging support code */
-
-/* (C) 2008-2010 by Harald Welte <laforge at gnumonks.org>
- * (C) 2008 by Holger Hans Peter Freyther <zecke at selfish.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 <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <time.h>
-#include <errno.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/gprs/gprs_msgb.h>
-#include <osmocom/sgsn/gsm_data.h>
-#include <osmocom/sgsn/debug.h>
-
-/* default categories */
-static const struct log_info_cat default_categories[] = {
-	[DRLL] = {
-		.name = "DRLL",
-		.description = "A-bis Radio Link Layer (RLL)",
-		.color = "\033[1;31m",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DCC] = {
-		.name = "DCC",
-		.description = "Layer3 Call Control (CC)",
-		.color = "\033[1;32m",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DMM] = {
-		.name = "DMM",
-		.description = "Layer3 Mobility Management (MM)",
-		.color = "\033[1;33m",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DRR] = {
-		.name = "DRR",
-		.description = "Layer3 Radio Resource (RR)",
-		.color = "\033[1;34m",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DRSL] = {
-		.name = "DRSL",
-		.description = "A-bis Radio Siganlling Link (RSL)",
-		.color = "\033[1;35m",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DNM] =	{
-		.name = "DNM",
-		.description = "A-bis Network Management / O&M (NM/OML)",
-		.color = "\033[1;36m",
-		.enabled = 1, .loglevel = LOGL_INFO,
-	},
-	[DMNCC] = {
-		.name = "DMNCC",
-		.description = "MNCC API for Call Control application",
-		.color = "\033[1;39m",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DPAG]	= {
-		.name = "DPAG",
-		.description = "Paging Subsystem",
-		.color = "\033[1;38m",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DMEAS] = {
-		.name = "DMEAS",
-		.description = "Radio Measurement Processing",
-		.enabled = 0, .loglevel = LOGL_NOTICE,
-	},
-	[DSCCP] = {
-		.name = "DSCCP",
-		.description = "SCCP Protocol",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DMSC] = {
-		.name = "DMSC",
-		.description = "Mobile Switching Center",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DHO] = {
-		.name = "DHO",
-		.description = "Hand-Over",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DDB] = {
-		.name = "DDB",
-		.description = "Database Layer",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DREF] = {
-		.name = "DREF",
-		.description = "Reference Counting",
-		.enabled = 0, .loglevel = LOGL_NOTICE,
-	},
-	[DGPRS] = {
-		.name = "DGPRS",
-		.description = "GPRS Packet Service",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DNS] = {
-		.name = "DNS",
-		.description = "GPRS Network Service (NS)",
-		.enabled = 1, .loglevel = LOGL_INFO,
-	},
-	[DBSSGP] = {
-		.name = "DBSSGP",
-		.description = "GPRS BSS Gateway Protocol (BSSGP)",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DLLC] = {
-		.name = "DLLC",
-		.description = "GPRS Logical Link Control Protocol (LLC)",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DSNDCP] = {
-		.name = "DSNDCP",
-		.description = "GPRS Sub-Network Dependent Control Protocol (SNDCP)",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DNAT] = {
-		.name = "DNAT",
-		.description = "GSM 08.08 NAT/Multiplexer",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DCTRL] = {
-		.name = "DCTRL",
-		.description = "Control interface",
-		.enabled = 1, .loglevel = LOGL_NOTICE,
-	},
-	[DFILTER] = {
-		.name = "DFILTER",
-		.description = "BSC/NAT IMSI based filtering",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DRANAP] = {
-		.name = "DRANAP",
-		.description = "Radio Access Network Application Part Protocol",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DSUA] = {
-		.name = "DSUA",
-		.description = "SCCP User Adaptation Protocol",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DPCU] = {
-		.name = "DPCU",
-		.description = "PCU Interface",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DVLR] = {
-		.name = "DVLR",
-		.description = "Visitor Location Register",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DIUCS] = {
-		.name = "DIUCS",
-		.description = "Iu-CS Protocol",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-	[DSIGTRAN] = {
-		.name = "DSIGTRAN",
-		.description = "SIGTRAN Signalling Transport",
-		.color = "\033[1;29m",
-		.enabled = 1, .loglevel = LOGL_DEBUG,
-	},
-};
-
-static int filter_fn(const struct log_context *ctx, struct log_target *tar)
-{
-	const struct vlr_subscr *vsub = ctx->ctx[LOG_CTX_VLR_SUBSCR];
-	const struct bsc_subscr *bsub = ctx->ctx[LOG_CTX_BSC_SUBSCR];
-	const struct gprs_nsvc *nsvc = ctx->ctx[LOG_CTX_GB_NSVC];
-	const struct gprs_nsvc *bvc = ctx->ctx[LOG_CTX_GB_BVC];
-
-	if ((tar->filter_map & (1 << LOG_FLT_VLR_SUBSCR)) != 0
-	    && vsub && vsub == tar->filter_data[LOG_FLT_VLR_SUBSCR])
-		return 1;
-
-	if ((tar->filter_map & (1 << LOG_FLT_BSC_SUBSCR)) != 0
-	    && bsub && bsub == tar->filter_data[LOG_FLT_BSC_SUBSCR])
-		return 1;
-
-	/* Filter on the NS Virtual Connection */
-	if ((tar->filter_map & (1 << LOG_FLT_GB_NSVC)) != 0
-	    && nsvc && (nsvc == tar->filter_data[LOG_FLT_GB_NSVC]))
-		return 1;
-
-	/* Filter on the NS Virtual Connection */
-	if ((tar->filter_map & (1 << LOG_FLT_GB_BVC)) != 0
-	    && bvc && (bvc == tar->filter_data[LOG_FLT_GB_BVC]))
-		return 1;
-
-	return 0;
-}
-
-const struct log_info log_info = {
-	.filter_fn = filter_fn,
-	.cat = default_categories,
-	.num_cat = ARRAY_SIZE(default_categories),
-};
diff --git a/src/libcommon/gsm_data.c b/src/libcommon/gsm_data.c
deleted file mode 100644
index 6400963..0000000
--- a/src/libcommon/gsm_data.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/* (C) 2008-2010 by Harald Welte <laforge at 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <stdbool.h>
-#include <netinet/in.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/abis_nm.h>
-#include <osmocom/core/statistics.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-#include <osmocom/sgsn/gsm_data.h>
-#include <osmocom/sgsn/bsc_msc_data.h>
-#include <osmocom/sgsn/abis_nm.h>
-
-void *tall_bsc_ctx;
-
-static LLIST_HEAD(bts_models);
-
-void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
-		   uint8_t e1_ts, uint8_t e1_ts_ss)
-{
-	ts->e1_link.e1_nr = e1_nr;
-	ts->e1_link.e1_ts = e1_ts;
-	ts->e1_link.e1_ts_ss = e1_ts_ss;
-}
-
-static struct gsm_bts_model *bts_model_find(enum gsm_bts_type type)
-{
-	struct gsm_bts_model *model;
-
-	llist_for_each_entry(model, &bts_models, list) {
-		if (model->type == type)
-			return model;
-	}
-
-	return NULL;
-}
-
-int gsm_bts_model_register(struct gsm_bts_model *model)
-{
-	if (bts_model_find(model->type))
-		return -EEXIST;
-
-	tlv_def_patch(&model->nm_att_tlvdef, &abis_nm_att_tlvdef);
-	llist_add_tail(&model->list, &bts_models);
-	return 0;
-}
-
-const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1] = {
-	{ GSM_BTS_TYPE_UNKNOWN,		"Unknown BTS Type" },
-	{ GSM_BTS_TYPE_BS11,		"Siemens BTS (BS-11 or compatible)" },
-	{ GSM_BTS_TYPE_NANOBTS,		"ip.access nanoBTS or compatible" },
-	{ GSM_BTS_TYPE_RBS2000,		"Ericsson RBS2000 Series" },
-	{ GSM_BTS_TYPE_NOKIA_SITE,	"Nokia {Metro,Ultra,In}Site" },
-	{ GSM_BTS_TYPE_OSMOBTS,		"sysmocom sysmoBTS" },
-	{ 0,				NULL }
-};
-
-struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr)
-{
-	struct gsm_bts_trx *trx;
-
-	llist_for_each_entry(trx, &bts->trx_list, list) {
-		if (trx->nr == nr)
-			return trx;
-	}
-	return NULL;
-}
-
-/* Search for a BTS in the given Location Area; optionally start searching
- * with start_bts (for continuing to search after the first result) */
-struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
-				struct gsm_bts *start_bts)
-{
-	int i;
-	struct gsm_bts *bts;
-	int skip = 0;
-
-	if (start_bts)
-		skip = 1;
-
-	for (i = 0; i < net->num_bts; i++) {
-		bts = gsm_bts_num(net, i);
-
-		if (skip) {
-			if (start_bts == bts)
-				skip = 0;
-			continue;
-		}
-
-		if (lac == GSM_LAC_RESERVED_ALL_BTS || bts->location_area_code == lac)
-			return bts;
-	}
-	return NULL;
-}
-
-static const struct value_string auth_policy_names[] = {
-	{ GSM_AUTH_POLICY_CLOSED,	"closed" },
-	{ GSM_AUTH_POLICY_ACCEPT_ALL,	"accept-all" },
-	{ GSM_AUTH_POLICY_TOKEN,	"token" },
-	{ GSM_AUTH_POLICY_REGEXP,	"regexp" },
-	{ 0,				NULL }
-};
-
-enum gsm_auth_policy gsm_auth_policy_parse(const char *arg)
-{
-	return get_string_value(auth_policy_names, arg);
-}
-
-const char *gsm_auth_policy_name(enum gsm_auth_policy policy)
-{
-	return get_value_string(auth_policy_names, policy);
-}
-
-static const struct value_string rrlp_mode_names[] = {
-	{ RRLP_MODE_NONE,	"none" },
-	{ RRLP_MODE_MS_BASED,	"ms-based" },
-	{ RRLP_MODE_MS_PREF,	"ms-preferred" },
-	{ RRLP_MODE_ASS_PREF,	"ass-preferred" },
-	{ 0,			NULL }
-};
-
-enum rrlp_mode rrlp_mode_parse(const char *arg)
-{
-	return get_string_value(rrlp_mode_names, arg);
-}
-
-const char *rrlp_mode_name(enum rrlp_mode mode)
-{
-	return get_value_string(rrlp_mode_names, mode);
-}
-
-static const struct value_string bts_gprs_mode_names[] = {
-	{ BTS_GPRS_NONE,	"none" },
-	{ BTS_GPRS_GPRS,	"gprs" },
-	{ BTS_GPRS_EGPRS,	"egprs" },
-	{ 0,			NULL }
-};
-
-enum bts_gprs_mode bts_gprs_mode_parse(const char *arg, int *valid)
-{
-	int rc;
-
-	rc = get_string_value(bts_gprs_mode_names, arg);
-	if (valid)
-		*valid = rc != -EINVAL;
-	return rc;
-}
-
-const char *bts_gprs_mode_name(enum bts_gprs_mode mode)
-{
-	return get_value_string(bts_gprs_mode_names, mode);
-}
-
-int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode)
-{
-	if (mode != BTS_GPRS_NONE &&
-	    !gsm_btsmodel_has_feature(bts->model, BTS_FEAT_GPRS)) {
-		return 0;
-	}
-	if (mode == BTS_GPRS_EGPRS &&
-	    !gsm_btsmodel_has_feature(bts->model, BTS_FEAT_EGPRS)) {
-		return 0;
-	}
-
-	return 1;
-}
-
-int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat)
-{
-	OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
-	return bitvec_set_bit_pos(&model->features, feat, 1);
-}
-
-bool gsm_btsmodel_has_feature(struct gsm_bts_model *model, enum gsm_bts_features feat)
-{
-	OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
-	return bitvec_get_bit_pos(&model->features, feat);
-}
-
-int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type)
-{
-	struct gsm_bts_model *model;
-
-	model = bts_model_find(type);
-	if (!model)
-		return -EINVAL;
-
-	bts->type = type;
-	bts->model = model;
-
-	if (model->start && !model->started) {
-		int ret = model->start(bts->network);
-		if (ret < 0)
-			return ret;
-
-		model->started = true;
-	}
-
-	switch (bts->type) {
-	case GSM_BTS_TYPE_NANOBTS:
-	case GSM_BTS_TYPE_OSMOBTS:
-		/* Set the default OML Stream ID to 0xff */
-		bts->oml_tei = 0xff;
-		bts->c0->nominal_power = 23;
-		break;
-	case GSM_BTS_TYPE_RBS2000:
-		INIT_LLIST_HEAD(&bts->rbs2000.is.conn_groups);
-		INIT_LLIST_HEAD(&bts->rbs2000.con.conn_groups);
-		break;
-	case GSM_BTS_TYPE_BS11:
-	case GSM_BTS_TYPE_UNKNOWN:
-	case GSM_BTS_TYPE_NOKIA_SITE:
-		/* Set default BTS reset timer */
-		bts->nokia.bts_reset_timer_cnf = 15;
-	case _NUM_GSM_BTS_TYPE:
-		break;
-	}
-
-	return 0;
-}
-
-struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net, enum gsm_bts_type type,
-					uint8_t bsic)
-{
-	struct gsm_bts_model *model = bts_model_find(type);
-	struct gsm_bts *bts;
-
-	if (!model && type != GSM_BTS_TYPE_UNKNOWN)
-		return NULL;
-
-	bts = gsm_bts_alloc(net, net->num_bts);
-	if (!bts)
-		return NULL;
-
-	net->num_bts++;
-
-	bts->network = net;
-	bts->type = type;
-	bts->model = model;
-	bts->bsic = bsic;
-	bts->dtxu = GSM48_DTX_SHALL_NOT_BE_USED;
-	bts->dtxd = false;
-	bts->gprs.ctrl_ack_type_use_block = true; /* use RLC/MAC control block */
-	bts->neigh_list_manual_mode = 0;
-	bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */
-	bts->si_common.cell_sel_par.rxlev_acc_min = 0;
-	bts->si_common.si2quater_neigh_list.arfcn = bts->si_common.data.earfcn_list;
-	bts->si_common.si2quater_neigh_list.meas_bw = bts->si_common.data.meas_bw_list;
-	bts->si_common.si2quater_neigh_list.length = MAX_EARFCN_LIST;
-	bts->si_common.si2quater_neigh_list.thresh_hi = 0;
-	osmo_earfcn_init(&bts->si_common.si2quater_neigh_list);
-	bts->si_common.neigh_list.data = bts->si_common.data.neigh_list;
-	bts->si_common.neigh_list.data_len =
-				sizeof(bts->si_common.data.neigh_list);
-	bts->si_common.si5_neigh_list.data = bts->si_common.data.si5_neigh_list;
-	bts->si_common.si5_neigh_list.data_len =
-				sizeof(bts->si_common.data.si5_neigh_list);
-	bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc;
-	bts->si_common.cell_alloc.data_len =
-				sizeof(bts->si_common.data.cell_alloc);
-	bts->si_common.rach_control.re = 1; /* no re-establishment */
-	bts->si_common.rach_control.tx_integer = 9;  /* 12 slots spread - 217/115 slots delay */
-	bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
-	bts->si_common.rach_control.t2 = 4; /* no emergency calls */
-	bts->si_common.chan_desc.att = 1; /* attachment required */
-	bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5; /* paging frames */
-	bts->si_common.chan_desc.bs_ag_blks_res = 1; /* reserved AGCH blocks */
-	bts->si_common.chan_desc.t3212 = net->t3212; /* Use network's current value */
-	gsm_bts_set_radio_link_timeout(bts, 32); /* Use RADIO LINK TIMEOUT of 32 */
-
-	llist_add_tail(&bts->list, &net->bts_list);
-
-	INIT_LLIST_HEAD(&bts->abis_queue);
-
-	INIT_LLIST_HEAD(&bts->loc_list);
-
-	return bts;
-}
-
-void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts)
-{
-	raid->mcc = bts->network->country_code;
-	raid->mnc = bts->network->network_code;
-	raid->lac = bts->location_area_code;
-	raid->rac = bts->gprs.rac;
-}
-
-int gsm_parse_reg(void *ctx, regex_t *reg, char **str, int argc, const char **argv)
-{
-	int ret;
-
-	ret = 0;
-	if (*str) {
-		talloc_free(*str);
-		*str = NULL;
-	}
-	regfree(reg);
-
-	if (argc > 0) {
-		*str = talloc_strdup(ctx, argv[0]);
-		ret = regcomp(reg, argv[0], 0);
-
-		/* handle compilation failures */
-		if (ret != 0) {
-			talloc_free(*str);
-			*str = NULL;
-		}
-	}
-
-	return ret;
-}
-
-/* Assume there are only 256 possible bts */
-osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);
-static void depends_calc_index_bit(int bts_nr, int *idx, int *bit)
-{
-	*idx = bts_nr / (8 * 4);
-	*bit = bts_nr % (8 * 4);
-}
-
-void bts_depend_mark(struct gsm_bts *bts, int dep)
-{
-	int idx, bit;
-	depends_calc_index_bit(dep, &idx, &bit);
-
-	bts->depends_on[idx] |= 1 << bit;
-}
-
-void bts_depend_clear(struct gsm_bts *bts, int dep)
-{
-	int idx, bit;
-	depends_calc_index_bit(dep, &idx, &bit);
-
-	bts->depends_on[idx] &= ~(1 << bit);
-}
-
-int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
-{
-	int idx, bit;
-	depends_calc_index_bit(other->nr, &idx, &bit);
-
-	/* Check if there is a depends bit */
-	return (base->depends_on[idx] & (1 << bit)) > 0;
-}
-
-static int bts_is_online(struct gsm_bts *bts)
-{
-	/* TODO: support E1 BTS too */
-	if (!is_ipaccess_bts(bts))
-		return 1;
-
-	if (!bts->oml_link)
-		return 0;
-
-	return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
-}
-
-int bts_depend_check(struct gsm_bts *bts)
-{
-	struct gsm_bts *other_bts;
-
-	llist_for_each_entry(other_bts, &bts->network->bts_list, list) {
-		if (!bts_depend_is_depedency(bts, other_bts))
-			continue;
-		if (bts_is_online(other_bts))
-			continue;
-		return 0;
-	}
-	return 1;
-}
-
-/* get the radio link timeout (based on SACCH decode errors, according
- * to algorithm specified in TS 05.08 section 5.2.  A value of -1
- * indicates we should use an infinitely long timeout, which only works
- * with OsmoBTS as the BTS implementation */
-int gsm_bts_get_radio_link_timeout(const struct gsm_bts *bts)
-{
-	const struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
-
-	if (bts->infinite_radio_link_timeout)
-		return -1;
-	else {
-		/* Encoding as per Table 10.5.21 of TS 04.08 */
-		return (cell_options->radio_link_timeout + 1) << 2;
-	}
-}
-
-/* set the radio link timeout (based on SACCH decode errors, according
- * to algorithm specified in TS 05.08 Section 5.2.  A value of -1
- * indicates we should use an infinitely long timeout, which only works
- * with OsmoBTS as the BTS implementation */
-void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value)
-{
-	struct gsm48_cell_options *cell_options = &bts->si_common.cell_options;
-
-	if (value < 0)
-		bts->infinite_radio_link_timeout = true;
-	else {
-		bts->infinite_radio_link_timeout = false;
-		/* Encoding as per Table 10.5.21 of TS 04.08 */
-		if (value < 4)
-			value = 4;
-		if (value > 64)
-			value = 64;
-		cell_options->radio_link_timeout = (value >> 2) - 1;
-	}
-}
-
-bool classmark_is_r99(struct gsm_classmark *cm)
-{
-	int rev_lev = 0;
-	if (cm->classmark1_set)
-		rev_lev = cm->classmark1.rev_lev;
-	else if (cm->classmark2_len > 0)
-		rev_lev = (cm->classmark2[0] >> 5) & 0x3;
-	return rev_lev >= 2;
-}
-
-const struct value_string ran_type_names[] = {
-	OSMO_VALUE_STRING(RAN_UNKNOWN),
-	OSMO_VALUE_STRING(RAN_GERAN_A),
-	OSMO_VALUE_STRING(RAN_UTRAN_IU),
-	{ 0, NULL }
-};
diff --git a/src/libcommon/gsm_data_shared.c b/src/libcommon/gsm_data_shared.c
deleted file mode 100644
index 8d5f990..0000000
--- a/src/libcommon/gsm_data_shared.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/* (C) 2008-2010 by Harald Welte <laforge at 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include <netinet/in.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/abis_nm.h>
-#include <osmocom/core/statistics.h>
-
-#include <osmocom/sgsn/gsm_data.h>
-
-void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
-{
-	mo->nm_state.operational = NM_OPSTATE_NULL;
-	mo->nm_state.availability = NM_AVSTATE_POWER_OFF;
-}
-
-static void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
-			uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)
-{
-	mo->bts = bts;
-	mo->obj_class = obj_class;
-	mo->obj_inst.bts_nr = p1;
-	mo->obj_inst.trx_nr = p2;
-	mo->obj_inst.ts_nr = p3;
-	gsm_abis_mo_reset(mo);
-}
-
-const struct value_string bts_attribute_names[] = {
-	OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
-	OSMO_VALUE_STRING(BTS_SUB_MODEL),
-	OSMO_VALUE_STRING(TRX_PHY_VERSION),
-	{ 0, NULL }
-};
-
-enum bts_attribute str2btsattr(const char *s)
-{
-	return get_string_value(bts_attribute_names, s);
-}
-
-const char *btsatttr2str(enum bts_attribute v)
-{
-	return get_value_string(bts_attribute_names, v);
-}
-
-const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
-	{ BTS_UNKNOWN,		"unknown" },
-	{ BTS_OSMO_LITECELL15,	"osmo-bts-lc15" },
-	{ BTS_OSMO_OCTPHY,	"osmo-bts-octphy" },
-	{ BTS_OSMO_SYSMO,	"osmo-bts-sysmo" },
-	{ BTS_OSMO_TRX,		"omso-bts-trx" },
-	{ 0, NULL }
-};
-
-enum gsm_bts_type_variant str2btsvariant(const char *arg)
-{
-	return get_string_value(osmo_bts_variant_names, arg);
-}
-
-const char *btsvariant2str(enum gsm_bts_type_variant v)
-{
-	return get_value_string(osmo_bts_variant_names, v);
-}
-
-const struct value_string bts_type_names[_NUM_GSM_BTS_TYPE + 1] = {
-	{ GSM_BTS_TYPE_UNKNOWN,		"unknown" },
-	{ GSM_BTS_TYPE_BS11,		"bs11" },
-	{ GSM_BTS_TYPE_NANOBTS,		"nanobts" },
-	{ GSM_BTS_TYPE_RBS2000,		"rbs2000" },
-	{ GSM_BTS_TYPE_NOKIA_SITE,	"nokia_site" },
-	{ GSM_BTS_TYPE_OSMOBTS,		"sysmobts" },
-	{ 0, NULL }
-};
-
-enum gsm_bts_type str2btstype(const char *arg)
-{
-	return get_string_value(bts_type_names, arg);
-}
-
-const char *btstype2str(enum gsm_bts_type type)
-{
-	return get_value_string(bts_type_names, type);
-}
-
-const struct value_string gsm_bts_features_descs[] = {
-	{ BTS_FEAT_HSCSD,		"HSCSD" },
-	{ BTS_FEAT_GPRS,		"GPRS" },
-	{ BTS_FEAT_EGPRS,		"EGPRS" },
-	{ BTS_FEAT_ECSD,		"ECSD" },
-	{ BTS_FEAT_HOPPING,		"Frequency Hopping" },
-	{ BTS_FEAT_MULTI_TSC,		"Multi-TSC" },
-	{ BTS_FEAT_OML_ALERTS,		"OML Alerts" },
-	{ BTS_FEAT_AGCH_PCH_PROP,	"AGCH/PCH proportional allocation" },
-	{ BTS_FEAT_CBCH,		"CBCH" },
-	{ 0, NULL }
-};
-
-const struct value_string gsm_chreq_descs[] = {
-	{ GSM_CHREQ_REASON_EMERG,	"emergency call" },
-	{ GSM_CHREQ_REASON_PAG,		"answer to paging" },
-	{ GSM_CHREQ_REASON_CALL,	"call re-establishment" },
-	{ GSM_CHREQ_REASON_LOCATION_UPD,"Location updating" },
-	{ GSM_CHREQ_REASON_PDCH,	"one phase packet access" },
-	{ GSM_CHREQ_REASON_OTHER,	"other" },
-	{ 0,				NULL }
-};
-
-const struct value_string gsm_pchant_names[13] = {
-	{ GSM_PCHAN_NONE,	"NONE" },
-	{ GSM_PCHAN_CCCH,	"CCCH" },
-	{ GSM_PCHAN_CCCH_SDCCH4,"CCCH+SDCCH4" },
-	{ GSM_PCHAN_TCH_F,	"TCH/F" },
-	{ GSM_PCHAN_TCH_H,	"TCH/H" },
-	{ GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" },
-	{ GSM_PCHAN_PDCH,	"PDCH" },
-	{ GSM_PCHAN_TCH_F_PDCH,	"TCH/F_PDCH" },
-	{ GSM_PCHAN_UNKNOWN,	"UNKNOWN" },
-	{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH+SDCCH4+CBCH" },
-	{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8+CBCH" },
-	{ GSM_PCHAN_TCH_F_TCH_H_PDCH, "TCH/F_TCH/H_PDCH" },
-	{ 0,			NULL }
-};
-
-const struct value_string gsm_pchant_descs[13] = {
-	{ GSM_PCHAN_NONE,	"Physical Channel not configured" },
-	{ GSM_PCHAN_CCCH,	"FCCH + SCH + BCCH + CCCH (Comb. IV)" },
-	{ GSM_PCHAN_CCCH_SDCCH4,
-		"FCCH + SCH + BCCH + CCCH + 4 SDCCH + 2 SACCH (Comb. V)" },
-	{ GSM_PCHAN_TCH_F,	"TCH/F + FACCH/F + SACCH (Comb. I)" },
-	{ GSM_PCHAN_TCH_H,	"2 TCH/H + 2 FACCH/H + 2 SACCH (Comb. II)" },
-	{ GSM_PCHAN_SDCCH8_SACCH8C, "8 SDCCH + 4 SACCH (Comb. VII)" },
-	{ GSM_PCHAN_PDCH,	"Packet Data Channel for GPRS/EDGE" },
-	{ GSM_PCHAN_TCH_F_PDCH,	"Dynamic TCH/F or GPRS PDCH" },
-	{ GSM_PCHAN_UNKNOWN,	"Unknown / Unsupported channel combination" },
-	{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "FCCH + SCH + BCCH + CCCH + CBCH + 3 SDCCH + 2 SACCH (Comb. V)" },
-	{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "7 SDCCH + 4 SACCH + CBCH (Comb. VII)" },
-	{ GSM_PCHAN_TCH_F_TCH_H_PDCH, "Dynamic TCH/F or TCH/H or GPRS PDCH" },
-	{ 0,			NULL }
-};
-
-const char *gsm_pchan_name(enum gsm_phys_chan_config c)
-{
-	return get_value_string(gsm_pchant_names, c);
-}
-
-enum gsm_phys_chan_config gsm_pchan_parse(const char *name)
-{
-	return get_string_value(gsm_pchant_names, name);
-}
-
-/* TODO: move to libosmocore, next to gsm_chan_t_names? */
-const char *gsm_lchant_name(enum gsm_chan_t c)
-{
-	return get_value_string(gsm_chan_t_names, c);
-}
-
-static const struct value_string lchan_s_names[] = {
-	{ LCHAN_S_NONE,		"NONE" },
-	{ LCHAN_S_ACT_REQ,	"ACTIVATION REQUESTED" },
-	{ LCHAN_S_ACTIVE,	"ACTIVE" },
-	{ LCHAN_S_INACTIVE,	"INACTIVE" },
-	{ LCHAN_S_REL_REQ,	"RELEASE REQUESTED" },
-	{ LCHAN_S_REL_ERR,	"RELEASE DUE ERROR" },
-	{ LCHAN_S_BROKEN,	"BROKEN UNUSABLE" },
-	{ 0,			NULL }
-};
-
-const char *gsm_lchans_name(enum gsm_lchan_state s)
-{
-	return get_value_string(lchan_s_names, s);
-}
-
-static const struct value_string chreq_names[] = {
-	{ GSM_CHREQ_REASON_EMERG,	"EMERGENCY" },
-	{ GSM_CHREQ_REASON_PAG,		"PAGING" },
-	{ GSM_CHREQ_REASON_CALL,	"CALL" },
-	{ GSM_CHREQ_REASON_LOCATION_UPD,"LOCATION_UPDATE" },
-	{ GSM_CHREQ_REASON_OTHER,	"OTHER" },
-	{ 0,				NULL }
-};
-
-const char *gsm_chreq_name(enum gsm_chreq_reason_t c)
-{
-	return get_value_string(chreq_names, c);
-}
-
-struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num)
-{
-	struct gsm_bts *bts;
-
-	if (num >= net->num_bts)
-		return NULL;
-
-	llist_for_each_entry(bts, &net->bts_list, list) {
-		if (bts->nr == num)
-			return bts;
-	}
-
-	return NULL;
-}
-
-struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
-{
-	struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);
-	int k;
-
-	if (!trx)
-		return NULL;
-
-	trx->bts = bts;
-	trx->nr = bts->num_trx++;
-	trx->mo.nm_state.administrative = NM_STATE_UNLOCKED;
-
-	gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
-		    bts->nr, trx->nr, 0xff);
-	gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
-		    bts->nr, trx->nr, 0xff);
-
-	for (k = 0; k < TRX_NR_TS; k++) {
-		struct gsm_bts_trx_ts *ts = &trx->ts[k];
-		int l;
-
-		ts->trx = trx;
-		ts->nr = k;
-		ts->pchan = GSM_PCHAN_NONE;
-		ts->dyn.pchan_is = GSM_PCHAN_NONE;
-		ts->dyn.pchan_want = GSM_PCHAN_NONE;
-		ts->tsc = -1;
-
-		gsm_mo_init(&ts->mo, bts, NM_OC_CHANNEL,
-			    bts->nr, trx->nr, ts->nr);
-
-		ts->hopping.arfcns.data_len = sizeof(ts->hopping.arfcns_data);
-		ts->hopping.arfcns.data = ts->hopping.arfcns_data;
-		ts->hopping.ma.data_len = sizeof(ts->hopping.ma_data);
-		ts->hopping.ma.data = ts->hopping.ma_data;
-
-		for (l = 0; l < TS_MAX_LCHAN; l++) {
-			struct gsm_lchan *lchan;
-			char *name;
-			lchan = &ts->lchan[l];
-
-			lchan->ts = ts;
-			lchan->nr = l;
-			lchan->type = GSM_LCHAN_NONE;
-
-			name = gsm_lchan_name_compute(lchan);
-			lchan->name = talloc_strdup(trx, name);
-#ifndef ROLE_BSC
-			INIT_LLIST_HEAD(&lchan->sapi_cmds);
-#endif
-		}
-	}
-
-	if (trx->nr != 0)
-		trx->nominal_power = bts->c0->nominal_power;
-
-	llist_add_tail(&trx->list, &bts->trx_list);
-
-	return trx;
-}
-
-
-static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
-static const uint8_t bts_cell_timer_default[] =
-				{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
-static const struct gprs_rlc_cfg rlc_cfg_default = {
-	.parameter = {
-		[RLC_T3142] = 20,
-		[RLC_T3169] = 5,
-		[RLC_T3191] = 5,
-		[RLC_T3193] = 160, /* 10ms */
-		[RLC_T3195] = 5,
-		[RLC_N3101] = 10,
-		[RLC_N3103] = 4,
-		[RLC_N3105] = 8,
-		[CV_COUNTDOWN] = 15,
-		[T_DL_TBF_EXT] = 250 * 10, /* ms */
-		[T_UL_TBF_EXT] = 250 * 10, /* ms */
-	},
-	.paging = {
-		.repeat_time = 5 * 50, /* ms */
-		.repeat_count = 3,
-	},
-	.cs_mask = 0x1fff,
-	.initial_cs = 2,
-	.initial_mcs = 6,
-};
-
-struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
-{
-	struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
-	int i;
-
-	if (!bts)
-		return NULL;
-
-	bts->nr = bts_num;
-	bts->num_trx = 0;
-	INIT_LLIST_HEAD(&bts->trx_list);
-	bts->ms_max_power = 15;	/* dBm */
-
-	gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
-			bts->nr, 0xff, 0xff);
-	gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
-			0xff, 0xff, 0xff);
-
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
-		bts->gprs.nsvc[i].bts = bts;
-		bts->gprs.nsvc[i].id = i;
-		gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
-				bts->nr, i, 0xff);
-	}
-	memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
-		sizeof(bts->gprs.nse.timer));
-	gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
-			bts->nr, 0xff, 0xff);
-	memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
-		sizeof(bts->gprs.cell.timer));
-	gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
-			bts->nr, 0xff, 0xff);
-	memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
-		sizeof(bts->gprs.cell.rlc_cfg));
-
-	/* create our primary TRX */
-	bts->c0 = gsm_bts_trx_alloc(bts);
-	if (!bts->c0) {
-		talloc_free(bts);
-		return NULL;
-	}
-	bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
-
-	bts->rach_b_thresh = -1;
-	bts->rach_ldavg_slots = -1;
-	bts->paging.free_chans_need = -1;
-	bts->features.data = &bts->_features_data[0];
-	bts->features.data_len = sizeof(bts->_features_data);
-
-	/* si handling */
-	bts->bcch_change_mark = 1;
-
-	return bts;
-}
-
-/* reset the state of all MO in the BTS */
-void gsm_bts_mo_reset(struct gsm_bts *bts)
-{
-	struct gsm_bts_trx *trx;
-	unsigned int i;
-
-	gsm_abis_mo_reset(&bts->mo);
-	gsm_abis_mo_reset(&bts->site_mgr.mo);
-	for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++)
-		gsm_abis_mo_reset(&bts->gprs.nsvc[i].mo);
-	gsm_abis_mo_reset(&bts->gprs.nse.mo);
-	gsm_abis_mo_reset(&bts->gprs.cell.mo);
-
-	llist_for_each_entry(trx, &bts->trx_list, list) {
-		gsm_abis_mo_reset(&trx->mo);
-		gsm_abis_mo_reset(&trx->bb_transc.mo);
-
-		for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
-			struct gsm_bts_trx_ts *ts = &trx->ts[i];
-			gsm_abis_mo_reset(&ts->mo);
-		}
-	}
-}
-
-struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
-{
-	struct gsm_bts_trx *trx;
-
-	if (num >= bts->num_trx)
-		return NULL;
-
-	llist_for_each_entry(trx, &bts->trx_list, list) {
-		if (trx->nr == num)
-			return trx;
-	}
-
-	return NULL;
-}
-
-static char ts2str[255];
-
-char *gsm_trx_name(const struct gsm_bts_trx *trx)
-{
-	if (!trx)
-		snprintf(ts2str, sizeof(ts2str), "(trx=NULL)");
-	else
-		snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d)",
-			 trx->bts->nr, trx->nr);
-
-	return ts2str;
-}
-
-
-char *gsm_ts_name(const struct gsm_bts_trx_ts *ts)
-{
-	snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d)",
-		 ts->trx->bts->nr, ts->trx->nr, ts->nr);
-
-	return ts2str;
-}
-
-/*! Log timeslot number with full pchan information */
-char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts)
-{
-	switch (ts->pchan) {
-	case GSM_PCHAN_TCH_F_TCH_H_PDCH:
-		if (ts->dyn.pchan_is == ts->dyn.pchan_want)
-			snprintf(ts2str, sizeof(ts2str),
-				 "(bts=%d,trx=%d,ts=%d,pchan=%s as %s)",
-				 ts->trx->bts->nr, ts->trx->nr, ts->nr,
-				 gsm_pchan_name(ts->pchan),
-				 gsm_pchan_name(ts->dyn.pchan_is));
-		else
-			snprintf(ts2str, sizeof(ts2str),
-				 "(bts=%d,trx=%d,ts=%d,pchan=%s"
-				 " switching %s -> %s)",
-				 ts->trx->bts->nr, ts->trx->nr, ts->nr,
-				 gsm_pchan_name(ts->pchan),
-				 gsm_pchan_name(ts->dyn.pchan_is),
-				 gsm_pchan_name(ts->dyn.pchan_want));
-		break;
-	case GSM_PCHAN_TCH_F_PDCH:
-		if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
-			snprintf(ts2str, sizeof(ts2str),
-				 "(bts=%d,trx=%d,ts=%d,pchan=%s as %s)",
-				 ts->trx->bts->nr, ts->trx->nr, ts->nr,
-				 gsm_pchan_name(ts->pchan),
-				 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
-							       : "TCH/F");
-		else
-			snprintf(ts2str, sizeof(ts2str),
-				 "(bts=%d,trx=%d,ts=%d,pchan=%s"
-				 " switching %s -> %s)",
-				 ts->trx->bts->nr, ts->trx->nr, ts->nr,
-				 gsm_pchan_name(ts->pchan),
-				 (ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
-							       : "TCH/F",
-				 (ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
-								    : "TCH/F");
-		break;
-	default:
-		snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d,pchan=%s)",
-			 ts->trx->bts->nr, ts->trx->nr, ts->nr,
-			 gsm_pchan_name(ts->pchan));
-		break;
-	}
-
-	return ts2str;
-}
-
-char *gsm_lchan_name_compute(const struct gsm_lchan *lchan)
-{
-	struct gsm_bts_trx_ts *ts = lchan->ts;
-
-	snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d,ss=%d)",
-		 ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr);
-
-	return ts2str;
-}
-
-/* obtain the MO structure for a given object instance */
-struct gsm_abis_mo *
-gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
-	    const struct abis_om_obj_inst *obj_inst)
-{
-	struct gsm_bts_trx *trx;
-	struct gsm_abis_mo *mo = NULL;
-
-	switch (obj_class) {
-	case NM_OC_BTS:
-		mo = &bts->mo;
-		break;
-	case NM_OC_RADIO_CARRIER:
-		if (obj_inst->trx_nr >= bts->num_trx) {
-			return NULL;
-		}
-		trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-		mo = &trx->mo;
-		break;
-	case NM_OC_BASEB_TRANSC:
-		if (obj_inst->trx_nr >= bts->num_trx) {
-			return NULL;
-		}
-		trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-		mo = &trx->bb_transc.mo;
-		break;
-	case NM_OC_CHANNEL:
-		if (obj_inst->trx_nr >= bts->num_trx) {
-			return NULL;
-		}
-		trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-		if (obj_inst->ts_nr >= TRX_NR_TS)
-			return NULL;
-		mo = &trx->ts[obj_inst->ts_nr].mo;
-		break;
-	case NM_OC_SITE_MANAGER:
-		mo = &bts->site_mgr.mo;
-		break;
-	case NM_OC_BS11:
-		switch (obj_inst->bts_nr) {
-		case BS11_OBJ_CCLK:
-			mo = &bts->bs11.cclk.mo;
-			break;
-		case BS11_OBJ_BBSIG:
-			if (obj_inst->ts_nr > bts->num_trx)
-				return NULL;
-			trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-			mo = &trx->bs11.bbsig.mo;
-			break;
-		case BS11_OBJ_PA:
-			if (obj_inst->ts_nr > bts->num_trx)
-				return NULL;
-			trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-			mo = &trx->bs11.pa.mo;
-			break;
-		default:
-			return NULL;
-		}
-		break;
-	case NM_OC_BS11_RACK:
-		mo = &bts->bs11.rack.mo;
-		break;
-	case NM_OC_BS11_ENVABTSE:
-		if (obj_inst->trx_nr >= ARRAY_SIZE(bts->bs11.envabtse))
-			return NULL;
-		mo = &bts->bs11.envabtse[obj_inst->trx_nr].mo;
-		break;
-	case NM_OC_GPRS_NSE:
-		mo = &bts->gprs.nse.mo;
-		break;
-	case NM_OC_GPRS_CELL:
-		mo = &bts->gprs.cell.mo;
-		break;
-	case NM_OC_GPRS_NSVC:
-		if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
-			return NULL;
-		mo = &bts->gprs.nsvc[obj_inst->trx_nr].mo;
-		break;
-	}
-	return mo;
-}
-
-/* obtain the gsm_nm_state data structure for a given object instance */
-struct gsm_nm_state *
-gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
-		 const struct abis_om_obj_inst *obj_inst)
-{
-	struct gsm_abis_mo *mo;
-
-	mo = gsm_objclass2mo(bts, obj_class, obj_inst);
-	if (!mo)
-		return NULL;
-
-	return &mo->nm_state;
-}
-
-/* obtain the in-memory data structure of a given object instance */
-void *
-gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
-	     const struct abis_om_obj_inst *obj_inst)
-{
-	struct gsm_bts_trx *trx;
-	void *obj = NULL;
-
-	switch (obj_class) {
-	case NM_OC_BTS:
-		obj = bts;
-		break;
-	case NM_OC_RADIO_CARRIER:
-		if (obj_inst->trx_nr >= bts->num_trx) {
-			return NULL;
-		}
-		trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-		obj = trx;
-		break;
-	case NM_OC_BASEB_TRANSC:
-		if (obj_inst->trx_nr >= bts->num_trx) {
-			return NULL;
-		}
-		trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-		obj = &trx->bb_transc;
-		break;
-	case NM_OC_CHANNEL:
-		if (obj_inst->trx_nr >= bts->num_trx) {
-			return NULL;
-		}
-		trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
-		if (obj_inst->ts_nr >= TRX_NR_TS)
-			return NULL;
-		obj = &trx->ts[obj_inst->ts_nr];
-		break;
-	case NM_OC_SITE_MANAGER:
-		obj = &bts->site_mgr;
-		break;
-	case NM_OC_GPRS_NSE:
-		obj = &bts->gprs.nse;
-		break;
-	case NM_OC_GPRS_CELL:
-		obj = &bts->gprs.cell;
-		break;
-	case NM_OC_GPRS_NSVC:
-		if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
-			return NULL;
-		obj = &bts->gprs.nsvc[obj_inst->trx_nr];
-		break;
-	}
-	return obj;
-}
-
-/* See Table 10.5.25 of GSM04.08 */
-uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
-			  uint8_t ts_nr, uint8_t lchan_nr)
-{
-	uint8_t cbits, chan_nr;
-
-	switch (pchan) {
-	case GSM_PCHAN_TCH_F:
-	case GSM_PCHAN_TCH_F_PDCH:
-		OSMO_ASSERT(lchan_nr == 0);
-		cbits = 0x01;
-		break;
-	case GSM_PCHAN_PDCH:
-		OSMO_ASSERT(lchan_nr == 0);
-		cbits = RSL_CHAN_OSMO_PDCH >> 3;
-		break;
-	case GSM_PCHAN_TCH_H:
-		OSMO_ASSERT(lchan_nr < 2);
-		cbits = 0x02;
-		cbits += lchan_nr;
-		break;
-	case GSM_PCHAN_CCCH_SDCCH4:
-	case GSM_PCHAN_CCCH_SDCCH4_CBCH:
-		/*
-		 * As a special hack for BCCH, lchan_nr == 4 may be passed
-		 * here. This should never be sent in an RSL message.
-		 * See osmo-bts-xxx/oml.c:opstart_compl().
-		 */
-		if (lchan_nr == CCCH_LCHAN)
-			chan_nr = 0;
-		else
-			OSMO_ASSERT(lchan_nr < 4);
-		cbits = 0x04;
-		cbits += lchan_nr;
-		break;
-	case GSM_PCHAN_SDCCH8_SACCH8C:
-	case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
-		OSMO_ASSERT(lchan_nr < 8);
-		cbits = 0x08;
-		cbits += lchan_nr;
-		break;
-	default:
-	case GSM_PCHAN_CCCH:
-#ifdef ROLE_BSC
-		OSMO_ASSERT(lchan_nr == 0);
-#else
-		/*
-		 * FIXME: On octphy and litecell, we hit above assertion (see
-		 * Max's comment at https://gerrit.osmocom.org/589 ); disabled
-		 * for BTS until this is clarified; remove the #ifdef when it
-		 * is fixed.
-		 */
-#warning "fix caller that passes lchan_nr != 0"
-#endif
-		cbits = 0x10;
-		break;
-	}
-
-	chan_nr = (cbits << 3) | (ts_nr & 0x7);
-
-	return chan_nr;
-}
-
-uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
-{
-	enum gsm_phys_chan_config pchan = lchan->ts->pchan;
-	if (pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH)
-		return gsm_lchan_as_pchan2chan_nr(lchan,
-						  lchan->ts->dyn.pchan_is);
-	return gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr);
-}
-
-uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
-				   enum gsm_phys_chan_config as_pchan)
-{
-	if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
-	    && as_pchan == GSM_PCHAN_PDCH)
-		return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK);
-	return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);
-}
-
-/* return the gsm_lchan for the CBCH (if it exists at all) */
-struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
-{
-	struct gsm_lchan *lchan = NULL;
-	struct gsm_bts_trx *trx = bts->c0;
-
-	if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
-		lchan = &trx->ts[0].lchan[2];
-	else {
-		int i;
-		for (i = 0; i < 8; i++) {
-			if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
-				lchan = &trx->ts[i].lchan[2];
-				break;
-			}
-		}
-	}
-
-	return lchan;
-}
-
-/* determine logical channel based on TRX and channel number IE */
-struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
-				   int *rc)
-{
-	uint8_t ts_nr = chan_nr & 0x07;
-	uint8_t cbits = chan_nr >> 3;
-	uint8_t lch_idx;
-	struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
-	bool ok = true;
-
-	if (rc)
-		*rc = -EINVAL;
-
-	if (cbits == 0x01) {
-		lch_idx = 0;	/* TCH/F */	
-		if (ts->pchan != GSM_PCHAN_TCH_F &&
-		    ts->pchan != GSM_PCHAN_PDCH &&
-		    ts->pchan != GSM_PCHAN_TCH_F_PDCH
-		    && !(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
-			 && (ts->dyn.pchan_is == GSM_PCHAN_TCH_F
-			     || ts->dyn.pchan_want == GSM_PCHAN_TCH_F)))
-			ok = false;
-	} else if ((cbits & 0x1e) == 0x02) {
-		lch_idx = cbits & 0x1;	/* TCH/H */
-		if (ts->pchan != GSM_PCHAN_TCH_H
-		    && !(ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
-			 && (ts->dyn.pchan_is == GSM_PCHAN_TCH_H
-			     || ts->dyn.pchan_want == GSM_PCHAN_TCH_H)))
-			ok = false;
-	} else if ((cbits & 0x1c) == 0x04) {
-		lch_idx = cbits & 0x3;	/* SDCCH/4 */
-		if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
-		    ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
-			ok = false;
-	} else if ((cbits & 0x18) == 0x08) {
-		lch_idx = cbits & 0x7;	/* SDCCH/8 */
-		if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C &&
-		    ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C_CBCH)
-			ok = false;
-	} else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
-		lch_idx = 0;
-		if (ts->pchan != GSM_PCHAN_CCCH &&
-		    ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
-		    ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
-			ok = false;
-		/* FIXME: we should not return first sdcch4 !!! */
-	} else if ((chan_nr & RSL_CHAN_NR_MASK) == RSL_CHAN_OSMO_PDCH) {
-		lch_idx = 0;
-		if (ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
-			ok = false;
-	} else
-		return NULL;
-
-	if (rc && ok)
-		*rc = 0;
-
-	return &ts->lchan[lch_idx];
-}
-
-static const uint8_t subslots_per_pchan[] = {
-	[GSM_PCHAN_NONE] = 0,
-	[GSM_PCHAN_CCCH] = 0,
-	[GSM_PCHAN_PDCH] = 0,
-	[GSM_PCHAN_CCCH_SDCCH4] = 4,
-	[GSM_PCHAN_TCH_F] = 1,
-	[GSM_PCHAN_TCH_H] = 2,
-	[GSM_PCHAN_SDCCH8_SACCH8C] = 8,
-	[GSM_PCHAN_CCCH_SDCCH4_CBCH] = 4,
-	[GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 8,
-	/*
-	 * GSM_PCHAN_TCH_F_PDCH and GSM_PCHAN_TCH_F_TCH_H_PDCH should not be
-	 * part of this, those TS are handled according to their dynamic state.
-	 */
-};
-
-/*! Return the actual pchan type, also heeding dynamic TS. */
-enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts)
-{
-	switch (ts->pchan) {
-	case GSM_PCHAN_TCH_F_TCH_H_PDCH:
-		return ts->dyn.pchan_is;
-	case GSM_PCHAN_TCH_F_PDCH:
-		if (ts->flags & TS_F_PDCH_ACTIVE)
-			return GSM_PCHAN_PDCH;
-		else
-			return GSM_PCHAN_TCH_F;
-	default:
-		return ts->pchan;
-	}
-}
-
-/*! According to ts->pchan and possibly ts->dyn_pchan, return the number of
- * logical channels available in the timeslot. */
-uint8_t ts_subslots(struct gsm_bts_trx_ts *ts)
-{
-	return subslots_per_pchan[ts_pchan(ts)];
-}
-
-static bool pchan_is_tch(enum gsm_phys_chan_config pchan)
-{
-	switch (pchan) {
-	case GSM_PCHAN_TCH_F:
-	case GSM_PCHAN_TCH_H:
-		return true;
-	default:
-		return false;
-	}
-}
-
-bool ts_is_tch(struct gsm_bts_trx_ts *ts)
-{
-	return pchan_is_tch(ts_pchan(ts));
-}
diff --git a/src/libcommon/gsm_subscriber_base.c b/src/libcommon/gsm_subscriber_base.c
deleted file mode 100644
index 2a8a59f..0000000
--- a/src/libcommon/gsm_subscriber_base.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* The concept of a subscriber as seen by the BSC */
-
-/* (C) 2008 by Harald Welte <laforge at gnumonks.org>
- * (C) 2009-2010 by Holger Hans Peter Freyther <zecke at selfish.org>
- * (C) 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 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/sgsn/gsm_subscriber.h>
-#include <osmocom/sgsn/debug.h>
-#include <osmocom/sgsn/vlr.h>
-
-LLIST_HEAD(active_subscribers);
-void *tall_subscr_ctx;
-
-/* return static buffer with printable name of VLR subscriber */
-const char *vlr_subscr_name(struct vlr_subscr *vsub)
-{
-	static char buf[32];
-	if (!vsub)
-		return "unknown";
-	if (vsub->msisdn[0])
-		snprintf(buf, sizeof(buf), "MSISDN:%s", vsub->msisdn);
-	else if (vsub->imsi[0])
-		snprintf(buf, sizeof(buf), "IMSI:%s", vsub->imsi);
-	else if (vsub->tmsi != GSM_RESERVED_TMSI)
-		snprintf(buf, sizeof(buf), "TMSI:0x%08x", vsub->tmsi);
-	else if (vsub->tmsi_new != GSM_RESERVED_TMSI)
-		snprintf(buf, sizeof(buf), "TMSI(new):0x%08x", vsub->tmsi_new);
-	else
-		return "unknown";
-	buf[sizeof(buf)-1] = '\0';
-	return buf;
-}
-
-const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub)
-{
-	if (!vsub || !vsub->msisdn[0])
-		return vlr_subscr_name(vsub);
-	return vsub->msisdn;
-}
diff --git a/src/libcommon/gsup_client.c b/src/libcommon/gsup_client.c
deleted file mode 100644
index 0520045..0000000
--- a/src/libcommon/gsup_client.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/* Generic Subscriber Update Protocol client */
-
-/* (C) 2014-2016 by Sysmocom s.f.m.c. GmbH
- * All Rights Reserved
- *
- * Author: Jacob Erlbeck
- * Author: Neels Hofmeyr
- *
- * 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 <osmocom/sgsn/gsup_client.h>
-
-#include <osmocom/abis/ipa.h>
-#include <osmocom/gsm/protocol/ipaccess.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/logging.h>
-
-#include <osmocom/sgsn/debug.h>
-
-#include <errno.h>
-#include <string.h>
-
-extern void *tall_bsc_ctx;
-
-static void start_test_procedure(struct gsup_client *gsupc);
-
-static void gsup_client_send_ping(struct gsup_client *gsupc)
-{
-	struct msgb *msg = gsup_client_msgb_alloc();
-
-	msg->l2h = msgb_put(msg, 1);
-	msg->l2h[0] = IPAC_MSGT_PING;
-	ipa_msg_push_header(msg, IPAC_PROTO_IPACCESS);
-	ipa_client_conn_send(gsupc->link, msg);
-}
-
-static int gsup_client_connect(struct gsup_client *gsupc)
-{
-	int rc;
-
-	if (gsupc->is_connected)
-		return 0;
-
-	if (osmo_timer_pending(&gsupc->connect_timer)) {
-		LOGP(DLGSUP, LOGL_DEBUG,
-		     "GSUP connect: connect timer already running\n");
-		osmo_timer_del(&gsupc->connect_timer);
-	}
-
-	if (osmo_timer_pending(&gsupc->ping_timer)) {
-		LOGP(DLGSUP, LOGL_DEBUG,
-		     "GSUP connect: ping timer already running\n");
-		osmo_timer_del(&gsupc->ping_timer);
-	}
-
-	if (ipa_client_conn_clear_queue(gsupc->link) > 0)
-		LOGP(DLGSUP, LOGL_DEBUG, "GSUP connect: discarded stored messages\n");
-
-	rc = ipa_client_conn_open(gsupc->link);
-
-	if (rc >= 0) {
-		LOGP(DLGSUP, LOGL_NOTICE, "GSUP connecting to %s:%d\n",
-		     gsupc->link->addr, gsupc->link->port);
-		return 0;
-	}
-
-	LOGP(DLGSUP, LOGL_ERROR, "GSUP failed to connect to %s:%d: %s\n",
-	     gsupc->link->addr, gsupc->link->port, strerror(-rc));
-
-	if (rc == -EBADF || rc == -ENOTSOCK || rc == -EAFNOSUPPORT ||
-	    rc == -EINVAL)
-		return rc;
-
-	osmo_timer_schedule(&gsupc->connect_timer,
-			    GSUP_CLIENT_RECONNECT_INTERVAL, 0);
-
-	LOGP(DLGSUP, LOGL_INFO, "Scheduled timer to retry GSUP connect to %s:%d\n",
-	     gsupc->link->addr, gsupc->link->port);
-
-	return 0;
-}
-
-static void connect_timer_cb(void *gsupc_)
-{
-	struct gsup_client *gsupc = gsupc_;
-
-	if (gsupc->is_connected)
-		return;
-
-	gsup_client_connect(gsupc);
-}
-
-static void client_send(struct gsup_client *gsupc, int proto_ext,
-			struct msgb *msg_tx)
-{
-	ipa_prepend_header_ext(msg_tx, proto_ext);
-	ipa_msg_push_header(msg_tx, IPAC_PROTO_OSMO);
-	ipa_client_conn_send(gsupc->link, msg_tx);
-	/* msg_tx is now queued and will be freed. */
-}
-
-static void gsup_client_oap_register(struct gsup_client *gsupc)
-{
-	struct msgb *msg_tx;
-	int rc;
-	rc = osmo_oap_client_register(&gsupc->oap_state, &msg_tx);
-
-	if ((rc < 0) || (!msg_tx)) {
-		LOGP(DLGSUP, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n");
-		return;
-	}
-
-	client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
-}
-
-static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
-{
-	struct gsup_client *gsupc = link->data;
-
-	LOGP(DLGSUP, LOGL_INFO, "GSUP link to %s:%d %s\n",
-		     link->addr, link->port, up ? "UP" : "DOWN");
-
-	gsupc->is_connected = up;
-
-	if (up) {
-		start_test_procedure(gsupc);
-
-		if (gsupc->osmo_oap_state.state == OSMO_OAP_INITIALIZED)
-			gsup_client_oap_register(gsupc);
-
-		osmo_timer_del(&gsupc->connect_timer);
-	} else {
-		osmo_timer_del(&gsupc->ping_timer);
-
-		osmo_timer_schedule(&gsupc->connect_timer,
-				    GSUP_CLIENT_RECONNECT_INTERVAL, 0);
-	}
-}
-
-static int gsup_client_oap_handle(struct gsup_client *gsupc, struct msgb *msg_rx)
-{
-	int rc;
-	struct msgb *msg_tx;
-
-	/* If the oap_state is disabled, this will reject the messages. */
-	rc = osmo_oap_client_handle(&gsupc->oap_state, msg_rx, &msg_tx);
-	msgb_free(msg_rx);
-	if (rc < 0)
-		return rc;
-
-	if (msg_tx)
-		client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
-
-	return 0;
-}
-
-static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
-{
-	struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
-	struct ipaccess_head_ext *he = (struct ipaccess_head_ext *) msgb_l2(msg);
-	struct gsup_client *gsupc = (struct gsup_client *)link->data;
-	int rc;
-	struct ipaccess_unit ipa_dev = {
-		/* see gsup_client_create() on const vs non-const */
-		.unit_name = (char*)gsupc->unit_name,
-	};
-
-	OSMO_ASSERT(ipa_dev.unit_name);
-
-	msg->l2h = &hh->data[0];
-
-	rc = ipaccess_bts_handle_ccm(link, &ipa_dev, msg);
-
-	if (rc < 0) {
-		LOGP(DLGSUP, LOGL_NOTICE,
-		     "GSUP received an invalid IPA/CCM message from %s:%d\n",
-		     link->addr, link->port);
-		/* Link has been closed */
-		gsupc->is_connected = 0;
-		msgb_free(msg);
-		return -1;
-	}
-
-	if (rc == 1) {
-		uint8_t msg_type = *(msg->l2h);
-		/* CCM message */
-		if (msg_type == IPAC_MSGT_PONG) {
-			LOGP(DLGSUP, LOGL_DEBUG, "GSUP receiving PONG\n");
-			gsupc->got_ipa_pong = 1;
-		}
-
-		msgb_free(msg);
-		return 0;
-	}
-
-	if (hh->proto != IPAC_PROTO_OSMO)
-		goto invalid;
-
-	if (!he || msgb_l2len(msg) < sizeof(*he))
-		goto invalid;
-
-	msg->l2h = &he->data[0];
-
-	if (he->proto == IPAC_PROTO_EXT_GSUP) {
-		OSMO_ASSERT(gsupc->read_cb != NULL);
-		gsupc->read_cb(gsupc, msg);
-		/* expecting read_cb() to free msg */
-	} else if (he->proto == IPAC_PROTO_EXT_OAP) {
-		return gsup_client_oap_handle(gsupc, msg);
-		/* gsup_client_oap_handle frees msg */
-	} else
-		goto invalid;
-
-	return 0;
-
-invalid:
-	LOGP(DLGSUP, LOGL_NOTICE,
-	     "GSUP received an invalid IPA message from %s:%d, size = %d\n",
-	     link->addr, link->port, msgb_length(msg));
-
-	msgb_free(msg);
-	return -1;
-}
-
-static void ping_timer_cb(void *gsupc_)
-{
-	struct gsup_client *gsupc = gsupc_;
-
-	LOGP(DLGSUP, LOGL_INFO, "GSUP ping callback (%s, %s PONG)\n",
-	     gsupc->is_connected ? "connected" : "not connected",
-	     gsupc->got_ipa_pong ? "got" : "didn't get");
-
-	if (gsupc->got_ipa_pong) {
-		start_test_procedure(gsupc);
-		return;
-	}
-
-	LOGP(DLGSUP, LOGL_NOTICE, "GSUP ping timed out, reconnecting\n");
-	ipa_client_conn_close(gsupc->link);
-	gsupc->is_connected = 0;
-
-	gsup_client_connect(gsupc);
-}
-
-static void start_test_procedure(struct gsup_client *gsupc)
-{
-	osmo_timer_setup(&gsupc->ping_timer, ping_timer_cb, gsupc);
-
-	gsupc->got_ipa_pong = 0;
-	osmo_timer_schedule(&gsupc->ping_timer, GSUP_CLIENT_PING_INTERVAL, 0);
-	LOGP(DLGSUP, LOGL_DEBUG, "GSUP sending PING\n");
-	gsup_client_send_ping(gsupc);
-}
-
-struct gsup_client *gsup_client_create(const char *unit_name,
-				       const char *ip_addr,
-				       unsigned int tcp_port,
-				       gsup_client_read_cb_t read_cb,
-				       struct osmo_oap_client_config *oapc_config)
-{
-	struct gsup_client *gsupc;
-	int rc;
-
-	gsupc = talloc_zero(tall_bsc_ctx, struct gsup_client);
-	OSMO_ASSERT(gsupc);
-
-	/* struct ipaccess_unit has a non-const unit_name, so let's copy to be
-	 * able to have a non-const unit_name here as well. To not taint the
-	 * public gsup_client API, let's store it in a const char* anyway. */
-	gsupc->unit_name = talloc_strdup(gsupc, unit_name);
-	OSMO_ASSERT(gsupc->unit_name);
-
-	/* a NULL oapc_config will mark oap_state disabled. */
-	rc = osmo_oap_client_init(oapc_config, &gsupc->oap_state);
-	if (rc != 0)
-		goto failed;
-
-	gsupc->link = ipa_client_conn_create(gsupc,
-					     /* no e1inp */ NULL,
-					     0,
-					     ip_addr, tcp_port,
-					     gsup_client_updown_cb,
-					     gsup_client_read_cb,
-					     /* default write_cb */ NULL,
-					     gsupc);
-	if (!gsupc->link)
-		goto failed;
-
-	osmo_timer_setup(&gsupc->connect_timer, connect_timer_cb, gsupc);
-
-	rc = gsup_client_connect(gsupc);
-
-	if (rc < 0)
-		goto failed;
-
-	gsupc->read_cb = read_cb;
-
-	return gsupc;
-
-failed:
-	gsup_client_destroy(gsupc);
-	return NULL;
-}
-
-void gsup_client_destroy(struct gsup_client *gsupc)
-{
-	osmo_timer_del(&gsupc->connect_timer);
-	osmo_timer_del(&gsupc->ping_timer);
-
-	if (gsupc->link) {
-		ipa_client_conn_close(gsupc->link);
-		ipa_client_conn_destroy(gsupc->link);
-		gsupc->link = NULL;
-	}
-	talloc_free(gsupc);
-}
-
-int gsup_client_send(struct gsup_client *gsupc, struct msgb *msg)
-{
-	if (!gsupc || !gsupc->is_connected) {
-		LOGP(DGPRS, LOGL_ERROR, "GSUP not connected, unable to send %s\n", msgb_hexdump(msg));
-		msgb_free(msg);
-		return -ENOTCONN;
-	}
-
-	client_send(gsupc, IPAC_PROTO_EXT_GSUP, msg);
-
-	return 0;
-}
-
-struct msgb *gsup_client_msgb_alloc(void)
-{
-	return msgb_alloc_headroom(4000, 64, __func__);
-}
diff --git a/src/libcommon/gsup_test_client.c b/src/libcommon/gsup_test_client.c
deleted file mode 100644
index 2357ba5..0000000
--- a/src/libcommon/gsup_test_client.c
+++ /dev/null
@@ -1,299 +0,0 @@
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/application.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/gsup.h>
-
-#include <osmocom/sgsn/gsup_client.h>
-#include <osmocom/sgsn/debug.h>
-
-static struct gsup_client *g_gc;
-
-
-/***********************************************************************
- * IMSI Operation
- ***********************************************************************/
-static LLIST_HEAD(g_imsi_ops);
-
-struct imsi_op_stats {
-	uint32_t num_alloc;
-	uint32_t num_released;
-	uint32_t num_rx_success;
-	uint32_t num_rx_error;
-	uint32_t num_timeout;
-};
-
-enum imsi_op_type {
-	IMSI_OP_SAI,
-	IMSI_OP_LU,
-	IMSI_OP_ISD,
-	_NUM_IMSI_OP
-};
-
-static const struct value_string imsi_op_names[] = {
-	{ IMSI_OP_SAI, "SAI" },
-	{ IMSI_OP_LU, "LU" },
-	{ IMSI_OP_ISD, "ISD" },
-	{ 0, NULL }
-};
-
-static struct imsi_op_stats imsi_op_stats[_NUM_IMSI_OP];
-
-struct imsi_op {
-	struct llist_head list;
-	char imsi[17];
-	enum imsi_op_type type;
-	struct osmo_timer_list timer;
-};
-
-static struct imsi_op *imsi_op_find(const char *imsi,
-			     enum imsi_op_type type)
-{
-	struct imsi_op *io;
-
-	llist_for_each_entry(io, &g_imsi_ops, list) {
-		if (!strcmp(io->imsi, imsi) && io->type == type)
-			return io;
-	}
-	return NULL;
-}
-
-static void imsi_op_timer_cb(void *data);
-
-static struct imsi_op *imsi_op_alloc(void *ctx, const char *imsi,
-				enum imsi_op_type type)
-{
-	struct imsi_op *io;
-
-	if (imsi_op_find(imsi, type))
-		return NULL;
-
-	io = talloc_zero(ctx, struct imsi_op);
-	osmo_strlcpy(io->imsi, imsi, sizeof(io->imsi));
-	io->type = type;
-	osmo_timer_setup(&io->timer, imsi_op_timer_cb, io);
-	llist_add(&io->list, &g_imsi_ops);
-	imsi_op_stats[type].num_alloc++;
-
-	return io;
-}
-
-static void imsi_op_release(struct imsi_op *io)
-{
-	osmo_timer_del(&io->timer);
-	llist_del(&io->list);
-	imsi_op_stats[io->type].num_released++;
-	talloc_free(io);
-}
-
-static void imsi_op_timer_cb(void *data)
-{
-	struct imsi_op *io = data;
-	printf("%s: Timer expiration\n", io->imsi);
-	imsi_op_stats[io->type].num_timeout++;
-	imsi_op_release(io);
-}
-
-/* allocate + generate + send Send-Auth-Info */
-int req_auth_info(const char *imsi)
-{
-	struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_SAI);
-	struct osmo_gsup_message gsup = {0};
-	struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);
-
-	osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
-	gsup.message_type = OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST;
-
-	osmo_gsup_encode(msg, &gsup);
-
-	return gsup_client_send(g_gc, msg);
-}
-
-/* allocate + generate + send Send-Auth-Info */
-int req_loc_upd(const char *imsi)
-{
-	struct imsi_op *io = imsi_op_alloc(g_gc, imsi, IMSI_OP_LU);
-	struct osmo_gsup_message gsup = {0};
-	struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);
-
-	osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
-	gsup.message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST;
-
-	osmo_gsup_encode(msg, &gsup);
-
-	return gsup_client_send(g_gc, msg);
-}
-
-int resp_isd(struct imsi_op *io)
-{
-	struct osmo_gsup_message gsup = {0};
-	struct msgb *msg = msgb_alloc_headroom(1200, 200, __func__);
-
-	osmo_strlcpy(gsup.imsi, io->imsi, sizeof(gsup.imsi));
-	gsup.message_type = OSMO_GSUP_MSGT_INSERT_DATA_RESULT;
-
-	osmo_gsup_encode(msg, &gsup);
-
-	imsi_op_release(io);
-
-	return gsup_client_send(g_gc, msg);
-}
-
-/* receive an incoming GSUP message */
-static void imsi_op_rx_gsup(struct imsi_op *io, const struct osmo_gsup_message *gsup)
-{
-	int is_error = 0;
-
-	if (OSMO_GSUP_IS_MSGT_ERROR(gsup->message_type)) {
-		imsi_op_stats[io->type].num_rx_error++;
-		is_error = 1;
-	} else
-		imsi_op_stats[io->type].num_rx_success++;
-
-	switch (io->type) {
-	case IMSI_OP_SAI:
-		printf("%s; SAI Response%s\n", io->imsi, is_error ? ": ERROR" : "");
-		/* now that we have auth tuples, request LU */
-		req_loc_upd(io->imsi);
-		imsi_op_release(io);
-		break;
-	case IMSI_OP_LU:
-		printf("%s; LU Response%s\n", io->imsi, is_error ? ": ERROR" : "");
-		imsi_op_release(io);
-		break;
-	case IMSI_OP_ISD:
-		printf("%s; ISD Request%s\n", io->imsi, is_error ? ": ERROR" : "");
-		resp_isd(io);
-		break;
-	default:
-		printf("%s: Unknown\n", io->imsi);
-		imsi_op_release(io);
-		break;
-	}
-}
-
-static int op_type_by_gsup_msgt(enum osmo_gsup_message_type msg_type)
-{
-	switch (msg_type) {
-	case OSMO_GSUP_MSGT_SEND_AUTH_INFO_RESULT:
-	case OSMO_GSUP_MSGT_SEND_AUTH_INFO_ERROR:
-		return IMSI_OP_SAI;
-	case OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT:
-	case OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR:
-		return IMSI_OP_LU;
-	case OSMO_GSUP_MSGT_INSERT_DATA_REQUEST:
-		return IMSI_OP_ISD;
-	default:
-		printf("Unknown GSUP msg_type %u\n", msg_type);
-		return -1;
-	}
-}
-
-static int gsupc_read_cb(struct gsup_client *gsupc, struct msgb *msg)
-{
-	struct osmo_gsup_message gsup_msg = {0};
-	struct imsi_op *io;
-	int rc;
-
-	DEBUGP(DGPRS, "Rx GSUP %s\n", osmo_hexdump(msgb_l2(msg), msgb_l2len(msg)));
-
-	rc = osmo_gsup_decode(msgb_l2(msg), msgb_l2len(msg), &gsup_msg);
-	if (rc < 0)
-		return rc;
-
-	if (!gsup_msg.imsi[0])
-		return -1;
-
-	rc = op_type_by_gsup_msgt(gsup_msg.message_type);
-	if (rc < 0)
-		return rc;
-
-	switch (rc) {
-	case IMSI_OP_SAI:
-	case IMSI_OP_LU:
-		io = imsi_op_find(gsup_msg.imsi, rc);
-		if (!io)
-			return -1;
-		break;
-	case IMSI_OP_ISD:
-		/* ISD is an inbound transaction */
-		io = imsi_op_alloc(g_gc, gsup_msg.imsi, IMSI_OP_ISD);
-		break;
-	}
-
-	imsi_op_rx_gsup(io, &gsup_msg);
-	msgb_free(msg);
-
-	return 0;
-}
-
-static void print_report(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(imsi_op_stats); i++) {
-		struct imsi_op_stats *st = &imsi_op_stats[i];
-		const char *name = get_value_string(imsi_op_names, i);
-		printf("%s: %u alloc, %u released, %u success, %u error , %u tout\n",
-			name, st->num_alloc, st->num_released, st->num_rx_success,
-			st->num_rx_error, st->num_timeout);
-	}
-}
-
-static void sig_cb(int sig)
-{
-	switch (sig) {
-	case SIGINT:
-		print_report();
-		exit(0);
-		break;
-	}
-}
-
-void *tall_bsc_ctx = NULL;
-
-/* default categories */
-static struct log_info_cat default_categories[] = {
-};
-
-static const struct log_info gsup_test_client_log_info = {
-	.cat = default_categories,
-	.num_cat = ARRAY_SIZE(default_categories),
-};
-
-int main(int argc, char **argv)
-{
-	unsigned long long i;
-	char *server_host = "127.0.0.1";
-	uint16_t server_port = OSMO_GSUP_PORT;
-	void *ctx = talloc_named_const(NULL, 0, "gsup_test_client");
-
-	osmo_init_logging2(ctx, &gsup_test_client_log_info);
-
-	g_gc = gsup_client_create(ctx, "GSUPTEST", server_host, server_port,
-				  gsupc_read_cb, NULL);
-
-
-	signal(SIGINT, sig_cb);
-
-	for (i = 0; i < 10000; i++) {
-		unsigned long long imsi = 901790000000000 + i;
-		char imsi_buf[17];
-		snprintf(imsi_buf, sizeof(imsi_buf), "%015llu", imsi);
-		req_auth_info(imsi_buf);
-		osmo_select_main(0);
-	}
-
-	while (1) {
-		osmo_select_main(0);
-	}
-
-	print_report();
-	exit(0);
-}
diff --git a/src/libcommon/socket.c b/src/libcommon/socket.c
deleted file mode 100644
index dfcb393..0000000
--- a/src/libcommon/socket.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/* OpenBSC sokcet code, taken from Abis input driver for ip.access */
-
-/* (C) 2009 by Harald Welte <laforge at gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther
- * (C) 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 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 <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <time.h>
-#include <sys/fcntl.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/select.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/sgsn/debug.h>
-#include <osmocom/sgsn/gsm_data.h>
-#include <osmocom/core/talloc.h>
-
-int make_sock(struct osmo_fd *bfd, int proto,
-	      uint32_t ip, uint16_t port, int priv_nr,
-	      int (*cb)(struct osmo_fd *fd, unsigned int what), void *data)
-{
-	struct sockaddr_in addr;
-	int ret, on = 1;
-	int type = SOCK_STREAM;
-
-	switch (proto) {
-	case IPPROTO_TCP:
-		type = SOCK_STREAM;
-		break;
-	case IPPROTO_UDP:
-		type = SOCK_DGRAM;
-		break;
-#ifdef IPPROTO_GRE
-	case IPPROTO_GRE:
-		type = SOCK_RAW;
-		break;
-#endif
-	default:
-		return -EINVAL;
-	}
-
-	bfd->fd = socket(AF_INET, type, proto);
-	bfd->cb = cb;
-	bfd->when = BSC_FD_READ;
-	bfd->data = data;
-	bfd->priv_nr = priv_nr;
-
-	if (bfd->fd < 0) {
-		LOGP(DLINP, LOGL_ERROR, "could not create socket.\n");
-		return -EIO;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.sin_family = AF_INET;
-	addr.sin_port = htons(port);
-	if (ip != INADDR_ANY)
-		addr.sin_addr.s_addr = htonl(ip);
-	else
-		addr.sin_addr.s_addr = INADDR_ANY;
-
-	setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
-	ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
-	if (ret < 0) {
-		LOGP(DLINP, LOGL_ERROR, "could not bind socket %s\n",
-			strerror(errno));
-		close(bfd->fd);
-		return -EIO;
-	}
-
-	if (proto == IPPROTO_TCP) {
-		ret = listen(bfd->fd, 1);
-		if (ret < 0) {
-			perror("listen");
-			close(bfd->fd);
-			return ret;
-		}
-	}
-
-	ret = osmo_fd_register(bfd);
-	if (ret < 0) {
-		perror("register_listen_fd");
-		close(bfd->fd);
-		return ret;
-	}
-	return 0;
-}
diff --git a/src/libcommon/talloc_ctx.c b/src/libcommon/talloc_ctx.c
deleted file mode 100644
index c8e9cd3..0000000
--- a/src/libcommon/talloc_ctx.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* OpenBSC allocation contexts initialization code */
-/* (C) 2011-2016 by sysmocom s.f.m.c. GmbH <info at sysmocom.de>
- * 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 <osmocom/core/talloc.h>
-#include <osmocom/core/msgb.h>
-
-extern void *tall_bsc_ctx;
-extern void *tall_fle_ctx;
-extern void *tall_locop_ctx;
-extern void *tall_authciphop_ctx;
-extern void *tall_gsms_ctx;
-extern void *tall_subscr_ctx;
-extern void *tall_sub_req_ctx;
-extern void *tall_call_ctx;
-extern void *tall_paging_ctx;
-extern void *tall_sigh_ctx;
-extern void *tall_tqe_ctx;
-extern void *tall_trans_ctx;
-extern void *tall_map_ctx;
-extern void *tall_upq_ctx;
-extern void *tall_ctr_ctx;
-
-void talloc_ctx_init(void *ctx_root)
-{
-	msgb_talloc_ctx_init(ctx_root, 0);
-	tall_fle_ctx = talloc_named_const(ctx_root, 0, "bs11_file_list_entry");
-	tall_locop_ctx = talloc_named_const(ctx_root, 0, "loc_updating_oper");
-	tall_authciphop_ctx = talloc_named_const(ctx_root, 0, "auth_ciph_oper");
-	tall_gsms_ctx = talloc_named_const(ctx_root, 0, "sms");
-	tall_subscr_ctx = talloc_named_const(ctx_root, 0, "subscriber");
-	tall_call_ctx = talloc_named_const(ctx_root, 0, "gsm_call");
-	tall_paging_ctx = talloc_named_const(ctx_root, 0, "paging_request");
-	tall_sigh_ctx = talloc_named_const(ctx_root, 0, "signal_handler");
-	tall_tqe_ctx = talloc_named_const(ctx_root, 0, "subch_txq_entry");
-	tall_trans_ctx = talloc_named_const(ctx_root, 0, "transaction");
-	tall_map_ctx = talloc_named_const(ctx_root, 0, "trau_map_entry");
-	tall_upq_ctx = talloc_named_const(ctx_root, 0, "trau_upq_entry");
-	tall_ctr_ctx = talloc_named_const(ctx_root, 0, "counter");
-}

-- 
To view, visit https://gerrit.osmocom.org/10260
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-sgsn
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I9307f9da7f48dd0a2e1cb213072068736e569722
Gerrit-Change-Number: 10260
Gerrit-PatchSet: 1
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180730/760d79ae/attachment.htm>


More information about the gerrit-log mailing list