New upstream version 0.9.14
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index 95b9ef4..9a7619b 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -1,6 +1,6 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
-AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS)
-AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS)
+AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS)
+AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS)
 
 bin_PROGRAMS = osmo-bsc
 
diff --git a/src/osmo-bsc/Makefile.in b/src/osmo-bsc/Makefile.in
index d83952c..b173f15 100644
--- a/src/osmo-bsc/Makefile.in
+++ b/src/osmo-bsc/Makefile.in
@@ -36,7 +36,7 @@
 subdir = src/osmo-bsc
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
@@ -117,6 +117,8 @@
 LIBOBJS = @LIBOBJS@
 LIBOSMOCORE_CFLAGS = @LIBOSMOCORE_CFLAGS@
 LIBOSMOCORE_LIBS = @LIBOSMOCORE_LIBS@
+LIBOSMOGSM_CFLAGS = @LIBOSMOGSM_CFLAGS@
+LIBOSMOGSM_LIBS = @LIBOSMOGSM_LIBS@
 LIBOSMOSCCP_CFLAGS = @LIBOSMOSCCP_CFLAGS@
 LIBOSMOSCCP_LIBS = @LIBOSMOSCCP_LIBS@
 LIBOSMOVTY_CFLAGS = @LIBOSMOVTY_CFLAGS@
@@ -186,8 +188,8 @@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
-AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS)
-AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS)
+AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(COVERAGE_CFLAGS)
+AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(COVERAGE_LDFLAGS)
 osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_rf.c osmo_bsc_vty.c osmo_bsc_api.c \
 		   osmo_bsc_grace.c osmo_bsc_msc.c osmo_bsc_sccp.c \
 		   osmo_bsc_filter.c osmo_bsc_bssap.c osmo_bsc_audio.c
diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c
index b8cbcf2..a943a0c 100644
--- a/src/osmo-bsc/osmo_bsc_api.c
+++ b/src/osmo-bsc/osmo_bsc_api.c
@@ -21,8 +21,8 @@
 #include <openbsc/osmo_msc_data.h>
 #include <openbsc/debug.h>
 
-#include <osmocore/protocol/gsm_08_08.h>
-#include <osmocore/gsm0808.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/gsm/gsm0808.h>
 
 #define return_when_not_connected(conn) \
 	if (!conn->sccp_con) {\
diff --git a/src/osmo-bsc/osmo_bsc_audio.c b/src/osmo-bsc/osmo_bsc_audio.c
index 515cfa7..64260aa 100644
--- a/src/osmo-bsc/osmo_bsc_audio.c
+++ b/src/osmo-bsc/osmo_bsc_audio.c
@@ -65,6 +65,6 @@
 int osmo_bsc_audio_init(struct gsm_network *net)
 {
 	net->hardcoded_rtp_payload = 98;
-	register_signal_handler(SS_ABISIP, handle_abisip_signal, net);
+	osmo_signal_register_handler(SS_ABISIP, handle_abisip_signal, net);
 	return 0;
 }
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index f871131..a3ba2ad 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -26,8 +26,8 @@
 #include <openbsc/mgcp.h>
 #include <openbsc/paging.h>
 
-#include <osmocore/gsm0808.h>
-#include <osmocore/protocol/gsm_08_08.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
+#include <osmocom/gsm/gsm0808.h>
 
 #include <arpa/inet.h>
 
@@ -158,7 +158,7 @@
 	if (data_length == 3 && data[0] == CELL_IDENT_LAC) {
 		lac = ntohs(read_data16(&data[1]));
 	} else if (data_length > 1 || (data[0] & 0x0f) != CELL_IDENT_BSS) {
-		LOGP(DMSC, LOGL_ERROR, "Unsupported Cell Identifier List: %s\n", hexdump(data, data_length));
+		LOGP(DMSC, LOGL_ERROR, "Unsupported Cell Identifier List: %s\n", osmo_hexdump(data, data_length));
 		return -1;
 	}
 
@@ -467,13 +467,13 @@
 	header = (struct dtap_header *) msg->l3h;
 	if (sizeof(*header) >= length) {
 		LOGP(DMSC, LOGL_ERROR, "The DTAP header does not fit. Wanted: %u got: %u\n", sizeof(*header), length);
-                LOGP(DMSC, LOGL_ERROR, "hex: %s\n", hexdump(msg->l3h, length));
+                LOGP(DMSC, LOGL_ERROR, "hex: %s\n", osmo_hexdump(msg->l3h, length));
                 return -1;
 	}
 
 	if (header->length > length - sizeof(*header)) {
 		LOGP(DMSC, LOGL_ERROR, "The DTAP l4 information does not fit: header: %u length: %u\n", header->length, length);
-                LOGP(DMSC, LOGL_ERROR, "hex: %s\n", hexdump(msg->l3h, length));
+                LOGP(DMSC, LOGL_ERROR, "hex: %s\n", osmo_hexdump(msg->l3h, length));
 		return -1;
 	}
 
@@ -502,7 +502,7 @@
 	struct bssmap_header *bs;
 
 	LOGP(DMSC, LOGL_DEBUG, "Incoming SCCP message ftom MSC: %s\n",
-		hexdump(msgb->l3h, length));
+		osmo_hexdump(msgb->l3h, length));
 
 	if (length < sizeof(*bs)) {
 		LOGP(DMSC, LOGL_ERROR, "The header is too short.\n");
diff --git a/src/osmo-bsc/osmo_bsc_grace.c b/src/osmo-bsc/osmo_bsc_grace.c
index f699cf3..c67984b 100644
--- a/src/osmo-bsc/osmo_bsc_grace.c
+++ b/src/osmo-bsc/osmo_bsc_grace.c
@@ -103,5 +103,5 @@
 
 static __attribute__((constructor)) void on_dso_load_grace(void)
 {
-	register_signal_handler(SS_RF, handle_rf_signal, NULL);
+	osmo_signal_register_handler(SS_RF, handle_rf_signal, NULL);
 }
diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c
index b5f64ab..42c74cc 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -1,6 +1,6 @@
 /* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2010 by On-Waves
+ * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2011 by On-Waves
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -26,8 +26,9 @@
 #include <openbsc/signal.h>
 #include <openbsc/vty.h>
 
-#include <osmocore/talloc.h>
-#include <osmocore/process.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/process.h>
 
 #include <osmocom/sccp/sccp.h>
 
@@ -43,18 +44,15 @@
 
 #include "../../bscconfig.h"
 
-static struct log_target *stderr_target;
 struct gsm_network *bsc_gsmnet = 0;
 static const char *config_file = "openbsc.cfg";
 static const char *rf_ctl = NULL;
 extern const char *openbsc_copyright;
 static int daemonize = 0;
 
-extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, struct msgb *), const char *cfg_file);
-
 static void print_usage()
 {
-	printf("Usage: bsc_msc_ip\n");
+	printf("Usage: osmo-bsc\n");
 }
 
 static void print_help()
@@ -101,10 +99,10 @@
 			print_help();
 			exit(0);
 		case 's':
-			log_set_use_color(stderr_target, 0);
+			log_set_use_color(osmo_stderr_target, 0);
 			break;
 		case 'd':
-			log_parse_category_mask(stderr_target, optarg);
+			log_parse_category_mask(osmo_stderr_target, optarg);
 			break;
 		case 'D':
 			daemonize = 1;
@@ -113,13 +111,10 @@
 			config_file = strdup(optarg);
 			break;
 		case 'T':
-			log_set_print_timestamp(stderr_target, 1);
-			break;
-		case 'P':
-			ipacc_rtp_direct = 0;
+			log_set_print_timestamp(osmo_stderr_target, 1);
 			break;
 		case 'e':
-			log_set_log_level(stderr_target, atoi(optarg));
+			log_set_log_level(osmo_stderr_target, atoi(optarg));
 			break;
 		case 'r':
 			rf_ctl = optarg;
@@ -131,10 +126,6 @@
 	}
 }
 
-extern int bts_model_unknown_init(void);
-extern int bts_model_bs11_init(void);
-extern int bts_model_nanobts_init(void);
-
 extern enum node_type bsc_vty_go_parent(struct vty *vty);
 
 static struct vty_app_info vty_info = {
@@ -152,7 +143,7 @@
 	switch (signal) {
 	case SIGINT:
 		bsc_shutdown_net(bsc_gsmnet);
-		dispatch_signal(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
+		osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
 		sleep(3);
 		exit(0);
 		break;
@@ -179,24 +170,22 @@
 
 int main(int argc, char **argv)
 {
+	struct osmo_msc_data *data;
 	int rc;
 
-	log_init(&log_info);
 	tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
-	stderr_target = log_target_create_stderr();
-	log_add_target(stderr_target);
 
-	bts_model_unknown_init();
-	bts_model_bs11_init();
-	bts_model_nanobts_init();
+	osmo_init_logging(&log_info);
+
+	bts_init();
+	e1inp_init();
 
 	/* enable filters */
-	log_set_all_filter(stderr_target, 1);
 
 	/* This needs to precede handle_options() */
 	vty_info.copyright = openbsc_copyright;
 	vty_init(&vty_info);
-	bsc_vty_init();
+	bsc_vty_init(&log_info);
 
 	/* parse options */
 	handle_options(argc, argv);
@@ -215,9 +204,13 @@
 	}
 	bsc_api_init(bsc_gsmnet, osmo_bsc_api());
 
-	if (rf_ctl) {
-		struct osmo_msc_data *data = bsc_gsmnet->msc_data;
-		data->rf_ctl = osmo_bsc_rf_create(rf_ctl, bsc_gsmnet);
+	data = bsc_gsmnet->msc_data;
+	if (rf_ctl)
+		bsc_replace_string(data, &data->rf_ctrl_name, rf_ctl);
+
+	if (data->rf_ctrl_name) {
+		data->rf_ctl = osmo_bsc_rf_create(data->rf_ctrl_name,
+						  bsc_gsmnet);
 		if (!data->rf_ctl) {
 			fprintf(stderr, "Failed to create the RF service.\n");
 			exit(1);
@@ -243,7 +236,7 @@
 	signal(SIGABRT, &signal_handler);
 	signal(SIGUSR1, &signal_handler);
 	signal(SIGUSR2, &signal_handler);
-	signal(SIGPIPE, SIG_IGN);
+	osmo_init_ignore_signals();
 
 	if (daemonize) {
 		rc = osmo_daemonize();
@@ -254,7 +247,7 @@
 	}
 
 	while (1) {
-		bsc_select_main(0);
+		osmo_select_main(0);
 	}
 
 	return 0;
diff --git a/src/osmo-bsc/osmo_bsc_msc.c b/src/osmo-bsc/osmo_bsc_msc.c
index 2e8cf05..2a32227 100644
--- a/src/osmo-bsc/osmo_bsc_msc.c
+++ b/src/osmo-bsc/osmo_bsc_msc.c
@@ -1,8 +1,8 @@
 /*
  * Handle the connection to the MSC. This include ping/timeout/reconnect
  * (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2010 by On-Waves
+ * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2011 by On-Waves
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -27,7 +27,7 @@
 #include <openbsc/osmo_msc_data.h>
 #include <openbsc/signal.h>
 
-#include <osmocore/gsm0808.h>
+#include <osmocom/gsm/gsm0808.h>
 
 #include <osmocom/sccp/sccp.h>
 
@@ -37,13 +37,14 @@
 
 
 static void initialize_if_needed(struct bsc_msc_connection *conn);
+static void send_lacs(struct gsm_network *net, struct bsc_msc_connection *conn);
 static void send_id_get_response(struct osmo_msc_data *data, int fd);
 static void send_ping(struct osmo_msc_data *data);
 
 /*
  * MGCP forwarding code
  */
-static int mgcp_do_read(struct bsc_fd *fd)
+static int mgcp_do_read(struct osmo_fd *fd)
 {
 	struct osmo_msc_data *data = (struct osmo_msc_data *) fd->data;
 	struct msgb *mgcp;
@@ -71,7 +72,7 @@
 	return 0;
 }
 
-static int mgcp_do_write(struct bsc_fd *fd, struct msgb *msg)
+static int mgcp_do_write(struct osmo_fd *fd, struct msgb *msg)
 {
 	int ret;
 
@@ -101,7 +102,7 @@
 
 	msgb_put(mgcp, msgb_l2len(msg));
 	memcpy(mgcp->data, msg->l2h, mgcp->len);
-	if (write_queue_enqueue(&data->mgcp_agent, mgcp) != 0) {
+	if (osmo_wqueue_enqueue(&data->mgcp_agent, mgcp) != 0) {
 		LOGP(DMGCP, LOGL_FATAL, "Could not queue message to MGCP GW.\n");
 		msgb_free(mgcp);
 	}
@@ -143,13 +144,13 @@
 		return -1;
 	}
 
-	write_queue_init(&data->mgcp_agent, 10);
+	osmo_wqueue_init(&data->mgcp_agent, 10);
 	data->mgcp_agent.bfd.when = BSC_FD_READ;
 	data->mgcp_agent.bfd.data = data;
 	data->mgcp_agent.read_cb = mgcp_do_read;
 	data->mgcp_agent.write_cb = mgcp_do_write;
 
-	if (bsc_register_fd(&data->mgcp_agent.bfd) != 0) {
+	if (osmo_fd_register(&data->mgcp_agent.bfd) != 0) {
 		LOGP(DMGCP, LOGL_FATAL, "Failed to register BFD\n");
 		close(data->mgcp_agent.bfd.fd);
 		data->mgcp_agent.bfd.fd = -1;
@@ -165,7 +166,7 @@
 int msc_queue_write(struct bsc_msc_connection *conn, struct msgb *msg, int proto)
 {
 	ipaccess_prepend_header(msg, proto);
-	if (write_queue_enqueue(&conn->write_queue, msg) != 0) {
+	if (osmo_wqueue_enqueue(&conn->write_queue, msg) != 0) {
 		LOGP(DMSC, LOGL_FATAL, "Failed to queue IPA/%d\n", proto);
 		msgb_free(msg);
 		return -1;
@@ -174,12 +175,12 @@
 	return 0;
 }
 
-static int msc_alink_do_write(struct bsc_fd *fd, struct msgb *msg)
+static int msc_alink_do_write(struct osmo_fd *fd, struct msgb *msg)
 {
 	int ret;
 
 	LOGP(DMSC, LOGL_DEBUG, "Sending SCCP to MSC: %u\n", msgb_l2len(msg));
-	LOGP(DMI, LOGL_DEBUG, "MSC TX %s\n", hexdump(msg->data, msg->len));
+	LOGP(DMI, LOGL_DEBUG, "MSC TX %s\n", osmo_hexdump(msg->data, msg->len));
 
 	ret = write(fd->fd, msg->data, msg->len);
 	if (ret < msg->len)
@@ -188,7 +189,26 @@
 	return ret;
 }
 
-static int ipaccess_a_fd_cb(struct bsc_fd *bfd)
+static void osmo_ext_handle(struct osmo_msc_data *msc, struct msgb *msg)
+{
+	struct ipaccess_head *hh;
+	struct ipaccess_head_ext *hh_ext;
+
+	hh = (struct ipaccess_head *) msg->data;
+	hh_ext = (struct ipaccess_head_ext *) hh->data;
+	if (msg->len < sizeof(*hh) + sizeof(*hh_ext)) {
+		LOGP(DMSC, LOGL_ERROR, "Packet too short for extended header.\n");
+		return;
+	}
+
+	msg->l2h = hh_ext->data;
+	if (hh_ext->proto == IPAC_PROTO_EXT_MGCP)
+		mgcp_forward(msc, msg);
+	else if (hh_ext->proto == IPAC_PROTO_EXT_LAC)
+		send_lacs(msc->network, msc->msc_con);
+}
+
+static int ipaccess_a_fd_cb(struct osmo_fd *bfd)
 {
 	int error;
 	struct msgb *msg = ipaccess_read_msg(bfd, &error);
@@ -206,7 +226,7 @@
 		return -1;
 	}
 
-	LOGP(DMSC, LOGL_DEBUG, "From MSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
+	LOGP(DMSC, LOGL_DEBUG, "From MSC: %s proto: %d\n", osmo_hexdump(msg->data, msg->len), msg->l2h[0]);
 
 	/* handle base message handling */
 	hh = (struct ipaccess_head *) msg->data;
@@ -219,12 +239,14 @@
 		else if (msg->l2h[0] == IPAC_MSGT_ID_GET) {
 			send_id_get_response(data, bfd->fd);
 		} else if (msg->l2h[0] == IPAC_MSGT_PONG) {
-			bsc_del_timer(&data->pong_timer);
+			osmo_timer_del(&data->pong_timer);
 		}
 	} else if (hh->proto == IPAC_PROTO_SCCP) {
 		sccp_system_incoming(msg);
 	} else if (hh->proto == IPAC_PROTO_MGCP_OLD) {
 		mgcp_forward(data, msg);
+	} else if (hh->proto == IPAC_PROTO_OSMO) {
+		osmo_ext_handle(data, msg);
 	}
 
 	msgb_free(msg);
@@ -256,10 +278,10 @@
 	send_ping(data);
 
 	/* send another ping in 20 seconds */
-	bsc_schedule_timer(&data->ping_timer, data->ping_timeout, 0);
+	osmo_timer_schedule(&data->ping_timer, data->ping_timeout, 0);
 
 	/* also start a pong timer */
-	bsc_schedule_timer(&data->pong_timer, data->pong_timeout, 0);
+	osmo_timer_schedule(&data->pong_timer, data->pong_timeout, 0);
 }
 
 static void msc_pong_timeout_cb(void *_data)
@@ -284,7 +306,7 @@
 	msc_ping_timeout_cb(data);
 
 	sig.data = data;
-	dispatch_signal(SS_MSC, S_MSC_CONNECTED, &sig);
+	osmo_signal_dispatch(SS_MSC, S_MSC_CONNECTED, &sig);
 }
 
 /*
@@ -299,16 +321,49 @@
 	LOGP(DMSC, LOGL_ERROR, "Lost MSC connection. Freing stuff.\n");
 
 	data = (struct osmo_msc_data *) msc->write_queue.bfd.data;
-	bsc_del_timer(&data->ping_timer);
-	bsc_del_timer(&data->pong_timer);
+	osmo_timer_del(&data->ping_timer);
+	osmo_timer_del(&data->pong_timer);
 
 	sig.data = data;
-	dispatch_signal(SS_MSC, S_MSC_LOST, &sig);
+	osmo_signal_dispatch(SS_MSC, S_MSC_LOST, &sig);
 
 	msc->is_authenticated = 0;
 	bsc_msc_schedule_connect(msc);
 }
 
+static void send_lacs(struct gsm_network *net, struct bsc_msc_connection *conn)
+{
+	struct ipac_ext_lac_cmd *lac;
+	struct gsm_bts *bts;
+	struct msgb *msg;
+	int lacs = 0;
+
+	if (llist_empty(&net->bts_list)) {
+		LOGP(DMSC, LOGL_ERROR, "No BTSs configured. Not sending LACs.\n");
+		return;
+	}
+
+	msg = msgb_alloc_headroom(4096, 128, "LAC Command");
+	if (!msg) {
+		LOGP(DMSC, LOGL_ERROR, "Failed to create the LAC command.\n");
+		return;
+	}
+
+	lac = (struct ipac_ext_lac_cmd *) msgb_put(msg, sizeof(*lac));
+	lac->add_remove = 1;
+
+	llist_for_each_entry(bts, &net->bts_list, list) {
+		if (lacs++ == 0)
+			lac->lac = htons(bts->location_area_code);
+		else
+			msgb_put_u16(msg, htons(bts->location_area_code));
+	}
+
+	lac->nr_extra_lacs = lacs - 1;
+	ipaccess_prepend_header_ext(msg, IPAC_PROTO_EXT_LAC);
+	msc_queue_write(conn, msg, IPAC_PROTO_OSMO);
+}
+
 static void initialize_if_needed(struct bsc_msc_connection *conn)
 {
 	struct msgb *msg;
@@ -344,9 +399,7 @@
 	if (mgcp_create_port(data) != 0)
 		return -1;
 
-	data->msc_con = bsc_msc_create(data->msc_ip,
-				       data->msc_port,
-				       data->msc_ip_dscp);
+	data->msc_con = bsc_msc_create(data, &data->dests);
 	if (!data->msc_con) {
 		LOGP(DMSC, LOGL_ERROR, "Creating the MSC network connection failed.\n");
 		return -1;
diff --git a/src/osmo-bsc/osmo_bsc_rf.c b/src/osmo-bsc/osmo_bsc_rf.c
index 5652c9d..cd64b52 100644
--- a/src/osmo-bsc/osmo_bsc_rf.c
+++ b/src/osmo-bsc/osmo_bsc_rf.c
@@ -25,9 +25,10 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/signal.h>
 #include <openbsc/osmo_msc_data.h>
+#include <openbsc/ipaccess.h>
 
-#include <osmocore/talloc.h>
-#include <osmocore/protocol/gsm_12_21.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/gsm/protocol/gsm_12_21.h>
 
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -68,7 +69,7 @@
 	msg->l2h = msgb_put(msg, 1);
 	msg->l2h[0] = send;
 
-	if (write_queue_enqueue(&conn->queue, msg) != 0) {
+	if (osmo_wqueue_enqueue(&conn->queue, msg) != 0) {
 		LOGP(DINP, LOGL_ERROR, "Failed to enqueue the answer.\n");
 		msgb_free(msg);
 		return;
@@ -95,8 +96,8 @@
 	llist_for_each_entry(bts, &conn->rf->gsm_network->bts_list, list) {
 		struct gsm_bts_trx *trx;
 		llist_for_each_entry(trx, &bts->trx_list, list) {
-			if (trx->nm_state.availability == NM_AVSTATE_OK &&
-			    trx->nm_state.operational != NM_STATE_LOCKED) {
+			if (trx->mo.nm_state.availability == NM_AVSTATE_OK &&
+			    trx->mo.nm_state.operational != NM_STATE_LOCKED) {
 					send = RF_CMD_ON;
 					break;
 			}
@@ -119,9 +120,9 @@
 			continue;
 
 		llist_for_each_entry(trx, &bts->trx_list, list) {
-			if (trx->nm_state.availability != NM_AVSTATE_OK ||
-			    trx->nm_state.operational != NM_OPSTATE_ENABLED ||
-			    trx->nm_state.administrative != NM_STATE_UNLOCKED) {
+			if (trx->mo.nm_state.availability != NM_AVSTATE_OK ||
+			    trx->mo.nm_state.operational != NM_OPSTATE_ENABLED ||
+			    trx->mo.nm_state.administrative != NM_STATE_UNLOCKED) {
 				LOGP(DNM, LOGL_ERROR, "RF activation failed. Starting again.\n");
 				ipaccess_drop_oml(bts);
 				break;
@@ -136,7 +137,7 @@
 	sig.net = rf->gsm_network;
 
 	rf->policy = val;
-	dispatch_signal(SS_RF, val, &sig);
+	osmo_signal_dispatch(SS_RF, val, &sig);
 }
 
 static int switch_rf_off(struct osmo_bsc_rf *rf)
@@ -159,7 +160,7 @@
 {
 	rf->grace_timeout.cb = grace_timeout;
 	rf->grace_timeout.data = rf;
-	bsc_schedule_timer(&rf->grace_timeout, rf->gsm_network->msc_data->mid_call_timeout, 0);
+	osmo_timer_schedule(&rf->grace_timeout, rf->gsm_network->msc_data->mid_call_timeout, 0);
 	LOGP(DINP, LOGL_NOTICE, "Going to switch RF off in %d seconds.\n",
 	     rf->gsm_network->msc_data->mid_call_timeout);
 
@@ -174,26 +175,26 @@
 	switch (rf->last_request) {
 	case RF_CMD_D_OFF:
 		rf->last_state_command = "RF Direct Off";
-		bsc_del_timer(&rf->rf_check);
-		bsc_del_timer(&rf->grace_timeout);
+		osmo_timer_del(&rf->rf_check);
+		osmo_timer_del(&rf->grace_timeout);
 		switch_rf_off(rf);
 		break;
 	case RF_CMD_ON:
 		rf->last_state_command = "RF Direct On";
-		bsc_del_timer(&rf->grace_timeout);
+		osmo_timer_del(&rf->grace_timeout);
 		lock_each_trx(rf->gsm_network, 0);
 		send_signal(rf, S_RF_ON);
-		bsc_schedule_timer(&rf->rf_check, 3, 0);
+		osmo_timer_schedule(&rf->rf_check, 3, 0);
 		break;
 	case RF_CMD_OFF:
 		rf->last_state_command = "RF Scheduled Off";
-		bsc_del_timer(&rf->rf_check);
+		osmo_timer_del(&rf->rf_check);
 		enter_grace(rf);
 		break;
 	}
 }
 
-static int rf_read_cmd(struct bsc_fd *fd)
+static int rf_read_cmd(struct osmo_fd *fd)
 {
 	struct osmo_bsc_rf_conn *conn = fd->data;
 	char buf[1];
@@ -202,9 +203,9 @@
 	rc = read(fd->fd, buf, sizeof(buf));
 	if (rc != sizeof(buf)) {
 		LOGP(DINP, LOGL_ERROR, "Short read %d/%s\n", errno, strerror(errno));
-		bsc_unregister_fd(fd);
+		osmo_fd_unregister(fd);
 		close(fd->fd);
-		write_queue_clear(&conn->queue);
+		osmo_wqueue_clear(&conn->queue);
 		talloc_free(conn);
 		return -1;
 	}
@@ -217,8 +218,8 @@
 	case RF_CMD_ON:
 	case RF_CMD_OFF:
 		conn->rf->last_request = buf[0];
-		if (!bsc_timer_pending(&conn->rf->delay_cmd))
-			bsc_schedule_timer(&conn->rf->delay_cmd, 1, 0);
+		if (!osmo_timer_pending(&conn->rf->delay_cmd))
+			osmo_timer_schedule(&conn->rf->delay_cmd, 1, 0);
 		break;
 	default:
 		conn->rf->last_state_command = "Unknown command";
@@ -229,7 +230,7 @@
 	return 0;
 }
 
-static int rf_write_cmd(struct bsc_fd *fd, struct msgb *msg)
+static int rf_write_cmd(struct osmo_fd *fd, struct msgb *msg)
 {
 	int rc;
 
@@ -242,7 +243,7 @@
 	return 0;
 }
 
-static int rf_ctl_accept(struct bsc_fd *bfd, unsigned int what)
+static int rf_ctl_accept(struct osmo_fd *bfd, unsigned int what)
 {
 	struct osmo_bsc_rf_conn *conn;
 	struct osmo_bsc_rf *rf = bfd->data;
@@ -264,7 +265,7 @@
 		return -1;
 	}
 
-	write_queue_init(&conn->queue, 10);
+	osmo_wqueue_init(&conn->queue, 10);
 	conn->queue.bfd.data = conn;
 	conn->queue.bfd.fd = fd;
 	conn->queue.bfd.when = BSC_FD_READ | BSC_FD_WRITE;
@@ -272,7 +273,7 @@
 	conn->queue.write_cb = rf_write_cmd;
 	conn->rf = rf;
 
-	if (bsc_register_fd(&conn->queue.bfd) != 0) {
+	if (osmo_fd_register(&conn->queue.bfd) != 0) {
 		close(fd);
 		talloc_free(conn);
 		return -1;
@@ -285,7 +286,7 @@
 {
 	unsigned int namelen;
 	struct sockaddr_un local;
-	struct bsc_fd *bfd;
+	struct osmo_fd *bfd;
 	struct osmo_bsc_rf *rf;
 	int rc;
 
@@ -340,7 +341,7 @@
 	bfd->cb = rf_ctl_accept;
 	bfd->data = rf;
 
-	if (bsc_register_fd(bfd) != 0) {
+	if (osmo_fd_register(bfd) != 0) {
 		LOGP(DINP, LOGL_ERROR, "Failed to register bfd.\n");
 		close(bfd->fd);
 		talloc_free(rf);
diff --git a/src/osmo-bsc/osmo_bsc_sccp.c b/src/osmo-bsc/osmo_bsc_sccp.c
index 1abb473..f4cdf36 100644
--- a/src/osmo-bsc/osmo_bsc_sccp.c
+++ b/src/osmo-bsc/osmo_bsc_sccp.c
@@ -27,9 +27,9 @@
 #include <openbsc/ipaccess.h>
 #include <openbsc/signal.h>
 
-#include <osmocore/gsm0808.h>
-#include <osmocore/talloc.h>
-#include <osmocore/protocol/gsm_08_08.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/gsm/gsm0808.h>
+#include <osmocom/gsm/protocol/gsm_08_08.h>
 
 #include <osmocom/sccp/sccp.h>
 
@@ -95,8 +95,8 @@
 		LOGP(DMSC, LOGL_DEBUG, "Connection established: %p\n", conn);
 		con_data = (struct osmo_bsc_sccp_con *) conn->data_ctx;
 
-		bsc_del_timer(&con_data->sccp_cc_timeout);
-		bsc_schedule_timer(&con_data->sccp_it_timeout, SCCP_IT_TIMER, 0);
+		osmo_timer_del(&con_data->sccp_cc_timeout);
+		osmo_timer_schedule(&con_data->sccp_it_timeout, SCCP_IT_TIMER, 0);
 
 		send_queued(con_data);
 	}
@@ -122,7 +122,7 @@
 		(struct osmo_bsc_sccp_con *) _data;
 
 	sccp_connection_send_it(data->sccp);
-	bsc_schedule_timer(&data->sccp_it_timeout, SCCP_IT_TIMER, 0);
+	osmo_timer_schedule(&data->sccp_it_timeout, SCCP_IT_TIMER, 0);
 }
 
 static void sccp_cc_timeout(void *_data)
@@ -231,7 +231,7 @@
 
 int bsc_open_connection(struct osmo_bsc_sccp_con *conn, struct msgb *msg)
 {
-	bsc_schedule_timer(&conn->sccp_cc_timeout, 10, 0);
+	osmo_timer_schedule(&conn->sccp_cc_timeout, 10, 0);
 	sccp_connection_connect(conn->sccp, &sccp_ssn_bssap, msg);
 	msgb_free(msg);
 	return 0;
@@ -246,8 +246,8 @@
 		LOGP(DMSC, LOGL_ERROR, "Should have been cleared.\n");
 
 	llist_del(&sccp->entry);
-	bsc_del_timer(&sccp->sccp_it_timeout);
-	bsc_del_timer(&sccp->sccp_cc_timeout);
+	osmo_timer_del(&sccp->sccp_it_timeout);
+	osmo_timer_del(&sccp->sccp_cc_timeout);
 	talloc_free(sccp);
 	return 0;
 }
@@ -282,7 +282,7 @@
 	sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL);
 	sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, gsmnet);
 
-	register_signal_handler(SS_MSC, handle_msc_signal, gsmnet);
+	osmo_signal_register_handler(SS_MSC, handle_msc_signal, gsmnet);
 
 	return 0;
 }
diff --git a/src/osmo-bsc/osmo_bsc_vty.c b/src/osmo-bsc/osmo_bsc_vty.c
index 1667742..0b1698e 100644
--- a/src/osmo-bsc/osmo_bsc_vty.c
+++ b/src/osmo-bsc/osmo_bsc_vty.c
@@ -1,6 +1,6 @@
 /* Osmo BSC VTY Configuration */
-/* (C) 2009-2010 by Holger Hans Peter Freyther
- * (C) 2009-2010 by On-Waves
+/* (C) 2009-2011 by Holger Hans Peter Freyther
+ * (C) 2009-2011 by On-Waves
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,7 @@
 #include <openbsc/osmo_msc_data.h>
 #include <openbsc/vty.h>
 
-#include <osmocore/talloc.h>
+#include <osmocom/core/talloc.h>
 
 
 #define IPA_STR "IP.ACCESS specific\n"
@@ -51,33 +51,34 @@
 
 static int config_write_msc(struct vty *vty)
 {
+	struct bsc_msc_dest *dest;
 	struct osmo_msc_data *data = osmo_msc_data(vty);
 
-	vty_out(vty, " msc%s", VTY_NEWLINE);
+	vty_out(vty, "msc%s", VTY_NEWLINE);
 	if (data->bsc_token)
-		vty_out(vty, "  token %s%s", data->bsc_token, VTY_NEWLINE);
+		vty_out(vty, " token %s%s", data->bsc_token, VTY_NEWLINE);
 	if (data->core_ncc != -1)
-		vty_out(vty, "  core-mobile-network-code %d%s",
+		vty_out(vty, " core-mobile-network-code %d%s",
 			data->core_ncc, VTY_NEWLINE);
 	if (data->core_mcc != -1)
-		vty_out(vty, "  core-mobile-country-code %d%s",
+		vty_out(vty, " core-mobile-country-code %d%s",
 			data->core_mcc, VTY_NEWLINE);
-	vty_out(vty, "  ip.access rtp-base %d%s", data->rtp_base, VTY_NEWLINE);
-	vty_out(vty, "  ip %s%s", data->msc_ip, VTY_NEWLINE);
-	vty_out(vty, "  port %d%s", data->msc_port, VTY_NEWLINE);
-	vty_out(vty, "  ip-dscp %d%s", data->msc_ip_dscp, VTY_NEWLINE);
-	vty_out(vty, "  timeout-ping %d%s", data->ping_timeout, VTY_NEWLINE);
-	vty_out(vty, "  timeout-pong %d%s", data->pong_timeout, VTY_NEWLINE);
+	vty_out(vty, " ip.access rtp-base %d%s", data->rtp_base, VTY_NEWLINE);
+	vty_out(vty, " timeout-ping %d%s", data->ping_timeout, VTY_NEWLINE);
+	vty_out(vty, " timeout-pong %d%s", data->pong_timeout, VTY_NEWLINE);
 	if (data->mid_call_txt)
-		vty_out(vty, "mid-call-text %s%s", data->mid_call_txt, VTY_NEWLINE);
+		vty_out(vty, " mid-call-text %s%s", data->mid_call_txt, VTY_NEWLINE);
 	vty_out(vty, " mid-call-timeout %d%s", data->mid_call_timeout, VTY_NEWLINE);
 	if (data->ussd_welcome_txt)
 		vty_out(vty, " bsc-welcome-text %s%s", data->ussd_welcome_txt, VTY_NEWLINE);
+	if (data->rf_ctrl_name)
+		vty_out(vty, " bsc-rf-socket %s%s",
+			data->rf_ctrl_name, VTY_NEWLINE);
 
 	if (data->audio_length != 0) {
 		int i;
 
-		vty_out(vty, " codec_list ");
+		vty_out(vty, " codec-list ");
 		for (i = 0; i < data->audio_length; ++i) {
 			if (i != 0)
 				vty_out(vty, ", ");
@@ -91,6 +92,10 @@
 
 	}
 
+	llist_for_each_entry(dest, &data->dests, list)
+		vty_out(vty, " dest %s %d %d%s", dest->ip, dest->port,
+			dest->dscp, VTY_NEWLINE);
+
 	return CMD_SUCCESS;
 }
 
@@ -197,34 +202,55 @@
 	return CMD_ERR_INCOMPLETE;
 }
 
-DEFUN(cfg_net_msc_ip,
-      cfg_net_msc_ip_cmd,
-      "ip A.B.C.D", "Set the MSC/MUX IP address.")
+DEFUN(cfg_net_msc_dest,
+      cfg_net_msc_dest_cmd,
+      "dest A.B.C.D <1-65000> <0-255>",
+      "Add a destination to a MUX/MSC\n"
+      "IP Address\n" "Port\n" "DSCP\n")
 {
+	struct bsc_msc_dest *dest;
 	struct osmo_msc_data *data = osmo_msc_data(vty);
 
-	bsc_replace_string(data, &data->msc_ip, argv[0]);
+	dest = talloc_zero(data, struct bsc_msc_dest);
+	if (!dest) {
+		vty_out(vty, "%%Failed to create structure.%s", VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	dest->ip = talloc_strdup(data, argv[0]);
+	if (!dest->ip) {
+		vty_out(vty, "%%Failed to copy dest ip.%s", VTY_NEWLINE);
+		talloc_free(dest);
+		return CMD_WARNING;
+	}
+
+	dest->port = atoi(argv[1]);
+	dest->dscp = atoi(argv[2]);
+	llist_add_tail(&dest->list, &data->dests);
 	return CMD_SUCCESS;
 }
 
-DEFUN(cfg_net_msc_port,
-      cfg_net_msc_port_cmd,
-      "port <1-65000>",
-      "Set the MSC/MUX port.")
+DEFUN(cfg_net_msc_no_dest,
+      cfg_net_msc_no_dest_cmd,
+      "no dest A.B.C.D <1-65000> <0-255>",
+      NO_STR "Remove a destination to a MUX/MSC\n"
+      "IP Address\n" "Port\n" "DSCP\n")
 {
+	struct bsc_msc_dest *dest, *tmp;
 	struct osmo_msc_data *data = osmo_msc_data(vty);
-	data->msc_port = atoi(argv[0]);
-	return CMD_SUCCESS;
-}
 
+	int port = atoi(argv[1]);
+	int dscp = atoi(argv[2]);
 
-DEFUN(cfg_net_msc_prio,
-      cfg_net_msc_prio_cmd,
-      "ip-dscp <0-255>",
-      "Set the IP_TOS socket attribite")
-{
-	struct osmo_msc_data *data = osmo_msc_data(vty);
-	data->msc_ip_dscp = atoi(argv[0]);
+	llist_for_each_entry_safe(dest, tmp, &data->dests, list) {
+		if (port != dest->port || dscp != dest->dscp
+		    || strcmp(dest->ip, argv[0]) != 0)
+			continue;
+
+		llist_del(&dest->list);
+		talloc_free(dest);
+	}
+
 	return CMD_SUCCESS;
 }
 
@@ -288,9 +314,29 @@
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_net_rf_socket,
+      cfg_net_rf_socket_cmd,
+      "bsc-rf-socket PATH",
+      "Set the filename for the RF control interface.\n" "RF Control path\n")
+{
+	struct osmo_msc_data *data = osmo_msc_data(vty);
+
+	bsc_replace_string(data, &data->rf_ctrl_name, argv[0]);
+	return CMD_SUCCESS;
+}
+
+DEFUN(show_statistics,
+      show_statistics_cmd,
+      "show statistics",
+      SHOW_STR "Statistics about the BSC\n")
+{
+	openbsc_vty_print_statistics(vty, bsc_gsmnet);
+	return CMD_SUCCESS;
+}
+
 int bsc_vty_init_extra(void)
 {
-	install_element(GSMNET_NODE, &cfg_net_msc_cmd);
+	install_element(CONFIG_NODE, &cfg_net_msc_cmd);
 	install_node(&msc_node, config_write_msc);
 	install_default(MSC_NODE);
 	install_element(MSC_NODE, &cfg_net_bsc_token_cmd);
@@ -298,14 +344,16 @@
 	install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd);
 	install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd);
 	install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd);
-	install_element(MSC_NODE, &cfg_net_msc_ip_cmd);
-	install_element(MSC_NODE, &cfg_net_msc_port_cmd);
-	install_element(MSC_NODE, &cfg_net_msc_prio_cmd);
+	install_element(MSC_NODE, &cfg_net_msc_dest_cmd);
+	install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd);
 	install_element(MSC_NODE, &cfg_net_msc_ping_time_cmd);
 	install_element(MSC_NODE, &cfg_net_msc_pong_time_cmd);
 	install_element(MSC_NODE, &cfg_net_msc_mid_call_text_cmd);
 	install_element(MSC_NODE, &cfg_net_msc_mid_call_timeout_cmd);
 	install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
+	install_element(MSC_NODE, &cfg_net_rf_socket_cmd);
+
+	install_element_ve(&show_statistics_cmd);
 
 	return 0;
 }