Merge remote branch 'origin/master' into on-waves/mgcp

Conflicts:
	openbsc/include/openbsc/Makefile.am
	openbsc/src/Makefile.am
diff --git a/openbsc/Makefile.am b/openbsc/Makefile.am
index deaba0f..7acae75 100644
--- a/openbsc/Makefile.am
+++ b/openbsc/Makefile.am
@@ -4,7 +4,7 @@
 SUBDIRS = include src tests
 
 pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = openbsc.pc
+pkgconfig_DATA = openbsc.pc libsccp.pc
 
 #dist-hook:
 #	rm -rf `find $(distdir) -name .svn`
diff --git a/openbsc/configure.in b/openbsc/configure.in
index cba6c6c..71ed10b 100644
--- a/openbsc/configure.in
+++ b/openbsc/configure.in
@@ -16,6 +16,8 @@
 AC_SEARCH_LIBS(crypt, crypt,
     [LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
 
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
+
 dnl checks for header files
 AC_HEADER_STDC
 
@@ -38,6 +40,7 @@
 
 AC_OUTPUT(
     openbsc.pc
+    libsccp.pc
     include/openbsc/Makefile
     include/vty/Makefile
     include/sccp/Makefile
@@ -45,8 +48,6 @@
     src/Makefile
     tests/Makefile
     tests/debug/Makefile
-    tests/timer/Makefile
-    tests/sms/Makefile
     tests/gsm0408/Makefile
     tests/db/Makefile
     tests/channel/Makefile
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index 05b802d..483997a 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -1,8 +1,11 @@
-noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \
-		 gsm_subscriber.h linuxlist.h msgb.h select.h tlv.h gsm_04_11.h \
-		 timer.h misdn.h chan_alloc.h telnet_interface.h paging.h \
-		 subchan_demux.h trau_frame.h e1_input.h trau_mux.h signal.h \
-		 gsm_utils.h ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
-		 bsc_rll.h mncc.h talloc.h transaction.h ussd.h gsm_04_80.h \
-		 silent_call.h mgcp.h meas_rep.h bitvec.h rest_octets.h \
-		 system_information.h handover.h statistics.h mgcp_internal.h
+noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
+		 gsm_subscriber.h gsm_04_11.h debug.h signal.h \
+		 misdn.h chan_alloc.h telnet_interface.h paging.h \
+		 subchan_demux.h trau_frame.h e1_input.h trau_mux.h \
+		 ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
+		 bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
+		 silent_call.h mgcp.h meas_rep.h rest_octets.h \
+		 system_information.h handover.h mgcp_internal.h
+
+openbsc_HEADERS = gsm_04_08.h meas_rep.h
+openbscdir = $(includedir)/openbsc
diff --git a/openbsc/include/openbsc/abis_nm.h b/openbsc/include/openbsc/abis_nm.h
index 81b4eda..cff91e0 100644
--- a/openbsc/include/openbsc/abis_nm.h
+++ b/openbsc/include/openbsc/abis_nm.h
@@ -24,672 +24,8 @@
 #define _NM_H
 
 #include <sys/types.h>
-
-#include <openbsc/tlv.h>
-
-/* PRIVATE */
-
-/* generic header in front of every OML message according to TS 08.59 */
-struct abis_om_hdr {
-	u_int8_t	mdisc;
-	u_int8_t	placement;
-	u_int8_t	sequence;
-	u_int8_t	length;
-	u_int8_t	data[0];
-} __attribute__ ((packed));
-
-#define ABIS_OM_MDISC_FOM		0x80
-#define ABIS_OM_MDISC_MMI		0x40
-#define ABIS_OM_MDISC_TRAU		0x20
-#define ABIS_OM_MDISC_MANUF		0x10
-#define ABIS_OM_PLACEMENT_ONLY		0x80
-#define ABIS_OM_PLACEMENT_FIRST 	0x40
-#define ABIS_OM_PLACEMENT_MIDDLE	0x20
-#define ABIS_OM_PLACEMENT_LAST		0x10
-
-struct abis_om_obj_inst {
-	u_int8_t	bts_nr;
-	u_int8_t	trx_nr;
-	u_int8_t	ts_nr;
-} __attribute__ ((packed));
-
-struct abis_om_fom_hdr {
-	u_int8_t	msg_type;
-	u_int8_t	obj_class;
-	struct abis_om_obj_inst	obj_inst;
-	u_int8_t	data[0];
-} __attribute__ ((packed));
-
-#define ABIS_OM_FOM_HDR_SIZE	(sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
-
-/* Section 9.1: Message Types */
-enum abis_nm_msgtype {
-	/* SW Download Management Messages */
-	NM_MT_LOAD_INIT			= 0x01,
-	NM_MT_LOAD_INIT_ACK,
-	NM_MT_LOAD_INIT_NACK,
-	NM_MT_LOAD_SEG,
-	NM_MT_LOAD_SEG_ACK,
-	NM_MT_LOAD_ABORT,
-	NM_MT_LOAD_END,
-	NM_MT_LOAD_END_ACK,
-	NM_MT_LOAD_END_NACK,
-	NM_MT_SW_ACT_REQ,		/* BTS->BSC */
-	NM_MT_SW_ACT_REQ_ACK,
-	NM_MT_SW_ACT_REQ_NACK,
-	NM_MT_ACTIVATE_SW,		/* BSC->BTS */
-	NM_MT_ACTIVATE_SW_ACK,
-	NM_MT_ACTIVATE_SW_NACK,
-	NM_MT_SW_ACTIVATED_REP,		/* 0x10 */
-	/* A-bis Interface Management Messages */
-	NM_MT_ESTABLISH_TEI		= 0x21,
-	NM_MT_ESTABLISH_TEI_ACK,
-	NM_MT_ESTABLISH_TEI_NACK,
-	NM_MT_CONN_TERR_SIGN,
-	NM_MT_CONN_TERR_SIGN_ACK,
-	NM_MT_CONN_TERR_SIGN_NACK,
-	NM_MT_DISC_TERR_SIGN,
-	NM_MT_DISC_TERR_SIGN_ACK,
-	NM_MT_DISC_TERR_SIGN_NACK,
-	NM_MT_CONN_TERR_TRAF,
-	NM_MT_CONN_TERR_TRAF_ACK,
-	NM_MT_CONN_TERR_TRAF_NACK,
-	NM_MT_DISC_TERR_TRAF,
-	NM_MT_DISC_TERR_TRAF_ACK,
-	NM_MT_DISC_TERR_TRAF_NACK,
-	/* Transmission Management Messages */
-	NM_MT_CONN_MDROP_LINK		= 0x31,
-	NM_MT_CONN_MDROP_LINK_ACK,
-	NM_MT_CONN_MDROP_LINK_NACK,
-	NM_MT_DISC_MDROP_LINK,
-	NM_MT_DISC_MDROP_LINK_ACK,
-	NM_MT_DISC_MDROP_LINK_NACK,
-	/* Air Interface Management Messages */
-	NM_MT_SET_BTS_ATTR		= 0x41,
-	NM_MT_SET_BTS_ATTR_ACK,
-	NM_MT_SET_BTS_ATTR_NACK,
-	NM_MT_SET_RADIO_ATTR,
-	NM_MT_SET_RADIO_ATTR_ACK,
-	NM_MT_SET_RADIO_ATTR_NACK,
-	NM_MT_SET_CHAN_ATTR,
-	NM_MT_SET_CHAN_ATTR_ACK,
-	NM_MT_SET_CHAN_ATTR_NACK,
-	/* Test Management Messages */
-	NM_MT_PERF_TEST			= 0x51,
-	NM_MT_PERF_TEST_ACK,
-	NM_MT_PERF_TEST_NACK,
-	NM_MT_TEST_REP,
-	NM_MT_SEND_TEST_REP,
-	NM_MT_SEND_TEST_REP_ACK,
-	NM_MT_SEND_TEST_REP_NACK,
-	NM_MT_STOP_TEST,
-	NM_MT_STOP_TEST_ACK,
-	NM_MT_STOP_TEST_NACK,
-	/* State Management and Event Report Messages */
-	NM_MT_STATECHG_EVENT_REP	= 0x61,
-	NM_MT_FAILURE_EVENT_REP,
-	NM_MT_STOP_EVENT_REP,
-	NM_MT_STOP_EVENT_REP_ACK,
-	NM_MT_STOP_EVENT_REP_NACK,
-	NM_MT_REST_EVENT_REP,
-	NM_MT_REST_EVENT_REP_ACK,
-	NM_MT_REST_EVENT_REP_NACK,
-	NM_MT_CHG_ADM_STATE,
-	NM_MT_CHG_ADM_STATE_ACK,
-	NM_MT_CHG_ADM_STATE_NACK,
-	NM_MT_CHG_ADM_STATE_REQ,
-	NM_MT_CHG_ADM_STATE_REQ_ACK,
-	NM_MT_CHG_ADM_STATE_REQ_NACK,
-	NM_MT_REP_OUTST_ALARMS		= 0x93,
-	NM_MT_REP_OUTST_ALARMS_ACK,
-	NM_MT_REP_OUTST_ALARMS_NACK,
-	/* Equipment Management Messages */
-	NM_MT_CHANGEOVER		= 0x71,
-	NM_MT_CHANGEOVER_ACK,
-	NM_MT_CHANGEOVER_NACK,
-	NM_MT_OPSTART,
-	NM_MT_OPSTART_ACK,
-	NM_MT_OPSTART_NACK,
-	NM_MT_REINIT,
-	NM_MT_REINIT_ACK,
-	NM_MT_REINIT_NACK,
-	NM_MT_SET_SITE_OUT,		/* BS11: get alarm ?!? */
-	NM_MT_SET_SITE_OUT_ACK,
-	NM_MT_SET_SITE_OUT_NACK,
-	NM_MT_CHG_HW_CONF		= 0x90,
-	NM_MT_CHG_HW_CONF_ACK,
-	NM_MT_CHG_HW_CONF_NACK,
-	/* Measurement Management Messages */
-	NM_MT_MEAS_RES_REQ		= 0x8a,
-	NM_MT_MEAS_RES_RESP,
-	NM_MT_STOP_MEAS,
-	NM_MT_START_MEAS,
-	/* Other Messages */
-	NM_MT_GET_ATTR			= 0x81,
-	NM_MT_GET_ATTR_RESP,
-	NM_MT_GET_ATTR_NACK,
-	NM_MT_SET_ALARM_THRES,
-	NM_MT_SET_ALARM_THRES_ACK,
-	NM_MT_SET_ALARM_THRES_NACK,
-};
-
-enum abis_nm_msgtype_bs11 {
-	NM_MT_BS11_RESET_RESOURCE	= 0x74,
-
-	NM_MT_BS11_BEGIN_DB_TX		= 0xa3,
-	NM_MT_BS11_BEGIN_DB_TX_ACK,
-	NM_MT_BS11_BEGIN_DB_TX_NACK,
-	NM_MT_BS11_END_DB_TX		= 0xa6,
-	NM_MT_BS11_END_DB_TX_ACK,
-	NM_MT_BS11_END_DB_TX_NACK,
-	NM_MT_BS11_CREATE_OBJ		= 0xa9,
-	NM_MT_BS11_CREATE_OBJ_ACK,
-	NM_MT_BS11_CREATE_OBJ_NACK,
-	NM_MT_BS11_DELETE_OBJ		= 0xac,
-	NM_MT_BS11_DELETE_OBJ_ACK,
-	NM_MT_BS11_DELETE_OBJ_NACK,
-
-	NM_MT_BS11_SET_ATTR		= 0xd0,
-	NM_MT_BS11_SET_ATTR_ACK,
-	NM_MT_BS11_SET_ATTR_NACK,
-	NM_MT_BS11_LMT_SESSION		= 0xdc,
-
-	NM_MT_BS11_GET_STATE		= 0xe3,
-	NM_MT_BS11_GET_STATE_ACK,
-	NM_MT_BS11_LMT_LOGON		= 0xe5,
-	NM_MT_BS11_LMT_LOGON_ACK,
-	NM_MT_BS11_RESTART		= 0xe7,
-	NM_MT_BS11_RESTART_ACK,
-	NM_MT_BS11_DISCONNECT		= 0xe9,
-	NM_MT_BS11_DISCONNECT_ACK,
-	NM_MT_BS11_LMT_LOGOFF		= 0xec,
-	NM_MT_BS11_LMT_LOGOFF_ACK,
-	NM_MT_BS11_RECONNECT		= 0xf1,
-	NM_MT_BS11_RECONNECT_ACK,
-};
-
-enum abis_nm_msgtype_ipacc {
-	NM_MT_IPACC_RESTART		= 0x87,
-	NM_MT_IPACC_RESTART_ACK,
-	NM_MT_IPACC_RESTART_NACK,
-	NM_MT_IPACC_RSL_CONNECT		= 0xe0,
-	NM_MT_IPACC_RSL_CONNECT_ACK,
-	NM_MT_IPACC_RSL_CONNECT_NACK,
-	NM_MT_IPACC_RSL_DISCONNECT	= 0xe3,
-	NM_MT_IPACC_RSL_DISCONNECT_ACK,
-	NM_MT_IPACC_RSL_DISCONNECT_NACK,
-	NM_MT_IPACC_CONN_TRAF		= 0xe6,
-	NM_MT_IPACC_CONN_TRAF_ACK,
-	NM_MT_IPACC_CONN_TRAF_NACK,
-	NM_MT_IPACC_DEF_BOOT_SW		= 0xec,
-	NM_MT_IPACC_DEF_BOOT_SW_ACK,
-	MN_MT_IPACC_DEF_BOOT_SW_NACK,
-	NM_MT_IPACC_SET_NVATTR		= 0xef,
-	NM_MT_IPACC_SET_NVATTR_ACK,
-	NM_MT_IPACC_SET_NVATTR_NACK,
-	NM_MT_IPACC_GET_NVATTR		= 0xf2,
-	NM_MT_IPACC_GET_NVATTR_ACK,
-	NM_MT_IPACC_GET_NVATTR_NACK,
-	NM_MT_IPACC_SET_ATTR		= 0xf5,
-	NM_MT_IPACC_SET_ATTR_ACK,
-	NM_MT_IPACC_SET_ATTR_NACK,
-};
-
-enum abis_nm_bs11_cell_alloc {
-	NM_BS11_CANR_GSM	= 0x00,
-	NM_BS11_CANR_DCS1800	= 0x01,
-};
-
-/* Section 9.2: Object Class */
-enum abis_nm_obj_class {
-	NM_OC_SITE_MANAGER		= 0x00,
-	NM_OC_BTS,
-	NM_OC_RADIO_CARRIER,
-	NM_OC_CHANNEL,
-	NM_OC_BASEB_TRANSC,
-	/* RFU: 05-FE */
-
-	NM_OC_IPAC_E1_TRUNK		= 0x0e,
-	NM_OC_IPAC_E1_PORT		= 0x0f,
-	NM_OC_IPAC_E1_CHAN		= 0x10,
-	NM_OC_IPAC_CLK_MODULE		= 0x22,
-
-	NM_OC_BS11_ADJC			= 0xa0,
-	NM_OC_BS11_HANDOVER		= 0xa1,
-	NM_OC_BS11_PWR_CTRL		= 0xa2,
-	NM_OC_BS11_BTSE			= 0xa3,		/* LMT? */
-	NM_OC_BS11_RACK			= 0xa4,
-	NM_OC_BS11			= 0xa5,		/* 01: ALCO */
-	NM_OC_BS11_TEST			= 0xa6,
-	NM_OC_BS11_ENVABTSE		= 0xa8,
-	NM_OC_BS11_BPORT		= 0xa9,
-
-	NM_OC_GPRS_NSE			= 0xf0,
-	NM_OC_GPRS_CELL			= 0xf1,
-	NM_OC_GPRS_NSVC			= 0xf2,
-
-	NM_OC_NULL			= 0xff,
-};
-
-/* Section 9.4: Attributes */
-enum abis_nm_attr {
-	NM_ATT_ABIS_CHANNEL	= 0x01,
-	NM_ATT_ADD_INFO,
-	NM_ATT_ADD_TEXT,
-	NM_ATT_ADM_STATE,
-	NM_ATT_ARFCN_LIST,
-	NM_ATT_AUTON_REPORT,
-	NM_ATT_AVAIL_STATUS,
-	NM_ATT_BCCH_ARFCN,
-	NM_ATT_BSIC,
-	NM_ATT_BTS_AIR_TIMER,
-	NM_ATT_CCCH_L_I_P,
-	NM_ATT_CCCH_L_T,
-	NM_ATT_CHAN_COMB,
-	NM_ATT_CONN_FAIL_CRIT,
-	NM_ATT_DEST,
-	/* res */
-	NM_ATT_EVENT_TYPE	= 0x11, /* BS11: file data ?!? */
-	NM_ATT_FILE_ID,
-	NM_ATT_FILE_VERSION,
-	NM_ATT_GSM_TIME,
-	NM_ATT_HSN,
-	NM_ATT_HW_CONFIG,
-	NM_ATT_HW_DESC,
-	NM_ATT_INTAVE_PARAM,
-	NM_ATT_INTERF_BOUND,
-	NM_ATT_LIST_REQ_ATTR,
-	NM_ATT_MAIO,
-	NM_ATT_MANUF_STATE,
-	NM_ATT_MANUF_THRESH,
-	NM_ATT_MANUF_ID,
-	NM_ATT_MAX_TA,
-	NM_ATT_MDROP_LINK,	/* 0x20 */
-	NM_ATT_MDROP_NEXT,
-	NM_ATT_NACK_CAUSES,
-	NM_ATT_NY1,
-	NM_ATT_OPER_STATE,
-	NM_ATT_OVERL_PERIOD,
-	NM_ATT_PHYS_CONF,
-	NM_ATT_POWER_CLASS,
-	NM_ATT_POWER_THRESH,
-	NM_ATT_PROB_CAUSE,
-	NM_ATT_RACH_B_THRESH,
-	NM_ATT_LDAVG_SLOTS,
-	NM_ATT_RAD_SUBC,
-	NM_ATT_RF_MAXPOWR_R,
-	NM_ATT_SITE_INPUTS,
-	NM_ATT_SITE_OUTPUTS,
-	NM_ATT_SOURCE,		/* 0x30 */
-	NM_ATT_SPEC_PROB,
-	NM_ATT_START_TIME,
-	NM_ATT_T200,
-	NM_ATT_TEI,
-	NM_ATT_TEST_DUR,
-	NM_ATT_TEST_NO,
-	NM_ATT_TEST_REPORT,
-	NM_ATT_VSWR_THRESH,
-	NM_ATT_WINDOW_SIZE,
-	/* Res  */
-	NM_ATT_BS11_RSSI_OFFS	= 0x3d,
-	NM_ATT_BS11_TXPWR	= 0x3e,
-	NM_ATT_BS11_DIVERSITY	= 0x3f,
-	/* Res  */
-	NM_ATT_TSC		= 0x40,
-	NM_ATT_SW_CONFIG,
-	NM_ATT_SW_DESCR,
-	NM_ATT_SEVERITY,
-	NM_ATT_GET_ARI,
-	NM_ATT_HW_CONF_CHG,
-	NM_ATT_OUTST_ALARM,
-	NM_ATT_FILE_DATA,
-	NM_ATT_MEAS_RES,
-	NM_ATT_MEAS_TYPE,
-
-	NM_ATT_BS11_ESN_FW_CODE_NO	= 0x4c,
-	NM_ATT_BS11_ESN_HW_CODE_NO	= 0x4f,
-
-	NM_ATT_BS11_ESN_PCB_SERIAL	= 0x55,
-	NM_ATT_BS11_EXCESSIVE_DISTANCE	= 0x58,
-
-	NM_ATT_BS11_ALL_TEST_CATG	= 0x60,
-	NM_ATT_BS11_BTSLS_HOPPING,
-	NM_ATT_BS11_CELL_ALLOC_NR,
-	NM_ATT_BS11_CELL_GLOBAL_ID,
-	NM_ATT_BS11_ENA_INTERF_CLASS	= 0x66,
-	NM_ATT_BS11_ENA_INT_INTEC_HANDO	= 0x67,
-	NM_ATT_BS11_ENA_INT_INTRC_HANDO	= 0x68,
-	NM_ATT_BS11_ENA_MS_PWR_CTRL	= 0x69,
-	NM_ATT_BS11_ENA_PWR_BDGT_HO	= 0x6a,
-	NM_ATT_BS11_ENA_PWR_CTRL_RLFW	= 0x6b,
-	NM_ATT_BS11_ENA_RXLEV_HO	= 0x6c,
-	NM_ATT_BS11_ENA_RXQUAL_HO	= 0x6d,
-	NM_ATT_BS11_FACCH_QUAL		= 0x6e,
-
-	NM_ATT_IPACC_DST_IP		= 0x80,
-	NM_ATT_IPACC_DST_IP_PORT	= 0x81,
-	NM_ATT_IPACC_SSRC		= 0x82,
-	NM_ATT_IPACC_RTP_PAYLD_TYPE	= 0x83,
-	NM_ATT_IPACC_BASEB_ID		= 0x84,
-	NM_ATT_IPACC_STREAM_ID		= 0x85,
-	NM_ATT_IPACC_NV_FLAGS		= 0x86,
-	NM_ATT_IPACC_FREQ_CTRL		= 0x87,
-	NM_ATT_IPACC_PRIM_OML_CFG	= 0x88,
-	NM_ATT_IPACC_SEC_OML_CFG	= 0x89,
-	NM_ATT_IPACC_IP_IF_CFG		= 0x8a,		/* IP interface */
-	NM_ATT_IPACC_IP_GW_CFG		= 0x8b,		/* IP gateway */
-	NM_ATT_IPACC_IN_SERV_TIME	= 0x8c,
-	NM_ATT_IPACC_TRX_BTS_ASS	= 0x8d,
-	NM_ATT_IPACC_LOCATION		= 0x8e,		/* string describing location */
-	NM_ATT_IPACC_PAGING_CFG		= 0x8f,
-	NM_ATT_IPACC_FILE_DATA		= 0x90,
-	NM_ATT_IPACC_UNIT_ID		= 0x91,		/* Site/BTS/TRX */
-	NM_ATT_IPACC_PARENT_UNIT_ID	= 0x92,
-	NM_ATT_IPACC_UNIT_NAME		= 0x93,		/* default: nbts-<mac-as-string> */
-	NM_ATT_IPACC_SNMP_CFG		= 0x94,
-	NM_ATT_IPACC_PRIM_OML_CFG_LIST	= 0x95,
-	NM_ATT_IPACC_PRIM_OML_FB_TOUT	= 0x96,
-	NM_ATT_IPACC_CUR_SW_CFG		= 0x97,
-	NM_ATT_IPACC_TIMING_BUS		= 0x98,
-	NM_ATT_IPACC_CGI		= 0x99,
-	NM_ATT_IPACC_RAC		= 0x9a,
-	NM_ATT_IPACC_OBJ_VERSION	= 0x9b,
-	NM_ATT_IPACC_GPRS_PAGING_CFG	= 0x9c,
-	NM_ATT_IPACC_NSEI		= 0x9d,
-	NM_ATT_IPACC_BVCI		= 0x9e,
-	NM_ATT_IPACC_NSVCI		= 0x9f,
-	NM_ATT_IPACC_NS_CFG		= 0xa0,
-	NM_ATT_IPACC_BSSGP_CFG		= 0xa1,
-	NM_ATT_IPACC_NS_LINK_CFG	= 0xa2,
-	NM_ATT_IPACC_RLC_CFG		= 0xa3,	
-	NM_ATT_IPACC_ALM_THRESH_LIST	= 0xa4,
-	NM_ATT_IPACC_MONIT_VAL_LIST	= 0xa5,
-	NM_ATT_IPACC_TIB_CONTROL	= 0xa6,
-	NM_ATT_IPACC_SUPP_FEATURES	= 0xa7,
-	NM_ATT_IPACC_CODING_SCHEMES	= 0xa8,
-	NM_ATT_IPACC_RLC_CFG_2		= 0xa9,
-	NM_ATT_IPACC_HEARTB_TOUT	= 0xaa,
-	NM_ATT_IPACC_UPTIME		= 0xab,
-	NM_ATT_IPACC_RLC_CFG_3		= 0xac,
-	NM_ATT_IPACC_SSL_CFG		= 0xad,
-	NM_ATT_IPACC_SEC_POSSIBLE	= 0xae,
-	NM_ATT_IPACC_IML_SSL_STATE	= 0xaf,
-	NM_ATT_IPACC_REVOC_DATE		= 0xb0,
-
-
-	NM_ATT_BS11_RF_RES_IND_PER	= 0x8f,
-	
-	NM_ATT_BS11_RX_LEV_MIN_CELL	= 0x90,
-	NM_ATT_BS11_ABIS_EXT_TIME	= 0x91,
-	NM_ATT_BS11_TIMER_HO_REQUEST	= 0x92,
-	NM_ATT_BS11_TIMER_NCELL		= 0x93,
-	NM_ATT_BS11_TSYNC		= 0x94,
-	NM_ATT_BS11_TTRAU		= 0x95,
-	NM_ATT_BS11_EMRG_CFG_MEMBER	= 0x9b,
-	NM_ATT_BS11_TRX_AREA		= 0x9f,
-
-	NM_ATT_BS11_BCCH_RECONF		= 0xd7,
-	NM_ATT_BS11_BIT_ERR_THESH	= 0xa0,
-	NM_ATT_BS11_BOOT_SW_VERS	= 0xa1,
-	NM_ATT_BS11_CCLK_ACCURACY	= 0xa3,
-	NM_ATT_BS11_CCLK_TYPE		= 0xa4,
-	NM_ATT_BS11_INP_IMPEDANCE	= 0xaa,
-	NM_ATT_BS11_L1_PROT_TYPE	= 0xab,
-	NM_ATT_BS11_LINE_CFG		= 0xac,
-	NM_ATT_BS11_LI_PORT_1		= 0xad,
-	NM_ATT_BS11_LI_PORT_2		= 0xae,
-
-	NM_ATT_BS11_L1_REM_ALM_TYPE	= 0xb0,
-	NM_ATT_BS11_SW_LOAD_INTENDED	= 0xbb,
-	NM_ATT_BS11_SW_LOAD_SAFETY	= 0xbc,
-	NM_ATT_BS11_SW_LOAD_STORED	= 0xbd,
-
-	NM_ATT_BS11_VENDOR_NAME		= 0xc1,
-	NM_ATT_BS11_HOPPING_MODE	= 0xc5,
-	NM_ATT_BS11_LMT_LOGON_SESSION	= 0xc6,
-	NM_ATT_BS11_LMT_LOGIN_TIME	= 0xc7,
-	NM_ATT_BS11_LMT_USER_ACC_LEV	= 0xc8,
-	NM_ATT_BS11_LMT_USER_NAME	= 0xc9,
-
-	NM_ATT_BS11_L1_CONTROL_TS	= 0xd8,
-	NM_ATT_BS11_RADIO_MEAS_GRAN	= 0xdc,	/* in SACCH multiframes */
-	NM_ATT_BS11_RADIO_MEAS_REP	= 0xdd,
-
-	NM_ATT_BS11_SH_LAPD_INT_TIMER	= 0xe8,
-
-	NM_ATT_BS11_BTS_STATE		= 0xf0,
-	NM_ATT_BS11_E1_STATE		= 0xf1,
-	NM_ATT_BS11_PLL			= 0xf2,
-	NM_ATT_BS11_RX_OFFSET		= 0xf3,
-	NM_ATT_BS11_ANT_TYPE		= 0xf4,
-	NM_ATT_BS11_PLL_MODE		= 0xfc,
-	NM_ATT_BS11_PASSWORD		= 0xfd,
-};
-#define NM_ATT_BS11_FILE_DATA	NM_ATT_EVENT_TYPE
-
-/* Section 9.4.4: Administrative State */
-enum abis_nm_adm_state {
-	NM_STATE_LOCKED		= 0x01,
-	NM_STATE_UNLOCKED	= 0x02,
-	NM_STATE_SHUTDOWN	= 0x03,
-	NM_STATE_NULL		= 0xff,
-};
-
-/* Section 9.4.7: Administrative State */
-enum abis_nm_avail_state {
-	NM_AVSTATE_IN_TEST	= 1,
-	NM_AVSTATE_POWER_OFF	= 2,
-	NM_AVSTATE_OFF_LINE	= 3,
-	NM_AVSTATE_DEPENDENCY	= 5,
-	NM_AVSTATE_DEGRADED	= 6,
-	NM_AVSTATE_NOT_INSTALLED= 7,
-	NM_AVSTATE_OK		= 0xff,
-};
-
-enum abis_nm_op_state {
-	NM_OPSTATE_DISABLED	= 1,
-	NM_OPSTATE_ENABLED	= 2,
-	NM_OPSTATE_NULL		= 0xff,
-};
-
-/* Section 9.4.13: Channel Combination */
-enum abis_nm_chan_comb {
-	NM_CHANC_TCHFull	= 0x00,	/* TCH/F + TCH/H + SACCH/TF */
-	NM_CHANC_TCHHalf	= 0x01, /* TCH/H(0,1) + FACCH/H(0,1) +
-					   SACCH/TH(0,1) */
-	NM_CHANC_TCHHalf2	= 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) +
-					   TCH/H(1) */
-	NM_CHANC_SDCCH		= 0x03,	/* SDCCH/8 + SACCH/8 */
-	NM_CHANC_mainBCCH	= 0x04,	/* FCCH + SCH + BCCH + CCCH */
-	NM_CHANC_BCCHComb	= 0x05,	/* FCCH + SCH + BCCH + CCCH + SDCCH/4 +
-					   SACCH/C4 */
-	NM_CHANC_BCCH		= 0x06,	/* BCCH + CCCH */
-	NM_CHANC_BCCH_CBCH	= 0x07,	/* CHANC_BCCHComb + CBCH */
-	NM_CHANC_SDCCH_CBCH	= 0x08,	/* CHANC_SDCCH8 + CBCH */
-	/* ip.access */
-	NM_CHANC_IPAC_bPDCH	= 0x0b,	/* PBCCH + PCCCH + PDTCH/F + PACCH/F +
-					   PTCCH/F */
-	NM_CHANC_IPAC_cPDCH	= 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
-	NM_CHANC_IPAC_PDCH	= 0x0d,	/* PDTCH/F + PACCH/F + PTCCH/F */
-	NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
-	NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
-};
-
-/* Section 9.4.16: Event Type */
-enum abis_nm_event_type {
-	NM_EVT_COMM_FAIL	= 0x00,
-	NM_EVT_QOS_FAIL		= 0x01,
-	NM_EVT_PROC_FAIL	= 0x02,
-	NM_EVT_EQUIP_FAIL	= 0x03,
-	NM_EVT_ENV_FAIL		= 0x04,
-};
-
-/* Section: 9.4.63: Perceived Severity */
-enum abis_nm_severity {
-	NM_SEVER_CEASED		= 0x00,
-	NM_SEVER_CRITICAL	= 0x01,
-	NM_SEVER_MAJOR		= 0x02,
-	NM_SEVER_MINOR		= 0x03,
-	NM_SEVER_WARNING	= 0x04,
-	NM_SEVER_INDETERMINATE	= 0x05,
-};
-
-/* Section 9.4.43: Probable Cause Type */
-enum abis_nm_pcause_type {
-	NM_PCAUSE_T_X721	= 0x01,
-	NM_PCAUSE_T_GSM		= 0x02,
-	NM_PCAUSE_T_MANUF	= 0x03,
-};
-
-/* Section 9.4.36: NACK Causes */
-enum abis_nm_nack_cause {
-	/* General Nack Causes */
-	NM_NACK_INCORR_STRUCT		= 0x01,
-	NM_NACK_MSGTYPE_INVAL		= 0x02,
-	NM_NACK_OBJCLASS_INVAL		= 0x05,
-	NM_NACK_OBJCLASS_NOTSUPP	= 0x06,
-	NM_NACK_BTSNR_UNKN		= 0x07,
-	NM_NACK_TRXNR_UNKN		= 0x08,
-	NM_NACK_OBJINST_UNKN		= 0x09,
-	NM_NACK_ATTRID_INVAL		= 0x0c,
-	NM_NACK_ATTRID_NOTSUPP		= 0x0d,
-	NM_NACK_PARAM_RANGE		= 0x0e,
-	NM_NACK_ATTRLIST_INCONSISTENT	= 0x0f,
-	NM_NACK_SPEC_IMPL_NOTSUPP	= 0x10,
-	NM_NACK_CANT_PERFORM		= 0x11,
-	/* Specific Nack Causes */
-	NM_NACK_RES_NOTIMPL		= 0x19,
-	NM_NACK_RES_NOTAVAIL		= 0x1a,
-	NM_NACK_FREQ_NOTAVAIL		= 0x1b,
-	NM_NACK_TEST_NOTSUPP		= 0x1c,
-	NM_NACK_CAPACITY_RESTR		= 0x1d,
-	NM_NACK_PHYSCFG_NOTPERFORM	= 0x1e,
-	NM_NACK_TEST_NOTINIT		= 0x1f,
-	NM_NACK_PHYSCFG_NOTRESTORE	= 0x20,
-	NM_NACK_TEST_NOSUCH		= 0x21,
-	NM_NACK_TEST_NOSTOP		= 0x22,
-	NM_NACK_MSGINCONSIST_PHYSCFG	= 0x23,
-	NM_NACK_FILE_INCOMPLETE		= 0x25,
-	NM_NACK_FILE_NOTAVAIL		= 0x26,
-	NM_NACK_FILE_NOTACTIVATE	= 0x27,
-	NM_NACK_REQ_NOT_GRANT		= 0x28,
-	NM_NACK_WAIT			= 0x29,
-	NM_NACK_NOTH_REPORT_EXIST	= 0x2a,
-	NM_NACK_MEAS_NOTSUPP		= 0x2b,
-	NM_NACK_MEAS_NOTSTART		= 0x2c,
-};
-
-/* Section 9.4.1 */
-struct abis_nm_channel {
-	u_int8_t	attrib;
-	u_int8_t	bts_port;
-	u_int8_t	timeslot;
-	u_int8_t	subslot;
-} __attribute__ ((packed));
-
-/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
-enum abis_bs11_objtype {
-	BS11_OBJ_ALCO		= 0x01,
-	BS11_OBJ_BBSIG		= 0x02,	/* obj_class: 0,1 */
-	BS11_OBJ_TRX1		= 0x03,	/* only DEACTIVATE TRX1 */
-	BS11_OBJ_CCLK		= 0x04,
-	BS11_OBJ_GPSU		= 0x06,
-	BS11_OBJ_LI		= 0x07,
-	BS11_OBJ_PA		= 0x09,	/* obj_class: 0, 1*/
-};
-
-enum abis_bs11_trx_power {
-	BS11_TRX_POWER_GSM_2W	= 0x06,
-	BS11_TRX_POWER_GSM_250mW= 0x07,
-	BS11_TRX_POWER_GSM_80mW	= 0x08,
-	BS11_TRX_POWER_GSM_30mW	= 0x09,
-	BS11_TRX_POWER_DCS_3W	= 0x0a,
-	BS11_TRX_POWER_DCS_1W6	= 0x0b,
-	BS11_TRX_POWER_DCS_500mW= 0x0c,
-	BS11_TRX_POWER_DCS_160mW= 0x0d,
-};
-
-enum abis_bs11_li_pll_mode {
-	BS11_LI_PLL_LOCKED	= 2,
-	BS11_LI_PLL_STANDALONE	= 3,
-};
-
-enum abis_bs11_line_cfg {
-	BS11_LINE_CFG_STAR	= 0x00,
-	BS11_LINE_CFG_MULTIDROP	= 0x01,
-	BS11_LINE_CFG_LOOP	= 0x02,
-};
-
-enum abis_bs11_phase {
-	BS11_STATE_SOFTWARE_RQD		= 0x01,
-	BS11_STATE_LOAD_SMU_INTENDED	= 0x11,
-	BS11_STATE_LOAD_SMU_SAFETY	= 0x21,
-	BS11_STATE_LOAD_FAILED		= 0x31,
-	BS11_STATE_LOAD_DIAGNOSTIC	= 0x41,
-	BS11_STATE_WARM_UP		= 0x51,
-	BS11_STATE_WARM_UP_2		= 0x52,
-	BS11_STATE_WAIT_MIN_CFG		= 0x62,
-	BS11_STATE_MAINTENANCE		= 0x72,
-	BS11_STATE_LOAD_MBCCU		= 0x92,
-	BS11_STATE_WAIT_MIN_CFG_2	= 0xA2,
-	BS11_STATE_NORMAL		= 0x03,
-	BS11_STATE_ABIS_LOAD		= 0x13,
-};
-
-enum abis_nm_ipacc_test_no {
-	NM_IPACC_TESTNO_RLOOP_ANT	= 0x01,
-	NM_IPACC_TESTNO_RLOOP_XCVR	= 0x02,
-	NM_IPACC_TESTNO_FUNC_OBJ	= 0x03,
-	NM_IPACC_TESTNO_CHAN_USAGE	= 0x40,
-	NM_IPACC_TESTNO_BCCH_CHAN_USAGE	= 0x41,
-	NM_IPACC_TESTNO_FREQ_SYNC	= 0x42,
-	NM_IPACC_TESTNO_BCCH_INFO	= 0x43,
-	NM_IPACC_TESTNO_TX_BEACON	= 0x44,
-	NM_IPACC_TESTNO_SYSINFO_MONITOR	= 0x45,
-	NM_IPACC_TESTNO_BCCCH_MONITOR	= 0x46,
-};
-
-/* first byte after length inside NM_ATT_TEST_REPORT */
-enum abis_nm_ipacc_test_res {
-	NM_IPACC_TESTRES_SUCCESS	= 0,
-	NM_IPACC_TESTRES_TIMEOUT	= 1,
-	NM_IPACC_TESTRES_NO_CHANS	= 2,
-	NM_IPACC_TESTRES_PARTIAL	= 3,
-	NM_IPACC_TESTRES_STOPPED	= 4,
-};
-
-/* internal IE inside NM_ATT_TEST_REPORT */
-enum abis_nm_ipacc_testres_ie {
-	NM_IPACC_TR_IE_FREQ_ERR_LIST	= 3,
-	NM_IPACC_TR_IE_CHAN_USAGE	= 4,
-	NM_IPACC_TR_IE_BCCH_INFO	= 6,
-	NM_IPACC_TR_IE_RESULT_DETAILS	= 8,
-	NM_IPACC_TR_IE_FREQ_ERR		= 18,
-};
-
-enum ipac_eie {
-	NM_IPAC_EIE_ARFCN_WHITE		= 0x01,
-	NM_IPAC_EIE_ARFCH_BLACK		= 0x02,
-	NM_IPAC_EIE_FREQ_ERR_LIST	= 0x03,
-	NM_IPAC_EIE_CHAN_USE_LIST	= 0x04,
-	NM_IPAC_EIE_BCCH_INFO_TYPE	= 0x05,
-	NM_IPAC_EIE_BCCH_INFO		= 0x06,
-	/* FIXME */
-};
-
-enum ipac_bcch_info_type {
-	IPAC_BINF_RXLEV			= (1 << 8),
-	IPAC_BINF_RXQUAL		= (1 << 9),
-	IPAC_BINF_FREQ_ERR_QUAL		= (1 << 10),
-	IPAC_BINF_FRAME_OFFSET		= (1 << 11),
-	IPAC_BINF_FRAME_NR_OFFSET	= (1 << 12),
-	IPAC_BINF_BSIC			= (1 << 13),
-	IPAC_BINF_CGI			= (1 << 14),
-	IPAC_BINF_NEIGH_BA_SI2		= (1 << 15),
-	IPAC_BINF_NEIGH_BA_SI2bis	= (1 << 0),
-	IPAC_BINF_NEIGH_BA_SI2ter	= (1 << 1),
-	IPAC_BINF_CELL_ALLOC		= (1 << 2),
-};
+#include <osmocore/tlv.h>
+#include <osmocore/protocol/gsm_12_21.h>
 
 struct cell_global_id {
 	u_int16_t mcc;
diff --git a/openbsc/include/openbsc/abis_rsl.h b/openbsc/include/openbsc/abis_rsl.h
index 797b2f3..b280184 100644
--- a/openbsc/include/openbsc/abis_rsl.h
+++ b/openbsc/include/openbsc/abis_rsl.h
@@ -23,468 +23,9 @@
 #ifndef _RSL_H
 #define _RSL_H
 
-struct abis_rsl_common_hdr {
-	u_int8_t	msg_discr;
-	u_int8_t	msg_type;
-	u_int8_t	data[0];
-} __attribute__ ((packed));
+#include <osmocore/protocol/gsm_08_58.h>
 
-/* Chapter 8.3 */
-struct abis_rsl_rll_hdr {
-	struct abis_rsl_common_hdr c;
-	u_int8_t	ie_chan;
-	u_int8_t	chan_nr;
-	u_int8_t	ie_link_id;
-	u_int8_t	link_id;
-	u_int8_t	data[0];
-} __attribute__ ((packed));
-
-/* Chapter 8.3 and 8.4 */
-struct abis_rsl_dchan_hdr {
-	struct abis_rsl_common_hdr c;
-	u_int8_t	ie_chan;
-	u_int8_t	chan_nr;
-	u_int8_t	data[0];
-} __attribute__ ((packed));
-
-
-/* Chapter 9.1 */
-#define ABIS_RSL_MDISC_RLL		0x02
-#define ABIS_RSL_MDISC_DED_CHAN		0x08
-#define ABIS_RSL_MDISC_COM_CHAN		0x0c
-#define ABIS_RSL_MDISC_TRX		0x10
-#define ABIS_RSL_MDISC_LOC		0x20
-#define ABIS_RSL_MDISC_IPACCESS		0x7e
-#define ABIS_RSL_MDISC_TRANSP		0x01
-
-#define ABIS_RSL_MDISC_IS_TRANSP(x)	(x & 0x01)
-
-/* Chapter 9.1 */
-enum abis_rsl_msgtype {
-	/* Radio Link Layer Management */
-	RSL_MT_DATA_REQ			= 0x01,
-	RSL_MT_DATA_IND,
-	RSL_MT_ERROR_IND,
-	RSL_MT_EST_REQ,
-	RSL_MT_EST_CONF,
-	RSL_MT_EST_IND,
-	RSL_MT_REL_REQ,
-	RSL_MT_REL_CONF,
-	RSL_MT_REL_IND,
-	RSL_MT_UNIT_DATA_REQ,
-	RSL_MT_UNIT_DATA_IND,		/* 0x0b */
-
-	/* Common Channel Management / TRX Management */
-	RSL_MT_BCCH_INFO			= 0x11,
-	RSL_MT_CCCH_LOAD_IND,
-	RSL_MT_CHAN_RQD,
-	RSL_MT_DELETE_IND,
-	RSL_MT_PAGING_CMD,
-	RSL_MT_IMMEDIATE_ASSIGN_CMD,
-	RSL_MT_SMS_BC_REQ,
-	/* empty */
-	RSL_MT_RF_RES_IND			= 0x19,
-	RSL_MT_SACCH_FILL,
-	RSL_MT_OVERLOAD,
-	RSL_MT_ERROR_REPORT,
-	RSL_MT_SMS_BC_CMD,
-	RSL_MT_CBCH_LOAD_IND,
-	RSL_MT_NOT_CMD,			/* 0x1f */
-
-	/* Dedicate Channel Management */
-	RSL_MT_CHAN_ACTIV			= 0x21,
-	RSL_MT_CHAN_ACTIV_ACK,
-	RSL_MT_CHAN_ACTIV_NACK,
-	RSL_MT_CONN_FAIL,
-	RSL_MT_DEACTIVATE_SACCH,
-	RSL_MT_ENCR_CMD,
-	RSL_MT_HANDO_DET,
-	RSL_MT_MEAS_RES,
-	RSL_MT_MODE_MODIFY_REQ,
-	RSL_MT_MODE_MODIFY_ACK,
-	RSL_MT_MODE_MODIFY_NACK,
-	RSL_MT_PHY_CONTEXT_REQ,
-	RSL_MT_PHY_CONTEXT_CONF,
-	RSL_MT_RF_CHAN_REL,
-	RSL_MT_MS_POWER_CONTROL,
-	RSL_MT_BS_POWER_CONTROL,		/* 0x30 */
-	RSL_MT_PREPROC_CONFIG,
-	RSL_MT_PREPROC_MEAS_RES,
-	RSL_MT_RF_CHAN_REL_ACK,
-	RSL_MT_SACCH_INFO_MODIFY,
-	RSL_MT_TALKER_DET,
-	RSL_MT_LISTENER_DET,
-	RSL_MT_REMOTE_CODEC_CONF_REP,
-	RSL_MT_RTD_REP,
-	RSL_MT_PRE_HANDO_NOTIF,
-	RSL_MT_MR_CODEC_MOD_REQ,
-	RSL_MT_MR_CODEC_MOD_ACK,
-	RSL_MT_MR_CODEC_MOD_NACK,
-	RSL_MT_MR_CODEC_MOD_PER,
-	RSL_MT_TFO_REP,
-	RSL_MT_TFO_MOD_REQ,		/* 0x3f */
-	RSL_MT_LOCATION_INFO		= 0x41,
-
-	/* ip.access specific RSL message types */
-	RSL_MT_IPAC_DIR_RETR_ENQ	= 0x40,
-	RSL_MT_IPAC_PDCH_ACT		= 0x48,
-	RSL_MT_IPAC_PDCH_ACT_ACK,
-	RSL_MT_IPAC_PDCH_ACT_NACK,
-	RSL_MT_IPAC_PDCH_DEACT		= 0x4b,
-	RSL_MT_IPAC_PDCH_DEACT_ACK,
-	RSL_MT_IPAC_PDCH_DEACT_NACK,
-	RSL_MT_IPAC_CONNECT_MUX		= 0x50,
-	RSL_MT_IPAC_CONNECT_MUX_ACK,
-	RSL_MT_IPAC_CONNECT_MUX_NACK,
-	RSL_MT_IPAC_BIND_MUX		= 0x53,
-	RSL_MT_IPAC_BIND_MUX_ACK,
-	RSL_MT_IPAC_BIND_MUX_NACK,
-	RSL_MT_IPAC_DISC_MUX		= 0x56,
-	RSL_MT_IPAC_DISC_MUX_ACK,
-	RSL_MT_IPAC_DISC_MUX_NACK,
-	RSL_MT_IPAC_CRCX		= 0x70,		/* Bind to local BTS RTP port */
-	RSL_MT_IPAC_CRCX_ACK,
-	RSL_MT_IPAC_CRCX_NACK,
-	RSL_MT_IPAC_MDCX		= 0x73,
-	RSL_MT_IPAC_MDCX_ACK,
-	RSL_MT_IPAC_MDCX_NACK,
-	RSL_MT_IPAC_DLCX_IND		= 0x76,
-	RSL_MT_IPAC_DLCX		= 0x77,
-	RSL_MT_IPAC_DLCX_ACK,
-	RSL_MT_IPAC_DLCX_NACK,
-};
-
-/* Siemens vendor-specific */
-enum abis_rsl_msgtype_siemens {
-	RSL_MT_SIEMENS_MRPCI		= 0x41,
-	RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42,
-	RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43,
-	RSL_MT_SIEMENS_FORCED_HO_REQ	= 0x44,
-	RSL_MT_SIEMENS_PREF_AREA_REQ	= 0x45,
-	RSL_MT_SIEMENS_PREF_AREA	= 0x46,
-	RSL_MT_SIEMENS_START_TRACE	= 0x47,
-	RSL_MT_SIEMENS_START_TRACE_ACK	= 0x48,
-	RSL_MT_SIEMENS_STOP_TRACE	= 0x49,
-	RSL_MT_SIEMENS_TRMR		= 0x4a,
-	RSL_MT_SIEMENS_HO_FAIL_IND	= 0x4b,
-	RSL_MT_SIEMENS_STOP_TRACE_ACK	= 0x4c,
-	RSL_MT_SIEMENS_UPLF		= 0x4d,
-	RSL_MT_SIEMENS_UPLB		= 0x4e,
-	RSL_MT_SIEMENS_SET_SYS_INFO_10	= 0x4f,
-	RSL_MT_SIEMENS_MODIF_COND_IND	= 0x50,
-};
-
-/* Chapter 9.3 */
-enum abis_rsl_ie {
-	RSL_IE_CHAN_NR			= 0x01,
-	RSL_IE_LINK_IDENT,
-	RSL_IE_ACT_TYPE,
-	RSL_IE_BS_POWER,
-	RSL_IE_CHAN_IDENT,
-	RSL_IE_CHAN_MODE,
-	RSL_IE_ENCR_INFO,
-	RSL_IE_FRAME_NUMBER,
-	RSL_IE_HANDO_REF,
-	RSL_IE_L1_INFO,
-	RSL_IE_L3_INFO,
-	RSL_IE_MS_IDENTITY,
-	RSL_IE_MS_POWER,
-	RSL_IE_PAGING_GROUP,
-	RSL_IE_PAGING_LOAD,
-	RSL_IE_PYHS_CONTEXT		= 0x10,
-	RSL_IE_ACCESS_DELAY,
-	RSL_IE_RACH_LOAD,
-	RSL_IE_REQ_REFERENCE,
-	RSL_IE_RELEASE_MODE,
-	RSL_IE_RESOURCE_INFO,
-	RSL_IE_RLM_CAUSE,
-	RSL_IE_STARTNG_TIME,
-	RSL_IE_TIMING_ADVANCE,
-	RSL_IE_UPLINK_MEAS,
-	RSL_IE_CAUSE,
-	RSL_IE_MEAS_RES_NR,
-	RSL_IE_MSG_ID,
-	/* reserved */
-	RSL_IE_SYSINFO_TYPE		= 0x1e,
-	RSL_IE_MS_POWER_PARAM,
-	RSL_IE_BS_POWER_PARAM,
-	RSL_IE_PREPROC_PARAM,
-	RSL_IE_PREPROC_MEAS,
-	RSL_IE_IMM_ASS_INFO,		/* Phase 1 (3.6.0), later Full below */
-	RSL_IE_SMSCB_INFO		= 0x24,
-	RSL_IE_MS_TIMING_OFFSET,
-	RSL_IE_ERR_MSG,
-	RSL_IE_FULL_BCCH_INFO,
-	RSL_IE_CHAN_NEEDED,
-	RSL_IE_CB_CMD_TYPE,
-	RSL_IE_SMSCB_MSG,
-	RSL_IE_FULL_IMM_ASS_INFO,
-	RSL_IE_SACCH_INFO,
-	RSL_IE_CBCH_LOAD_INFO,
-	RSL_IE_SMSCB_CHAN_INDICATOR,
-	RSL_IE_GROUP_CALL_REF,
-	RSL_IE_CHAN_DESC		= 0x30,
-	RSL_IE_NCH_DRX_INFO,
-	RSL_IE_CMD_INDICATOR,
-	RSL_IE_EMLPP_PRIO,
-	RSL_IE_UIC,
-	RSL_IE_MAIN_CHAN_REF,
-	RSL_IE_MR_CONFIG,
-	RSL_IE_MR_CONTROL,
-	RSL_IE_SUP_CODEC_TYPES,
-	RSL_IE_CODEC_CONFIG,
-	RSL_IE_RTD,
-	RSL_IE_TFO_STATUS,
-	RSL_IE_LLP_APDU,
-	/* Siemens vendor-specific */
-	RSL_IE_SIEMENS_MRPCI		= 0x40,
-	RSL_IE_SIEMENS_PREF_AREA_TYPE	= 0x43,
-	RSL_IE_SIEMENS_ININ_CELL_HO_PAR	= 0x45,
-	RSL_IE_SIEMENS_TRACE_REF_NR	= 0x46,
-	RSL_IE_SIEMENS_INT_TRACE_IDX	= 0x47,
-	RSL_IE_SIEMENS_L2_HDR_INFO	= 0x48,
-	RSL_IE_SIEMENS_HIGHEST_RATE	= 0x4e,
-	RSL_IE_SIEMENS_SUGGESTED_RATE	= 0x4f,
-
-	/* ip.access */
-	RSL_IE_IPAC_SRTP_CONFIG	= 0xe0,
-	RSL_IE_IPAC_PROXY_UDP	= 0xe1,
-	RSL_IE_IPAC_BSCMPL_TOUT	= 0xe2,
-	RSL_IE_IPAC_REMOTE_IP	= 0xf0,
-	RSL_IE_IPAC_REMOTE_PORT	= 0xf1,
-	RSL_IE_IPAC_RTP_PAYLOAD	= 0xf2,
-	RSL_IE_IPAC_LOCAL_PORT	= 0xf3,
-	RSL_IE_IPAC_SPEECH_MODE	= 0xf4,
-	RSL_IE_IPAC_LOCAL_IP	= 0xf5,
-	RSL_IE_IPAC_CONN_STAT	= 0xf6,
-	RSL_IE_IPAC_HO_C_PARMS	= 0xf7,
-	RSL_IE_IPAC_CONN_ID	= 0xf8,
-	RSL_IE_IPAC_RTP_CSD_FMT	= 0xf9,
-	RSL_IE_IPAC_RTP_JIT_BUF	= 0xfa,
-	RSL_IE_IPAC_RTP_COMPR	= 0xfb,
-	RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc,
-	RSL_IE_IPAC_RTP_MPLEX	= 0xfd,
-	RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe,
-};
-
-/* Chapter 9.3.1 */
-#define RSL_CHAN_NR_MASK	0xf8
-#define RSL_CHAN_Bm_ACCHs	0x08
-#define RSL_CHAN_Lm_ACCHs	0x10	/* .. 0x18 */
-#define RSL_CHAN_SDCCH4_ACCH	0x20	/* .. 0x38 */
-#define RSL_CHAN_SDCCH8_ACCH	0x40	/* ...0x78 */
-#define RSL_CHAN_BCCH		0x80
-#define RSL_CHAN_RACH		0x88
-#define RSL_CHAN_PCH_AGCH	0x90
-
-/* Chapter 9.3.3 */
-#define RSL_ACT_TYPE_INITIAL	0x00
-#define RSL_ACT_TYPE_REACT	0x80
-#define RSL_ACT_INTRA_IMM_ASS	0x00
-#define RSL_ACT_INTRA_NORM_ASS	0x01
-#define RSL_ACT_INTER_ASYNC	0x02
-#define RSL_ACT_INTER_SYNC	0x03
-#define RSL_ACT_SECOND_ADD	0x04
-#define RSL_ACT_SECOND_MULTI	0x05
-
-/* Chapter 9.3.6 */
-struct rsl_ie_chan_mode {
-	u_int8_t dtx_dtu;
-	u_int8_t spd_ind;
-	u_int8_t chan_rt;
-	u_int8_t chan_rate;
-} __attribute__ ((packed));
-#define RSL_CMOD_DTXu		0x01	/* uplink */
-#define RSL_CMOD_DTXd		0x02	/* downlink */
-enum rsl_cmod_spd {
-	RSL_CMOD_SPD_SPEECH	= 0x01,
-	RSL_CMOD_SPD_DATA	= 0x02,
-	RSL_CMOD_SPD_SIGN	= 0x03,
-};
-#define RSL_CMOD_CRT_SDCCH	0x01
-#define RSL_CMOD_CRT_TCH_Bm	0x08	/* full-rate */
-#define RSL_CMOD_CRT_TCH_Lm	0x09	/* half-rate */
-/* FIXME: More CRT types */
-/* Speech */
-#define RSL_CMOD_SP_GSM1	0x01
-#define RSL_CMOD_SP_GSM2	0x11
-#define RSL_CMOD_SP_GSM3	0x21
-/* Data */
-#define RSL_CMOD_SP_NT_14k5	0x58
-#define RSL_CMOD_SP_NT_12k0	0x50
-#define RSL_CMOD_SP_NT_6k0	0x51
-
-/* Chapter 9.3.5 */
-struct rsl_ie_chan_ident {
-	/* GSM 04.08 10.5.2.5 */
-	struct {
-		u_int8_t iei;
-		u_int8_t chan_nr;	/* enc_chan_nr */
-		u_int8_t oct3;
-		u_int8_t oct4;
-	} chan_desc;
-#if 0	/* spec says we need this but Abissim doesn't use it */
-	struct {
-		u_int8_t tag;
-		u_int8_t len;
-	} mobile_alloc;
-#endif
-} __attribute__ ((packed));
-
-/* Chapter 9.3.22 */
-#define RLL_CAUSE_T200_EXPIRED		0x01
-#define RLL_CAUSE_REEST_REQ		0x02
-#define RLL_CAUSE_UNSOL_UA_RESP		0x03
-#define RLL_CAUSE_UNSOL_DM_RESP		0x04
-#define RLL_CAUSE_UNSOL_DM_RESP_MF	0x05
-#define RLL_CAUSE_UNSOL_SPRV_RESP	0x06
-#define RLL_CAUSE_SEQ_ERR		0x07
-#define RLL_CAUSE_UFRM_INC_PARAM	0x08
-#define RLL_CAUSE_SFRM_INC_PARAM	0x09
-#define RLL_CAUSE_IFRM_INC_MBITS	0x0a
-#define RLL_CAUSE_IFRM_INC_LEN		0x0b
-#define RLL_CAUSE_FRM_UNIMPL		0x0c
-#define RLL_CAUSE_SABM_MF		0x0d
-#define RLL_CAUSE_SABM_INFO_NOTALL	0x0e
-
-/* Chapter 9.3.26 */
-#define RSL_ERRCLS_NORMAL		0x00
-#define RSL_ERRCLS_RESOURCE_UNAVAIL	0x20
-#define RSL_ERRCLS_SERVICE_UNAVAIL	0x30
-#define RSL_ERRCLS_SERVICE_UNIMPL	0x40
-#define RSL_ERRCLS_INVAL_MSG		0x50
-#define RSL_ERRCLS_PROTO_ERROR		0x60
-#define RSL_ERRCLS_INTERWORKING		0x70
-
-/* normal event */
-#define RSL_ERR_RADIO_IF_FAIL		0x00
-#define RSL_ERR_RADIO_LINK_FAIL		0x01
-#define RSL_ERR_HANDOVER_ACC_FAIL	0x02
-#define RSL_ERR_TALKER_ACC_FAIL		0x03
-#define RSL_ERR_OM_INTERVENTION		0x07
-#define RSL_ERR_NORMAL_UNSPEC		0x0f
-#define RSL_ERR_T_MSRFPCI_EXP		0x18
-/* resource unavailable */
-#define RSL_ERR_EQUIPMENT_FAIL		0x20
-#define RSL_ERR_RR_UNAVAIL		0x21
-#define RSL_ERR_TERR_CH_FAIL		0x22
-#define RSL_ERR_CCCH_OVERLOAD		0x23
-#define RSL_ERR_ACCH_OVERLOAD		0x24
-#define RSL_ERR_PROCESSOR_OVERLOAD	0x25
-#define RSL_ERR_RES_UNAVAIL		0x2f
-/* service or option not available */
-#define RSL_ERR_TRANSC_UNAVAIL		0x30
-#define RSL_ERR_SERV_OPT_UNAVAIL	0x3f
-/* service or option not implemented */
-#define RSL_ERR_ENCR_UNIMPL		0x40
-#define RSL_ERR_SERV_OPT_UNIMPL		0x4f
-/* invalid message */
-#define RSL_ERR_RCH_ALR_ACTV_ALLOC	0x50
-#define RSL_ERR_INVALID_MESSAGE		0x5f
-/* protocol error */
-#define RSL_ERR_MSG_DISCR		0x60
-#define RSL_ERR_MSG_TYPE		0x61
-#define RSL_ERR_MSG_SEQ			0x62
-#define RSL_ERR_IE_ERROR		0x63
-#define RSL_ERR_MAND_IE_ERROR		0x64
-#define RSL_ERR_OPT_IE_ERROR		0x65
-#define RSL_ERR_IE_NONEXIST		0x66
-#define RSL_ERR_IE_LENGTH		0x67
-#define RSL_ERR_IE_CONTENT		0x68
-#define RSL_ERR_PROTO			0x6f
-/* interworking */
-#define RSL_ERR_INTERWORKING		0x7f
-
-/* Chapter 9.3.30 */
-#define RSL_SYSTEM_INFO_8	0x00
-#define RSL_SYSTEM_INFO_1	0x01
-#define RSL_SYSTEM_INFO_2	0x02
-#define RSL_SYSTEM_INFO_3	0x03
-#define RSL_SYSTEM_INFO_4	0x04
-#define RSL_SYSTEM_INFO_5	0x05
-#define RSL_SYSTEM_INFO_6	0x06
-#define RSL_SYSTEM_INFO_7	0x07
-#define RSL_SYSTEM_INFO_16	0x08
-#define RSL_SYSTEM_INFO_17	0x09
-#define RSL_SYSTEM_INFO_2bis	0x0a
-#define RSL_SYSTEM_INFO_2ter	0x0b
-#define RSL_SYSTEM_INFO_5bis	0x0d
-#define RSL_SYSTEM_INFO_5ter	0x0e
-#define RSL_SYSTEM_INFO_10	0x0f
-#define REL_EXT_MEAS_ORDER	0x47
-#define RSL_MEAS_INFO		0x48
-#define RSL_SYSTEM_INFO_13	0x28
-#define RSL_SYSTEM_INFO_2quater	0x29
-#define RSL_SYSTEM_INFO_9	0x2a
-#define RSL_SYSTEM_INFO_18	0x2b
-#define RSL_SYSTEM_INFO_19	0x2c
-#define RSL_SYSTEM_INFO_20	0x2d
-
-/* Chapter 9.3.40 */
-#define RSL_CHANNEED_ANY	0x00
-#define RSL_CHANNEED_SDCCH	0x01
-#define RSL_CHANNEED_TCH_F	0x02
-#define RSL_CHANNEED_TCH_ForH	0x03
-
-/* Chapter 3.3.2.3 Brocast control channel */
-/* CCCH-CONF, NC is not combined */
-#define RSL_BCCH_CCCH_CONF_1_NC	0x00
-#define RSL_BCCH_CCCH_CONF_1_C	0x01
-#define RSL_BCCH_CCCH_CONF_2_NC	0x02
-#define RSL_BCCH_CCCH_CONF_3_NC	0x04
-#define RSL_BCCH_CCCH_CONF_4_NC	0x06
-
-/* BS-PA-MFRMS */
-#define RSL_BS_PA_MFRMS_2	0x00
-#define RSL_BS_PA_MFRMS_3	0x01
-#define RSL_BS_PA_MFRMS_4	0x02
-#define RSL_BS_PA_MFRMS_5	0x03
-#define RSL_BS_PA_MFRMS_6	0x04
-#define RSL_BS_PA_MFRMS_7	0x05
-#define RSL_BS_PA_MFRMS_8	0x06
-#define RSL_BS_PA_MFRMS_9	0x07
-
-/* RSL_IE_IPAC_RTP_PAYLOAD[2] */
-enum rsl_ipac_rtp_payload {
-	RSL_IPAC_RTP_GSM	= 1,
-	RSL_IPAC_RTP_EFR,
-	RSL_IPAC_RTP_AMR,
-	RSL_IPAC_RTP_CSD,
-	RSL_IPAC_RTP_MUX,
-};
-
-/* RSL_IE_IPAC_SPEECH_MODE, lower four bits */
-enum rsl_ipac_speech_mode_s {
-	RSL_IPAC_SPEECH_GSM_FR = 0,	/* GSM FR (Type 1, FS) */
-	RSL_IPAC_SPEECH_GSM_EFR = 1,	/* GSM EFR (Type 2, FS) */
-	RSL_IPAC_SPEECH_GSM_AMR_FR = 2,	/* GSM AMR/FR (Type 3, FS) */
-	RSL_IPAC_SPEECH_GSM_HR = 3,	/* GSM HR (Type 1, HS) */
-	RSL_IPAC_SPEECH_GSM_AMR_HR = 5,	/* GSM AMR/hr (Type 3, HS) */
-	RSL_IPAC_SPEECH_AS_RTP = 0xf,	/* As specified by RTP Payload IE */
-};
-/* RSL_IE_IPAC_SPEECH_MODE, upper four bits */
-enum rsl_ipac_speech_mode_m {
-	RSL_IPAC_SPEECH_M_RXTX = 0,	/* Send and Receive */
-	RSL_IPAC_SPEECH_M_RX = 1,	/* Receive only */
-	RSL_IPAC_SPEECH_M_TX = 2,	/* Send only */
-};
-
-/* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */
-enum rsl_ipac_rtp_csd_format_d {
-	RSL_IPAC_RTP_CSD_EXT_TRAU = 0,
-	RSL_IPAC_RTP_CSD_NON_TRAU = 1,
-	RSL_IPAC_RTP_CSD_TRAU_BTS = 2,
-	RSL_IPAC_RTP_CSD_IWF_FREE = 3,
-};
-/* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */
-enum rsl_ipac_rtp_csd_format_ir {
-	RSL_IPAC_RTP_CSD_IR_8k = 0,
-	RSL_IPAC_RTP_CSD_IR_16k = 1,
-	RSL_IPAC_RTP_CSD_IR_32k = 2,
-	RSL_IPAC_RTP_CSD_IR_64k = 3,
-};
-
-#include "msgb.h"
+#include <osmocore/msgb.h>
 
 int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
 		  const u_int8_t *data, int len);
@@ -511,27 +52,6 @@
 int rsl_relase_request(struct gsm_lchan *lchan, u_int8_t link_id);
 
 /* Siemens vendor-specific RSL extensions */
-struct rsl_mrpci {
-	u_int8_t power_class:3,
-		 vgcs_capable:1,
-		 vbs_capable:1,
-		 gsm_phase:2;
-} __attribute__ ((packed));
-
-enum rsl_mrpci_pwrclass {
-	RSL_MRPCI_PWRC_1	= 0,
-	RSL_MRPCI_PWRC_2	= 1,
-	RSL_MRPCI_PWRC_3	= 2,
-	RSL_MRPCI_PWRC_4	= 3,
-	RSL_MRPCI_PWRC_5	= 4,
-};
-enum rsl_mrpci_phase {
-	RSL_MRPCI_PHASE_1	= 0,
-	/* reserved */
-	RSL_MRPCI_PHASE_2	= 2,
-	RSL_MRPCI_PHASE_2PLUS	= 3,
-};
-
 int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
 
 /* ip.access specfic RSL extensions */
diff --git a/openbsc/include/openbsc/bitvec.h b/openbsc/include/openbsc/bitvec.h
deleted file mode 100644
index b35aebf..0000000
--- a/openbsc/include/openbsc/bitvec.h
+++ /dev/null
@@ -1,65 +0,0 @@
-#ifndef _BITVEC_H
-#define _BITVEC_H
-
-/* bit vector utility routines */
-
-/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-/* In GSM mac blocks, every bit can be 0 or 1, or L or H.  L/H are
- * defined relative to the 0x2b padding pattern */
-enum bit_value {
-	ZERO	= 0,
-	ONE	= 1,
-	L	= 2,
-	H	= 3,
-};
-
-struct bitvec {
-	unsigned int cur_bit;	/* curser to the next unused bit */
-	unsigned int data_len;	/* length of data array in bytes */
-	u_int8_t *data;		/* pointer to data array */
-};
-
-/* check if the bit is 0 or 1 for a given position inside a bitvec */
-enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr);
-
-/* get the Nth set bit inside the bit vector */
-unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n);
-
-/* Set a bit at given position */
-int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
-			enum bit_value bit);
-
-/* Set the next bit in the vector */
-int bitvec_set_bit(struct bitvec *bv, enum bit_value bit);
-
-/* Set multiple bits at the current position */
-int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count);
-
-/* Add an unsigned integer (of length count bits) to current position */
-int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count);
-
-
-/* Pad the bit vector up to a certain bit position */
-int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit);
-
-#endif /* _BITVEC_H */
diff --git a/openbsc/include/openbsc/comp128.h b/openbsc/include/openbsc/comp128.h
deleted file mode 100644
index 691ade5..0000000
--- a/openbsc/include/openbsc/comp128.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * COMP128 header
- *
- * See comp128.c for details
- */
-
-#ifndef __COMP128_H__
-#define __COMP128_H__
-
-#include <sys/types.h>
-
-/*
- * Performs the COMP128 algorithm (used as A3/A8)
- * ki    : u_int8_t [16]
- * srand : u_int8_t [16]
- * sres  : u_int8_t [4]
- * kc    : u_int8_t [8]
- */
-void comp128(u_int8_t *ki, u_int8_t *srand, u_int8_t *sres, u_int8_t *kc);
-
-#endif /* __COMP128_H__ */
-
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index c40eec3..4b67c61 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -2,7 +2,7 @@
 #define _DEBUG_H
 
 #include <stdio.h>
-#include "linuxlist.h"
+#include <osmocore/linuxlist.h>
 
 #define DEBUG
 
diff --git a/openbsc/include/openbsc/e1_input.h b/openbsc/include/openbsc/e1_input.h
index 64e0b4f..1a3d9d6 100644
--- a/openbsc/include/openbsc/e1_input.h
+++ b/openbsc/include/openbsc/e1_input.h
@@ -4,10 +4,10 @@
 #include <stdlib.h>
 #include <netinet/in.h>
 
-#include <openbsc/linuxlist.h>
+#include <osmocore/linuxlist.h>
 #include <openbsc/gsm_data.h>
-#include <openbsc/msgb.h>
-#include <openbsc/select.h>
+#include <osmocore/msgb.h>
+#include <osmocore/select.h>
 #include <openbsc/subchan_demux.h>
 
 #define NUM_E1_TS   32
diff --git a/openbsc/include/openbsc/gsm_04_08.h b/openbsc/include/openbsc/gsm_04_08.h
index 826ea5e..ed688c2 100644
--- a/openbsc/include/openbsc/gsm_04_08.h
+++ b/openbsc/include/openbsc/gsm_04_08.h
@@ -3,742 +3,7 @@
 
 #include <openbsc/meas_rep.h>
 
-/* GSM TS 04.08  definitions */
-struct gsm_lchan;
-
-struct gsm48_classmark1 {
-	u_int8_t spare:1,
-		 rev_level:2,
-		 es_ind:1,
-		 a5_1:1,
-		 pwr_lev:3;
-} __attribute__ ((packed));
-
-/* Chapter 10.5.2.5 */
-struct gsm48_chan_desc {
-	u_int8_t chan_nr;
-	union {
-		struct {
-			u_int8_t maio_high:4,
-				 h:1,
-				 tsc:3;
-			u_int8_t hsn:6,
-				 maio_low:2;
-		} h1;
-		struct {
-			u_int8_t arfcn_high:2,
-				 spare:2,
-				 h:1,
-				 tsc:3;
-			u_int8_t arfcn_low;
-		} h0;
-	};
-} __attribute__ ((packed));
-
-/* Chapter 10.5.2.21aa */
-struct gsm48_multi_rate_conf {
-	u_int8_t smod : 2,
-		 spare: 1,
-		 icmi : 1,
-		 nscb : 1,
-		 ver : 3;
-	u_int8_t m4_75 : 1,
-		 m5_15 : 1,
-		 m5_90 : 1,
-		 m6_70 : 1,
-		 m7_40 : 1,
-		 m7_95 : 1,
-		 m10_2 : 1,
-		 m12_2 : 1;
-} __attribute__((packed));
-
-/* Chapter 10.5.2.30 */
-struct gsm48_req_ref {
-	u_int8_t ra;
-	u_int8_t t3_high:3,
-		 t1_:5;
-	u_int8_t t2:5,
-		 t3_low:3;
-} __attribute__ ((packed));
-
-/*
- * Chapter 9.1.5/9.1.6
- *
- * For 9.1.6 the chan_desc has the meaning of 10.5.2.5a
- */
-struct gsm48_chan_mode_modify {
-	struct gsm48_chan_desc chan_desc;
-	u_int8_t mode;
-} __attribute__ ((packed));
-
-enum gsm48_chan_mode {
-	GSM48_CMODE_SIGN	= 0x00,
-	GSM48_CMODE_SPEECH_V1	= 0x01,
-	GSM48_CMODE_SPEECH_EFR	= 0x21,
-	GSM48_CMODE_SPEECH_AMR	= 0x41,
-	GSM48_CMODE_DATA_14k5	= 0x0f,
-	GSM48_CMODE_DATA_12k0	= 0x03,
-	GSM48_CMODE_DATA_6k0	= 0x0b,
-	GSM48_CMODE_DATA_3k6	= 0x23,
-};
-
-/* Chapter 9.1.2 */
-struct gsm48_ass_cmd {
-	/* Semantic is from 10.5.2.5a */
-	struct gsm48_chan_desc chan_desc;
-	u_int8_t power_command;
-	u_int8_t data[0];
-} __attribute__((packed));
-
-/* Chapter 10.5.2.2 */
-struct gsm48_cell_desc {
-	u_int8_t bcc:3,
-		 ncc:3,
-		 arfcn_hi:2;
-	u_int8_t arfcn_lo;
-} __attribute__((packed));
-
-/* Chapter 9.1.15 */
-struct gsm48_ho_cmd {
-	struct gsm48_cell_desc cell_desc;
-	struct gsm48_chan_desc chan_desc;
-	u_int8_t ho_ref;
-	u_int8_t power_command;
-	u_int8_t data[0];
-} __attribute__((packed));
-
-/* Chapter 9.1.18 */
-struct gsm48_imm_ass {
-	u_int8_t l2_plen;
-	u_int8_t proto_discr;
-	u_int8_t msg_type;
-	u_int8_t page_mode;
-	struct gsm48_chan_desc chan_desc;
-	struct gsm48_req_ref req_ref;
-	u_int8_t timing_advance;
-	u_int8_t mob_alloc_len;
-	u_int8_t mob_alloc[0];
-} __attribute__ ((packed));
-
-/* Chapter 10.5.1.3 */
-struct gsm48_loc_area_id {
-	u_int8_t digits[3];	/* BCD! */
-	u_int16_t lac;
-} __attribute__ ((packed));
-
-/* Section 9.2.2 */
-struct gsm48_auth_req {
-	u_int8_t key_seq:4,
-	         spare:4;
-	u_int8_t rand[16];
-} __attribute__ ((packed));
-
-/* Section 9.2.15 */
-struct gsm48_loc_upd_req {
-	u_int8_t type:4,
-		 key_seq:4;
-	struct gsm48_loc_area_id lai;
-	struct gsm48_classmark1 classmark1;
-	u_int8_t mi_len;
-	u_int8_t mi[0];
-} __attribute__ ((packed));
-
-/* Section 10.1 */
-struct gsm48_hdr {
-	u_int8_t proto_discr;
-	u_int8_t msg_type;
-	u_int8_t data[0];
-} __attribute__ ((packed));
-
-/* Section 9.1.3x System information Type header */
-struct gsm48_system_information_type_header {
-	u_int8_t l2_plen;
-	u_int8_t rr_protocol_discriminator :4,
-		skip_indicator:4; 
-	u_int8_t system_information;
-} __attribute__ ((packed));
-
-struct gsm48_rach_control {
-	u_int8_t re :1,
-		 cell_bar :1,
-		 tx_integer :4,
-		 max_trans :2;
-	u_int8_t t2;
-	u_int8_t t3;
-} __attribute__ ((packed));
-
-/* Section 10.5.2.4 Cell Selection Parameters */
-struct gsm48_cell_sel_par {
-	u_int8_t ms_txpwr_max_ccch:5,	/* GSM 05.08 MS-TXPWR-MAX-CCCH */
-		 cell_resel_hyst:3;	/* GSM 05.08 CELL-RESELECT-HYSTERESIS */
-	u_int8_t rxlev_acc_min:6,	/* GSM 05.08 RXLEV-ACCESS-MIN */
-		 neci:1,
-		 acs:1;
-} __attribute__ ((packed));
-
-/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */
-struct gsm48_control_channel_descr {
-	u_int8_t ccch_conf :3,
-		bs_ag_blks_res :3,
-		att :1,
-		spare1 :1;
-	u_int8_t bs_pa_mfrms : 3,
-		spare2 :5;
-	u_int8_t t3212;
-} __attribute__ ((packed));
-
-struct gsm48_cell_options {
-	u_int8_t radio_link_timeout:4,
-		 dtx:2,
-		 pwrc:1,
-		 spare:1;
-} __attribute__ ((packed));
-
-/* Section 9.2.9 CM service request */
-struct gsm48_service_request {
-	u_int8_t cm_service_type : 4,
-		 cipher_key_seq  : 4;
-	/* length + 3 bytes */
-	u_int32_t classmark;
-	u_int8_t mi_len;
-	u_int8_t mi[0];
-	/* optional priority level */
-} __attribute__ ((packed));
-
-/* Section 9.1.31 System information Type 1 */
-struct gsm48_system_information_type_1 {
-	struct gsm48_system_information_type_header header;
-	u_int8_t cell_channel_description[16];
-	struct gsm48_rach_control rach_control;
-	u_int8_t rest_octets[0]; /* NCH position on the CCCH */
-} __attribute__ ((packed));
-
-/* Section 9.1.32 System information Type 2 */
-struct gsm48_system_information_type_2 {
-	struct gsm48_system_information_type_header header;
-	u_int8_t bcch_frequency_list[16];
-	u_int8_t ncc_permitted;
-	struct gsm48_rach_control rach_control;
-} __attribute__ ((packed));
-
-/* Section 9.1.35 System information Type 3 */
-struct gsm48_system_information_type_3 {
-	struct gsm48_system_information_type_header header;
-	u_int16_t cell_identity;
-	struct gsm48_loc_area_id lai;
-	struct gsm48_control_channel_descr control_channel_desc;
-	struct gsm48_cell_options cell_options;
-	struct gsm48_cell_sel_par cell_sel_par;
-	struct gsm48_rach_control rach_control;
-	u_int8_t rest_octets[0];
-} __attribute__ ((packed));
-
-/* Section 9.1.36 System information Type 4 */
-struct gsm48_system_information_type_4 {
-	struct gsm48_system_information_type_header header;
-	struct gsm48_loc_area_id lai;
-	struct gsm48_cell_sel_par cell_sel_par;
-	struct gsm48_rach_control rach_control;
-	/*	optional CBCH conditional CBCH... followed by
-		mandantory SI 4 Reset Octets
-	 */
-	u_int8_t data[0];
-} __attribute__ ((packed));
-
-/* Section 9.1.37 System information Type 5 */
-struct gsm48_system_information_type_5 {
-	u_int8_t rr_protocol_discriminator :4,
-		skip_indicator:4; 
-	u_int8_t system_information;
-	u_int8_t bcch_frequency_list[16];
-} __attribute__ ((packed));
-
-/* Section 9.1.40 System information Type 6 */
-struct gsm48_system_information_type_6 {
-	u_int8_t rr_protocol_discriminator :4,
-		skip_indicator:4; 
-	u_int8_t system_information;
-	u_int16_t cell_identity;
-	struct gsm48_loc_area_id lai;
-	struct gsm48_cell_options cell_options;
-	u_int8_t ncc_permitted;
-	u_int8_t rest_octets[0];
-} __attribute__ ((packed));
-
-/* Section 9.1.43a System Information type 13 */
-struct gsm48_system_information_type_13 {
-	struct gsm48_system_information_type_header header;
-	u_int8_t rest_octets[0];
-} __attribute__ ((packed));
-
-/* Section 9.2.12 IMSI Detach Indication */
-struct gsm48_imsi_detach_ind {
-	struct gsm48_classmark1 classmark1;
-	u_int8_t mi_len;
-	u_int8_t mi[0];
-} __attribute__ ((packed));
-
-/* Section 10.2 + GSM 04.07 12.2.3.1.1 */
-#define GSM48_PDISC_GROUP_CC	0x00
-#define GSM48_PDISC_BCAST_CC	0x01
-#define GSM48_PDISC_PDSS1	0x02
-#define GSM48_PDISC_CC		0x03
-#define GSM48_PDISC_PDSS2	0x04
-#define GSM48_PDISC_MM		0x05
-#define GSM48_PDISC_RR		0x06
-#define GSM48_PDISC_MM_GPRS	0x08
-#define GSM48_PDISC_SMS		0x09
-#define GSM48_PDISC_SM_GPRS	0x0a
-#define GSM48_PDISC_NC_SS	0x0b
-#define GSM48_PDISC_LOC		0x0c
-#define GSM48_PDISC_MASK	0x0f
-#define GSM48_PDISC_USSD	0x11
-
-/* Section 10.4 */
-#define GSM48_MT_RR_INIT_REQ		0x3c
-#define GSM48_MT_RR_ADD_ASS		0x3b
-#define GSM48_MT_RR_IMM_ASS		0x3f
-#define GSM48_MT_RR_IMM_ASS_EXT		0x39
-#define GSM48_MT_RR_IMM_ASS_REJ		0x3a
-
-#define GSM48_MT_RR_CIPH_M_CMD		0x35
-#define GSM48_MT_RR_CIPH_M_COMPL	0x32
-
-#define GSM48_MT_RR_CFG_CHG_CMD		0x30
-#define GSM48_MT_RR_CFG_CHG_ACK		0x31
-#define GSM48_MT_RR_CFG_CHG_REJ		0x33
-
-#define GSM48_MT_RR_ASS_CMD		0x2e
-#define GSM48_MT_RR_ASS_COMPL		0x29
-#define GSM48_MT_RR_ASS_FAIL		0x2f
-#define GSM48_MT_RR_HANDO_CMD		0x2b
-#define GSM48_MT_RR_HANDO_COMPL		0x2c
-#define GSM48_MT_RR_HANDO_FAIL		0x28
-#define GSM48_MT_RR_HANDO_INFO		0x2d
-
-#define GSM48_MT_RR_CELL_CHG_ORDER	0x08
-#define GSM48_MT_RR_PDCH_ASS_CMD	0x23
-
-#define GSM48_MT_RR_CHAN_REL		0x0d
-#define GSM48_MT_RR_PART_REL		0x0a
-#define GSM48_MT_RR_PART_REL_COMP	0x0f
-
-#define GSM48_MT_RR_PAG_REQ_1		0x21
-#define GSM48_MT_RR_PAG_REQ_2		0x22
-#define GSM48_MT_RR_PAG_REQ_3		0x24
-#define GSM48_MT_RR_PAG_RESP		0x27
-#define GSM48_MT_RR_NOTIF_NCH		0x20
-#define GSM48_MT_RR_NOTIF_FACCH		0x25
-#define GSM48_MT_RR_NOTIF_RESP		0x26
-
-#define GSM48_MT_RR_SYSINFO_8		0x18
-#define GSM48_MT_RR_SYSINFO_1		0x19
-#define GSM48_MT_RR_SYSINFO_2		0x1a
-#define GSM48_MT_RR_SYSINFO_3		0x1b
-#define GSM48_MT_RR_SYSINFO_4		0x1c
-#define GSM48_MT_RR_SYSINFO_5		0x1d
-#define GSM48_MT_RR_SYSINFO_6		0x1e
-#define GSM48_MT_RR_SYSINFO_7		0x1f
-
-#define GSM48_MT_RR_SYSINFO_2bis	0x02
-#define GSM48_MT_RR_SYSINFO_2ter	0x03
-#define GSM48_MT_RR_SYSINFO_5bis	0x05
-#define GSM48_MT_RR_SYSINFO_5ter	0x06
-#define GSM48_MT_RR_SYSINFO_9		0x04
-#define GSM48_MT_RR_SYSINFO_13		0x00
-
-#define GSM48_MT_RR_SYSINFO_16		0x3d
-#define GSM48_MT_RR_SYSINFO_17		0x3e
-
-#define GSM48_MT_RR_CHAN_MODE_MODIF	0x10
-#define GSM48_MT_RR_STATUS		0x12
-#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK	0x17
-#define GSM48_MT_RR_FREQ_REDEF		0x14
-#define GSM48_MT_RR_MEAS_REP		0x15
-#define GSM48_MT_RR_CLSM_CHG		0x16
-#define GSM48_MT_RR_CLSM_ENQ		0x13
-#define GSM48_MT_RR_EXT_MEAS_REP	0x36
-#define GSM48_MT_RR_EXT_MEAS_REP_ORD	0x37
-#define GSM48_MT_RR_GPRS_SUSP_REQ	0x34
-
-#define GSM48_MT_RR_VGCS_UPL_GRANT	0x08
-#define GSM48_MT_RR_UPLINK_RELEASE	0x0e
-#define GSM48_MT_RR_UPLINK_FREE		0x0c
-#define GSM48_MT_RR_UPLINK_BUSY		0x2a
-#define GSM48_MT_RR_TALKER_IND		0x11
-
-#define GSM48_MT_RR_APP_INFO		0x38
-
-/* Table 10.2/3GPP TS 04.08 */
-#define GSM48_MT_MM_IMSI_DETACH_IND	0x01
-#define GSM48_MT_MM_LOC_UPD_ACCEPT	0x02
-#define GSM48_MT_MM_LOC_UPD_REJECT	0x04
-#define GSM48_MT_MM_LOC_UPD_REQUEST	0x08
-
-#define GSM48_MT_MM_AUTH_REJ		0x11
-#define GSM48_MT_MM_AUTH_REQ		0x12
-#define GSM48_MT_MM_AUTH_RESP		0x14
-#define GSM48_MT_MM_ID_REQ		0x18
-#define GSM48_MT_MM_ID_RESP		0x19
-#define GSM48_MT_MM_TMSI_REALL_CMD	0x1a
-#define GSM48_MT_MM_TMSI_REALL_COMPL	0x1b
-
-#define GSM48_MT_MM_CM_SERV_ACC		0x21
-#define GSM48_MT_MM_CM_SERV_REJ		0x22
-#define GSM48_MT_MM_CM_SERV_ABORT	0x23
-#define GSM48_MT_MM_CM_SERV_REQ		0x24
-#define GSM48_MT_MM_CM_SERV_PROMPT	0x25
-#define GSM48_MT_MM_CM_REEST_REQ	0x28
-#define GSM48_MT_MM_ABORT		0x29
-
-#define GSM48_MT_MM_NULL		0x30
-#define GSM48_MT_MM_STATUS		0x31
-#define GSM48_MT_MM_INFO		0x32
-
-/* Table 10.3/3GPP TS 04.08 */
-#define GSM48_MT_CC_ALERTING		0x01
-#define GSM48_MT_CC_CALL_CONF		0x08
-#define GSM48_MT_CC_CALL_PROC		0x02
-#define GSM48_MT_CC_CONNECT		0x07
-#define GSM48_MT_CC_CONNECT_ACK		0x0f
-#define GSM48_MT_CC_EMERG_SETUP		0x0e
-#define GSM48_MT_CC_PROGRESS		0x03
-#define GSM48_MT_CC_ESTAB		0x04
-#define GSM48_MT_CC_ESTAB_CONF		0x06
-#define GSM48_MT_CC_RECALL		0x0b
-#define GSM48_MT_CC_START_CC		0x09
-#define GSM48_MT_CC_SETUP		0x05
-
-#define GSM48_MT_CC_MODIFY		0x17
-#define GSM48_MT_CC_MODIFY_COMPL	0x1f
-#define GSM48_MT_CC_MODIFY_REJECT	0x13
-#define GSM48_MT_CC_USER_INFO		0x10
-#define GSM48_MT_CC_HOLD		0x18
-#define GSM48_MT_CC_HOLD_ACK		0x19
-#define GSM48_MT_CC_HOLD_REJ		0x1a
-#define GSM48_MT_CC_RETR		0x1c
-#define GSM48_MT_CC_RETR_ACK		0x1d
-#define GSM48_MT_CC_RETR_REJ		0x1e
-
-#define GSM48_MT_CC_DISCONNECT		0x25
-#define GSM48_MT_CC_RELEASE		0x2d
-#define GSM48_MT_CC_RELEASE_COMPL	0x2a
-
-#define GSM48_MT_CC_CONG_CTRL		0x39
-#define GSM48_MT_CC_NOTIFY		0x3e
-#define GSM48_MT_CC_STATUS		0x3d
-#define GSM48_MT_CC_STATUS_ENQ		0x34
-#define GSM48_MT_CC_START_DTMF		0x35
-#define GSM48_MT_CC_STOP_DTMF		0x31
-#define GSM48_MT_CC_STOP_DTMF_ACK	0x32
-#define GSM48_MT_CC_START_DTMF_ACK	0x36
-#define GSM48_MT_CC_START_DTMF_REJ	0x37
-#define GSM48_MT_CC_FACILITY		0x3a
-
-/* FIXME: Table 10.4 / 10.4a (GPRS) */
-
-/* Section 10.5.2.26, Table 10.5.64 */
-#define GSM48_PM_MASK		0x03
-#define GSM48_PM_NORMAL		0x00
-#define GSM48_PM_EXTENDED	0x01
-#define GSM48_PM_REORG		0x02
-#define GSM48_PM_SAME		0x03
-
-/* Chapter 10.5.3.5 / Table 10.5.93 */
-#define GSM48_LUPD_NORMAL	0x0
-#define GSM48_LUPD_PERIODIC	0x1
-#define GSM48_LUPD_IMSI_ATT	0x2
-#define GSM48_LUPD_RESERVED	0x3
-
-/* Table 10.5.4 */
-#define GSM_MI_TYPE_MASK	0x07
-#define GSM_MI_TYPE_NONE	0x00
-#define GSM_MI_TYPE_IMSI	0x01
-#define GSM_MI_TYPE_IMEI	0x02
-#define GSM_MI_TYPE_IMEISV	0x03
-#define GSM_MI_TYPE_TMSI	0x04
-#define GSM_MI_ODD		0x08
-
-#define GSM48_IE_MUL_RATE_CFG	0x03	/* 10.5.2.21aa */
-#define GSM48_IE_MOBILE_ID	0x17
-#define GSM48_IE_NAME_LONG	0x43	/* 10.5.3.5a */
-#define GSM48_IE_NAME_SHORT	0x45	/* 10.5.3.5a */
-#define GSM48_IE_UTC		0x46	/* 10.5.3.8 */
-#define GSM48_IE_NET_TIME_TZ	0x47	/* 10.5.3.9 */
-#define GSM48_IE_LSA_IDENT	0x48	/* 10.5.3.11 */
-
-#define GSM48_IE_BEARER_CAP	0x04	/* 10.5.4.5 */
-#define GSM48_IE_CAUSE		0x08	/* 10.5.4.11 */
-#define GSM48_IE_CC_CAP		0x15	/* 10.5.4.5a */
-#define GSM48_IE_ALERT		0x19	/* 10.5.4.26 */
-#define GSM48_IE_FACILITY	0x1c	/* 10.5.4.15 */
-#define GSM48_IE_PROGR_IND	0x1e	/* 10.5.4.21 */
-#define GSM48_IE_AUX_STATUS	0x24	/* 10.5.4.4 */
-#define GSM48_IE_NOTIFY		0x27	/* 10.5.4.20 */
-#define GSM48_IE_KPD_FACILITY	0x2c	/* 10.5.4.17 */
-#define GSM48_IE_SIGNAL		0x34	/* 10.5.4.23 */
-#define GSM48_IE_CONN_BCD	0x4c	/* 10.5.4.13 */
-#define GSM48_IE_CONN_SUB	0x4d	/* 10.5.4.14 */
-#define GSM48_IE_CALLING_BCD	0x5c	/* 10.5.4.9 */
-#define GSM48_IE_CALLING_SUB	0x5d	/* 10.5.4.10 */
-#define GSM48_IE_CALLED_BCD	0x5e	/* 10.5.4.7 */
-#define GSM48_IE_CALLED_SUB	0x6d	/* 10.5.4.8 */
-#define GSM48_IE_REDIR_BCD	0x74	/* 10.5.4.21a */
-#define GSM48_IE_REDIR_SUB	0x75	/* 10.5.4.21b */
-#define GSM48_IE_LOWL_COMPAT	0x7c	/* 10.5.4.18 */
-#define GSM48_IE_HIGHL_COMPAT	0x7d	/* 10.5.4.16 */
-#define GSM48_IE_USER_USER	0x7e	/* 10.5.4.25 */
-#define GSM48_IE_SS_VERS	0x7f	/* 10.5.4.24 */
-#define GSM48_IE_MORE_DATA	0xa0	/* 10.5.4.19 */
-#define GSM48_IE_CLIR_SUPP	0xa1	/* 10.5.4.11a */
-#define GSM48_IE_CLIR_INVOC	0xa2	/* 10.5.4.11b */
-#define GSM48_IE_REV_C_SETUP	0xa3	/* 10.5.4.22a */
-#define GSM48_IE_REPEAT_CIR	0xd1	/* 10.5.4.22 */
-#define GSM48_IE_REPEAT_SEQ	0xd3	/* 10.5.4.22 */
-
-/* Section 10.5.4.11 / Table 10.5.122 */
-#define GSM48_CAUSE_CS_GSM	0x60
-
-/* Section 9.1.2 / Table 9.3 */
-#define GSM48_IE_FRQLIST_AFTER	0x05
-#define GSM48_IE_CELL_CH_DESC	0x62
-#define GSM48_IE_MSLOT_DESC	0x10
-#define GSM48_IE_CHANMODE_1	0x63
-#define GSM48_IE_CHANMODE_2	0x11
-#define GSM48_IE_CHANMODE_3	0x13
-#define GSM48_IE_CHANMODE_4	0x14
-#define GSM48_IE_CHANMODE_5	0x15
-#define GSM48_IE_CHANMODE_6	0x16
-#define GSM48_IE_CHANMODE_7	0x17
-#define GSM48_IE_CHANMODE_8	0x18
-#define GSM48_IE_CHANDESC_2	0x64
-/* FIXME */
-
-/* Section 10.5.4.23 / Table 10.5.130 */
-enum gsm48_signal_val {
-	GSM48_SIGNAL_DIALTONE	= 0x00,
-	GSM48_SIGNAL_RINGBACK	= 0x01,
-	GSM48_SIGNAL_INTERCEPT	= 0x02,
-	GSM48_SIGNAL_NET_CONG	= 0x03,
-	GSM48_SIGNAL_BUSY	= 0x04,
-	GSM48_SIGNAL_CONFIRM	= 0x05,
-	GSM48_SIGNAL_ANSWER	= 0x06,
-	GSM48_SIGNAL_CALL_WAIT	= 0x07,
-	GSM48_SIGNAL_OFF_HOOK	= 0x08,
-	GSM48_SIGNAL_OFF	= 0x3f,
-	GSM48_SIGNAL_ALERT_OFF	= 0x4f,
-};
-
-enum gsm48_cause_loc {
-	GSM48_CAUSE_LOC_USER		= 0x00,
-	GSM48_CAUSE_LOC_PRN_S_LU	= 0x01,
-	GSM48_CAUSE_LOC_PUN_S_LU	= 0x02,
-	GSM48_CAUSE_LOC_TRANS_NET	= 0x03,
-	GSM48_CAUSE_LOC_PUN_S_RU	= 0x04,
-	GSM48_CAUSE_LOC_PRN_S_RU	= 0x05,
-	/* not defined */
-	GSM48_CAUSE_LOC_INN_NET		= 0x07,
-	GSM48_CAUSE_LOC_NET_BEYOND	= 0x0a,
-};
-
-/* Section 10.5.2.31 RR Cause / Table 10.5.70 */
-enum gsm48_rr_cause {
-	GSM48_RR_CAUSE_NORMAL		= 0x00,
-	GSM48_RR_CAUSE_ABNORMAL_UNSPEC	= 0x01,
-	GSM48_RR_CAUSE_ABNORMAL_UNACCT	= 0x02,
-	GSM48_RR_CAUSE_ABNORMAL_TIMER	= 0x03,
-	GSM48_RR_CAUSE_ABNORMAL_NOACT	= 0x04,
-	GSM48_RR_CAUSE_PREMPTIVE_REL	= 0x05,
-	GSM48_RR_CAUSE_HNDOVER_IMP	= 0x06,
-	GSM48_RR_CAUSE_CHAN_MODE_UNACCT	= 0x07,
-	GSM48_RR_CAUSE_FREQ_NOT_IMPL	= 0x08,
-	GSM48_RR_CAUSE_CALL_CLEARED	= 0x41,
-	GSM48_RR_CAUSE_SEMANT_INCORR	= 0x5f,
-	GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60,
-	GSM48_RR_CAUSE_MSG_TYPE_N	= 0x61,
-	GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62,
-	GSM48_RR_CAUSE_COND_IE_ERROR	= 0x64,
-	GSM48_RR_CAUSE_NO_CELL_ALLOC_A	= 0x65,
-	GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
-};
-
-/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
-enum gsm48_cc_cause {
-	GSM48_CC_CAUSE_UNASSIGNED_NR	= 1,
-	GSM48_CC_CAUSE_NO_ROUTE		= 3,
-	GSM48_CC_CAUSE_CHAN_UNACCEPT	= 6,
-	GSM48_CC_CAUSE_OP_DET_BARRING	= 8,
-	GSM48_CC_CAUSE_NORM_CALL_CLEAR	= 16,
-	GSM48_CC_CAUSE_USER_BUSY	= 17,
-	GSM48_CC_CAUSE_USER_NOTRESPOND	= 18,
-	GSM48_CC_CAUSE_USER_ALERTING_NA	= 19,
-	GSM48_CC_CAUSE_CALL_REJECTED	= 21,
-	GSM48_CC_CAUSE_NUMBER_CHANGED	= 22,
-	GSM48_CC_CAUSE_PRE_EMPTION	= 25,
-	GSM48_CC_CAUSE_NONSE_USER_CLR	= 26,
-	GSM48_CC_CAUSE_DEST_OOO		= 27,
-	GSM48_CC_CAUSE_INV_NR_FORMAT	= 28,
-	GSM48_CC_CAUSE_FACILITY_REJ	= 29,
-	GSM48_CC_CAUSE_RESP_STATUS_INQ	= 30,
-	GSM48_CC_CAUSE_NORMAL_UNSPEC	= 31,
-	GSM48_CC_CAUSE_NO_CIRCUIT_CHAN	= 34,
-	GSM48_CC_CAUSE_NETWORK_OOO	= 38,
-	GSM48_CC_CAUSE_TEMP_FAILURE	= 41,
-	GSM48_CC_CAUSE_SWITCH_CONG	= 42,
-	GSM48_CC_CAUSE_ACC_INF_DISCARD	= 43,
-	GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL	= 44,
-	GSM48_CC_CAUSE_RESOURCE_UNAVAIL	= 47,
-	GSM48_CC_CAUSE_QOS_UNAVAIL	= 49,
-	GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
-	GSM48_CC_CAUSE_INC_BARRED_CUG	= 55,
-	GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
-	GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
-	GSM48_CC_CAUSE_SERV_OPT_UNAVAIL	= 63,
-	GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
-	GSM48_CC_CAUSE_ACM_GE_ACM_MAX	= 68,
-	GSM48_CC_CAUSE_REQ_FAC_NOTIMPL	= 69,
-	GSM48_CC_CAUSE_RESTR_BCAP_AVAIL	= 70,
-	GSM48_CC_CAUSE_SERV_OPT_UNIMPL	= 79,
-	GSM48_CC_CAUSE_INVAL_TRANS_ID	= 81,
-	GSM48_CC_CAUSE_USER_NOT_IN_CUG	= 87,
-	GSM48_CC_CAUSE_INCOMPAT_DEST	= 88,
-	GSM48_CC_CAUSE_INVAL_TRANS_NET	= 91,
-	GSM48_CC_CAUSE_SEMANTIC_INCORR	= 95,
-	GSM48_CC_CAUSE_INVAL_MAND_INF	= 96,
-	GSM48_CC_CAUSE_MSGTYPE_NOTEXIST	= 97,
-	GSM48_CC_CAUSE_MSGTYPE_INCOMPAT	= 98,
-	GSM48_CC_CAUSE_IE_NOTEXIST	= 99,
-	GSM48_CC_CAUSE_COND_IE_ERR	= 100,
-	GSM48_CC_CAUSE_MSG_INCOMP_STATE	= 101,
-	GSM48_CC_CAUSE_RECOVERY_TIMER	= 102,
-	GSM48_CC_CAUSE_PROTO_ERR	= 111,
-	GSM48_CC_CAUSE_INTERWORKING	= 127,
-};
-
-/* Annex G, GSM specific cause values for mobility management */
-enum gsm48_reject_value {
-	GSM48_REJECT_IMSI_UNKNOWN_IN_HLR	= 2,
-	GSM48_REJECT_ILLEGAL_MS			= 3,
-	GSM48_REJECT_IMSI_UNKNOWN_IN_VLR	= 4,
-	GSM48_REJECT_IMEI_NOT_ACCEPTED		= 5,
-	GSM48_REJECT_ILLEGAL_ME			= 6,
-	GSM48_REJECT_PLMN_NOT_ALLOWED		= 11,
-	GSM48_REJECT_LOC_NOT_ALLOWED		= 12,
-	GSM48_REJECT_ROAMING_NOT_ALLOWED	= 13,
-	GSM48_REJECT_NETWORK_FAILURE		= 17,
-	GSM48_REJECT_CONGESTION			= 22,
-	GSM48_REJECT_SRV_OPT_NOT_SUPPORTED	= 32,
-	GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED	= 33,
-	GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER	= 34,
-	GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED	= 38,
-	GSM48_REJECT_INCORRECT_MESSAGE		= 95,
-	GSM48_REJECT_INVALID_MANDANTORY_INF	= 96,
-	GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED	= 97,
-	GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE	= 98,
-	GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED	= 99,
-	GSM48_REJECT_CONDTIONAL_IE_ERROR	= 100,
-	GSM48_REJECT_MSG_NOT_COMPATIBLE		= 101,
-	GSM48_REJECT_PROTOCOL_ERROR		= 111,
-
-	/* according to G.6 Additional cause codes for GMM */
-	GSM48_REJECT_GPRS_NOT_ALLOWED		= 7,
-	GSM48_REJECT_SERVICES_NOT_ALLOWED	= 8,
-	GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9,
-	GSM48_REJECT_IMPLICITLY_DETACHED	= 10,
-	GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN	= 14,
-	GSM48_REJECT_MSC_TMP_NOT_REACHABLE	= 16,
-};
-
-enum chreq_type {
-	CHREQ_T_EMERG_CALL,
-	CHREQ_T_CALL_REEST_TCH_F,
-	CHREQ_T_CALL_REEST_TCH_H,
-	CHREQ_T_CALL_REEST_TCH_H_DBL,
-	CHREQ_T_SDCCH,
-	CHREQ_T_TCH_F,
-	CHREQ_T_VOICE_CALL_TCH_H,
-	CHREQ_T_DATA_CALL_TCH_H,
-	CHREQ_T_LOCATION_UPD,
-	CHREQ_T_PAG_R_ANY_NECI0,
-	CHREQ_T_PAG_R_ANY_NECI1,
-	CHREQ_T_PAG_R_TCH_F,
-	CHREQ_T_PAG_R_TCH_FH,
-	CHREQ_T_LMU,
-	CHREQ_T_RESERVED_SDCCH,
-	CHREQ_T_RESERVED_IGNORE,
-};
-
-/* Chapter 11.3 */
-#define GSM48_T301	180, 0
-#define GSM48_T303	30, 0
-#define GSM48_T305	30, 0
-#define GSM48_T306	30, 0
-#define GSM48_T308	10, 0
-#define GSM48_T310	180, 0
-#define GSM48_T313	30, 0
-#define GSM48_T323	30, 0
-#define GSM48_T331	30, 0
-#define GSM48_T333	30, 0
-#define GSM48_T334	25, 0 /* min 15 */
-#define GSM48_T338	30, 0
-
-/* Chapter 5.1.2.2 */
-#define	GSM_CSTATE_NULL			0
-#define	GSM_CSTATE_INITIATED		1
-#define	GSM_CSTATE_MO_CALL_PROC		3
-#define	GSM_CSTATE_CALL_DELIVERED	4
-#define	GSM_CSTATE_CALL_PRESENT		6
-#define	GSM_CSTATE_CALL_RECEIVED	7
-#define	GSM_CSTATE_CONNECT_REQUEST	8
-#define	GSM_CSTATE_MO_TERM_CALL_CONF	9
-#define	GSM_CSTATE_ACTIVE		10
-#define	GSM_CSTATE_DISCONNECT_REQ	12
-#define	GSM_CSTATE_DISCONNECT_IND	12
-#define	GSM_CSTATE_RELEASE_REQ		19
-#define	GSM_CSTATE_MO_ORIG_MODIFY	26
-#define	GSM_CSTATE_MO_TERM_MODIFY	27
-#define	GSM_CSTATE_CONNECT_IND		28
-
-#define SBIT(a) (1 << a)
-#define ALL_STATES 0xffffffff
-
-/* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */
-#define GSM_LAC_RESERVED_DETACHED       0x0
-#define GSM_LAC_RESERVED_ALL_BTS        0xfffe
-
-/* GSM 04.08 Bearer Capability: Information Transfer Capability */
-enum gsm48_bcap_itcap {
-	GSM48_BCAP_ITCAP_SPEECH		= 0,
-	GSM48_BCAP_ITCAP_UNR_DIG_INF	= 1,
-	GSM48_BCAP_ITCAP_3k1_AUDIO	= 2,
-	GSM48_BCAP_ITCAP_FAX_G3		= 3,
-	GSM48_BCAP_ITCAP_OTHER		= 5,
-	GSM48_BCAP_ITCAP_RESERVED	= 7,
-};
-
-/* GSM 04.08 Bearer Capability: Transfer Mode */
-enum gsm48_bcap_tmod {
-	GSM48_BCAP_TMOD_CIRCUIT		= 0,
-	GSM48_BCAP_TMOD_PACKET		= 1,
-};
-
-/* GSM 04.08 Bearer Capability: Coding Standard */
-enum gsm48_bcap_coding {
-	GSM48_BCAP_CODING_GSM_STD	= 0,
-};
-
-/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
-enum gsm48_bcap_rrq {
-	GSM48_BCAP_RRQ_FR_ONLY	= 1,
-	GSM48_BCAP_RRQ_DUAL_HR	= 2,
-	GSM48_BCAP_RRQ_DUAL_FR	= 3,
-};
-
-
-#define GSM48_TMSI_LEN	5
-#define GSM48_MID_TMSI_LEN	(GSM48_TMSI_LEN + 2)
-#define GSM48_MI_SIZE 32
-
+#include <osmocore/protocol/gsm_04_08.h>
 
 struct msgb;
 struct gsm_bts;
diff --git a/openbsc/include/openbsc/gsm_04_11.h b/openbsc/include/openbsc/gsm_04_11.h
index 1851bba..9badd36 100644
--- a/openbsc/include/openbsc/gsm_04_11.h
+++ b/openbsc/include/openbsc/gsm_04_11.h
@@ -1,187 +1,7 @@
 #ifndef _GSM_04_11_H
 #define _GSM_04_11_H
 
-/* GSM TS 04.11  definitions */
-
-/* Chapter 5.2.3: SMC-CS states at the network side */
-enum gsm411_cp_state {
-	GSM411_CPS_IDLE 		= 0,
-	GSM411_CPS_MM_CONN_PENDING	= 1,	/* only MT ! */
-	GSM411_CPS_WAIT_CP_ACK		= 2,
-	GSM411_CPS_MM_ESTABLISHED	= 3,
-};
-
-/* Chapter 6.2.2: SMR states at the network side */
-enum gsm411_rp_state {
-	GSM411_RPS_IDLE			= 0,
-	GSM411_RPS_WAIT_FOR_RP_ACK	= 1,
-	GSM411_RPS_WAIT_TO_TX_RP_ACK	= 3,
-};
-
-/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
-#define GSM411_PDISC_SMS	0x09
-
-/* Chapter 8.1.3 */
-#define GSM411_MT_CP_DATA	0x01
-#define GSM411_MT_CP_ACK	0x04
-#define GSM411_MT_CP_ERROR	0x10
-
-enum gsm411_cp_ie {
-	GSM411_CP_IE_USER_DATA		= 0x01,	/* 8.1.4.1 */
-	GSM411_CP_IE_CAUSE		= 0x02,	/* 8.1.4.2. */
-};
-
-/* Section 8.1.4.2 / Table 8.2 */
-enum gsm411_cp_cause {
-	GSM411_CP_CAUSE_NET_FAIL	= 17,
-	GSM411_CP_CAUSE_CONGESTION	= 22,
-	GSM411_CP_CAUSE_INV_TRANS_ID	= 81,
-	GSM411_CP_CAUSE_SEMANT_INC_MSG	= 95,
-	GSM411_CP_CAUSE_INV_MAND_INF	= 96,
-	GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97,
-	GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98,
-	GSM411_CP_CAUSE_IE_NOTEXIST	= 99,
-	GSM411_CP_CAUSE_PROTOCOL_ERR	= 111,
-};
-
-/* Chapter 8.2.2 */
-#define GSM411_MT_RP_DATA_MO	0x00
-#define GSM411_MT_RP_DATA_MT	0x01
-#define GSM411_MT_RP_ACK_MO	0x02
-#define GSM411_MT_RP_ACK_MT	0x03
-#define GSM411_MT_RP_ERROR_MO	0x04
-#define GSM411_MT_RP_ERROR_MT	0x05
-#define GSM411_MT_RP_SMMA_MO	0x06
-
-enum gsm411_rp_ie {
-	GSM411_IE_RP_USER_DATA		= 0x41,	/* 8.2.5.3 */
-	GSM411_IE_RP_CAUSE		= 0x42,	/* 8.2.5.4 */
-};
-
-/* Chapter 8.2.5.4 Table 8.4 */
-enum gsm411_rp_cause {
-	/* valid only for MO */
-	GSM411_RP_CAUSE_MO_NUM_UNASSIGNED	= 1,
-	GSM411_RP_CAUSE_MO_OP_DET_BARR		= 8,
-	GSM411_RP_CAUSE_MO_CALL_BARRED		= 10,
-	GSM411_RP_CAUSE_MO_SMS_REJECTED		= 21,
-	GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER	= 27,
-	GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR	= 28,
-	GSM411_RP_CAUSE_MO_FACILITY_REJ		= 29,
-	GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR	= 30,
-	GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER	= 38,
-	GSM411_RP_CAUSE_MO_TEMP_FAIL		= 41,
-	GSM411_RP_CAUSE_MO_CONGESTION		= 42,
-	GSM411_RP_CAUSE_MO_RES_UNAVAIL		= 47,
-	GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR	= 50,
-	GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL	= 69,
-	GSM411_RP_CAUSE_MO_INTERWORKING		= 127,
-	/* valid only for MT */
-	GSM411_RP_CAUSE_MT_MEM_EXCEEDED		= 22,
-	/* valid for both directions */
-	GSM411_RP_CAUSE_INV_TRANS_REF		= 81,
-	GSM411_RP_CAUSE_SEMANT_INC_MSG		= 95,
-	GSM411_RP_CAUSE_INV_MAND_INF		= 96,
-	GSM411_RP_CAUSE_MSGTYPE_NOTEXIST	= 97,
-	GSM411_RP_CAUSE_MSG_INCOMP_STATE	= 98,
-	GSM411_RP_CAUSE_IE_NOTEXIST		= 99,
-	GSM411_RP_CAUSE_PROTOCOL_ERR		= 111,
-};
-
-/* Chapter 10: Timers */
-#define GSM411_TMR_TR1M		40, 0	/* 35 < x < 45 seconds */
-#define GSM411_TMR_TRAM		30, 0	/* 25 < x < 35 seconds */
-#define GSM411_TMR_TR2M		15, 0	/* 12 < x < 20 seconds */
-
-#define GSM411_TMR_TC1A		30, 0
-
-/* Chapter 8.2.1 */
-struct gsm411_rp_hdr {
-	u_int8_t len;
-	u_int8_t msg_type;
-	u_int8_t msg_ref;
-	u_int8_t data[0];
-} __attribute__ ((packed));
-
-/* our own enum, not related to on-air protocol */
-enum sms_alphabet {
-	DCS_NONE,
-	DCS_7BIT_DEFAULT,
-	DCS_UCS2,
-	DCS_8BIT_DATA,
-};
-
-/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */
-#define GSM340_SMS_DELIVER_SC2MS	0x00
-#define GSM340_SMS_DELIVER_REP_MS2SC	0x00
-#define GSM340_SMS_STATUS_REP_SC2MS	0x02
-#define GSM340_SMS_COMMAND_MS2SC	0x02
-#define GSM340_SMS_SUBMIT_MS2SC		0x01
-#define GSM340_SMS_SUBMIT_REP_SC2MS	0x01
-#define GSM340_SMS_RESSERVED		0x03
-
-/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */
-#define GSM340_TP_MMS_MORE		0
-#define GSM340_TP_MMS_NO_MORE		1
-
-/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */
-#define GSM340_TP_VPF_NONE		0
-#define GSM340_TP_VPF_RELATIVE		2
-#define GSM340_TP_VPF_ENHANCED		1
-#define GSM340_TP_VPF_ABSOLUTE		3
-
-/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */
-#define GSM340_TP_SRI_NONE		0
-#define GSM340_TP_SRI_PRESENT		1
-
-/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */
-#define GSM340_TP_SRR_NONE		0
-#define GSM340_TP_SRR_REQUESTED		1
-
-/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */
-/* telematic interworking (001 or 111 in bits 7-5) */
-#define GSM340_TP_PID_IMPLICIT		0x00
-#define GSM340_TP_PID_TELEX		0x01
-#define GSM340_TP_PID_FAX_G3		0x02
-#define GSM340_TP_PID_FAX_G4		0x03
-#define GSM340_TP_PID_VOICE		0x04
-#define GSM430_TP_PID_ERMES		0x05
-#define GSM430_TP_PID_NATIONAL_PAGING	0x06
-#define GSM430_TP_PID_VIDEOTEX		0x07
-#define GSM430_TP_PID_TELETEX_UNSPEC	0x08
-#define GSM430_TP_PID_TELETEX_PSPDN	0x09
-#define GSM430_TP_PID_TELETEX_CSPDN	0x0a
-#define GSM430_TP_PID_TELETEX_PSTN	0x0b
-#define GSM430_TP_PID_TELETEX_ISDN	0x0c
-#define GSM430_TP_PID_TELETEX_UCI	0x0d
-#define GSM430_TP_PID_MSG_HANDLING	0x10
-#define GSM430_TP_PID_MSG_X400		0x11
-#define GSM430_TP_PID_EMAIL		0x12
-#define GSM430_TP_PID_GSM_MS		0x1f
-/* if bit 7 = 0 and bit 6 = 1 */
-#define GSM430_TP_PID_SMS_TYPE_0	0
-#define GSM430_TP_PID_SMS_TYPE_1	1
-#define GSM430_TP_PID_SMS_TYPE_2	2
-#define GSM430_TP_PID_SMS_TYPE_3	3
-#define GSM430_TP_PID_SMS_TYPE_4	4
-#define GSM430_TP_PID_SMS_TYPE_5	5
-#define GSM430_TP_PID_SMS_TYPE_6	6
-#define GSM430_TP_PID_SMS_TYPE_7	7
-#define GSM430_TP_PID_RETURN_CALL_MSG	0x1f
-#define GSM430_TP_PID_ME_DATA_DNLOAD	0x3d
-#define GSM430_TP_PID_ME_DE_PERSONAL	0x3e
-#define GSM430_TP_PID_ME_SIM_DNLOAD	0x3f
-
-/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */
-#define GSM338_DCS_00_
-
-#define GSM338_DCS_1110_7BIT		(0 << 2)
-#define GSM338_DCS_1111_7BIT		(0 << 2)
-#define GSM338_DCS_1111_8BIT_DATA	(1 << 2)
-#define GSM338_DCS_1111_CLASS0		0
-#define GSM338_DCS_1111_CLASS1_ME	1
-#define GSM338_DCS_1111_CLASS2_SIM	2
-#define GSM338_DCS_1111_CLASS3_TE	3	/* See TS 07.05 */
+#include <osmocore/protocol/gsm_04_11.h>
 
 /* SMS deliver PDU */
 struct sms_deliver {
diff --git a/openbsc/include/openbsc/gsm_04_80.h b/openbsc/include/openbsc/gsm_04_80.h
index c240bbe..b5ab1c6 100644
--- a/openbsc/include/openbsc/gsm_04_80.h
+++ b/openbsc/include/openbsc/gsm_04_80.h
@@ -1,129 +1,8 @@
 #ifndef _GSM_04_80_H
 #define _GSM_04_80_H
 
-/* GSM TS 04.80  definitions (Supplementary Services Specification, Formats and Coding) */
-
-/* Section 3.4 */
-#define GSM0480_MTYPE_RELEASE_COMPLETE	0x2A
-#define GSM0480_MTYPE_FACILITY			0x3A
-#define GSM0480_MTYPE_REGISTER			0x3B
-
-/* Section 3.5 */
-#define GSM0480_IE_FACILITY			0x1C
-#define GSM0480_IE_SS_VERSION			0x7F
-
-/* Section 3.6.2 */
-#define GSM0480_CTYPE_INVOKE			0xA1
-#define GSM0480_CTYPE_RETURN_RESULT		0xA2
-#define GSM0480_CTYPE_RETURN_ERROR		0xA3
-#define GSM0480_CTYPE_REJECT			0xA4
-
-/* Section 3.6.3 */
-#define GSM0480_COMPIDTAG_INVOKE_ID		0x02
-#define GSM0480_COMPIDTAG_LINKED_ID		0x80
-
-/* Section 3.6.4 */
-#define GSM0480_OPERATION_CODE			0x02
-
-/* Section 3.6.5 */
-#define GSM_0480_SEQUENCE_TAG			0x30
-#define GSM_0480_SET_TAG			0x31
-
-/* Section 3.6.6 */
-#define GSM_0480_ERROR_CODE_TAG			0x02
-
-/* Section 3.6.7 */
-/* Table 3.13 */
-#define GSM_0480_PROBLEM_CODE_TAG_GENERAL	0x80
-#define GSM_0480_PROBLEM_CODE_TAG_INVOKE	0x81
-#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT	0x82
-#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR	0x83
-
-/* Table 3.14 */
-#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED	0x00
-#define GSM_0480_GEN_PROB_CODE_MISTYPED		0x01
-#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE	0x02
-
-/* Table 3.15 */
-#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID		0x00
-#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION	0x01
-#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER		0x02
-#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION		0x03
-#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE		0x04
-#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID	0x05
-#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE	0x06
-#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION	0x07
-
-/* Table 3.16 */
-#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID	0x00
-#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED	0x01
-#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER		0x02
-
-/* Table 3.17 */
-#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID		0x00
-#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED	0x01
-#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR		0x02
-#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR		0x03
-#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER		0x04
-
-/* Section 4.5 */
-#define GSM0480_OP_CODE_REGISTER_SS		0x0A
-#define GSM0480_OP_CODE_ERASE_SS		0x0B
-#define GSM0480_OP_CODE_ACTIVATE_SS		0x0C
-#define GSM0480_OP_CODE_DEACTIVATE_SS		0x0D
-#define GSM0480_OP_CODE_INTERROGATE_SS		0x0E
-#define GSM0480_OP_CODE_NOTIFY_SS		0x10
-#define GSM0480_OP_CODE_REGISTER_PASSWORD	0x11
-#define GSM0480_OP_CODE_GET_PASSWORD		0x12
-#define GSM0480_OP_CODE_PROCESS_USS_DATA	0x13
-#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND	0x26
-#define GSM0480_OP_CODE_PROCESS_USS_REQ		0x3B
-#define GSM0480_OP_CODE_USS_REQUEST		0x3C
-#define GSM0480_OP_CODE_USS_NOTIFY		0x3D
-#define GSM0480_OP_CODE_FORWARD_CUG_INFO	0x78
-#define GSM0480_OP_CODE_SPLIT_MPTY		0x79
-#define GSM0480_OP_CODE_RETRIEVE_MPTY		0x7A
-#define GSM0480_OP_CODE_HOLD_MPTY		0x7B
-#define GSM0480_OP_CODE_BUILD_MPTY		0x7C
-#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE	0x7D
-
-#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER			0x01
-#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER			0x09
-#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED		0x0A
-#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED		0x0B
-#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT			0x0C
-#define GSM0480_ERR_CODE_CALL_BARRED				0x0D
-#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION			0x10
-#define GSM0480_ERR_CODE_SS_ERROR_STATUS			0x11
-#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE			0x12
-#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION		0x13
-#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY			0x14
-#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED			0x15
-#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER			0x1B
-#define GSM0480_ERR_CODE_SYSTEM_FAILURE				0x22
-#define GSM0480_ERR_CODE_DATA_MISSING				0x23
-#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE			0x24
-#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE		0x25
-#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK			0x26
-#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION		0x2B
-#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET			0x47
-#define GSM0480_ERR_CODE_USSD_BUSY				0x48
-#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS			0x7E
-#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE		0x7F
-
-/* ASN.1 type-tags */
-#define ASN1_BOOLEAN_TAG		0x01
-#define ASN1_INTEGER_TAG		0x02
-#define ASN1_BIT_STRING_TAG		0x03
-#define ASN1_OCTET_STRING_TAG		0x04
-#define ASN1_NULL_TYPE_TAG		0x05
-#define ASN1_OBJECT_ID_TAG		0x06
-#define ASN1_UTF8_STRING_TAG		0x0C
-#define ASN1_PRINTABLE_STRING_TAG	0x13
-#define ASN1_IA5_STRING_TAG		0x16
-#define ASN1_UNICODE_STRING_TAG		0x1E
-
-#include <openbsc/msgb.h>
+#include <osmocore/msgb.h>
+#include <osmocore/protocol/gsm_04_80.h>
 
 #define MAX_LEN_USSD_STRING	31
 
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 5567d89..eebe6ab 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -11,14 +11,6 @@
 const char *get_value_string(const struct value_string *vs, u_int32_t val);
 int get_string_value(const struct value_string *vs, const char *str);
 
-enum gsm_band {
-	GSM_BAND_400,
-	GSM_BAND_850,
-	GSM_BAND_900,
-	GSM_BAND_1800,
-	GSM_BAND_1900,
-};
-
 enum gsm_phys_chan_config {
 	GSM_PCHAN_NONE,
 	GSM_PCHAN_CCCH,
@@ -56,15 +48,15 @@
 	GSM_CHREQ_REASON_OTHER,
 };
 
-#include <openbsc/timer.h>
+#include <osmocore/timer.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/mncc.h>
-#include <openbsc/tlv.h>
-#include <openbsc/bitvec.h>
-#include <openbsc/statistics.h>
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#include <osmocore/tlv.h>
+#include <osmocore/bitvec.h>
+#include <osmocore/statistics.h>
+#include <osmocore/gsm_utils.h>
+#include <osmocore/utils.h>
 
 #define TRX_NR_TS	8
 #define TS_MAX_LCHAN	8
diff --git a/openbsc/include/openbsc/gsm_subscriber.h b/openbsc/include/openbsc/gsm_subscriber.h
index c639f40..0653996 100644
--- a/openbsc/include/openbsc/gsm_subscriber.h
+++ b/openbsc/include/openbsc/gsm_subscriber.h
@@ -3,7 +3,7 @@
 
 #include <sys/types.h>
 #include "gsm_data.h"
-#include "linuxlist.h"
+#include <osmocore/linuxlist.h>
 
 #define GSM_IMEI_LENGTH 17
 #define GSM_IMSI_LENGTH 17
diff --git a/openbsc/include/openbsc/gsm_utils.h b/openbsc/include/openbsc/gsm_utils.h
deleted file mode 100644
index 56a4120..0000000
--- a/openbsc/include/openbsc/gsm_utils.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* GSM utility functions, e.g. coding and decoding */
-/*
- * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
- * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef GSM_UTILS_H
-#define GSM_UTILS_H
-
-#include <sys/types.h>
-
-int gsm_7bit_decode(char *decoded, const u_int8_t *user_data, u_int8_t length);
-int gsm_7bit_encode(u_int8_t *result, const char *data);
-
-int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
-int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl);
-
-/* According to TS 08.05 Chapter 8.1.4 */
-int rxlev2dbm(u_int8_t rxlev);
-u_int8_t dbm2rxlev(int dbm);
-
-/* According to GSM 04.08 Chapter 10.5.2.29 */
-static inline int rach_max_trans_val2raw(int val) { return (val >> 1) & 3; }
-static inline int rach_max_trans_raw2val(int raw) {
-	const int tbl[4] = { 1, 2, 4, 7 };
-	return tbl[raw & 3];
-}
-
-void generate_backtrace();
-#endif
diff --git a/openbsc/include/openbsc/ipaccess.h b/openbsc/include/openbsc/ipaccess.h
index 8c12e59..904a962 100644
--- a/openbsc/include/openbsc/ipaccess.h
+++ b/openbsc/include/openbsc/ipaccess.h
@@ -2,7 +2,7 @@
 #define _IPACCESS_H
 
 #include "e1_input.h"
-#include "linuxlist.h"
+#include <osmocore/linuxlist.h>
 
 #define IPA_TCP_PORT_OML	3002
 #define IPA_TCP_PORT_RSL	3003
@@ -48,6 +48,11 @@
 int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd);
 struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
 void ipaccess_prepend_header(struct msgb *msg, int proto);
+int ipaccess_send_id_ack(int fd);
+int ipaccess_send_id_req(int fd);
+
+int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
+
 
 /*
  * Firmware specific header
diff --git a/openbsc/include/openbsc/linuxlist.h b/openbsc/include/openbsc/linuxlist.h
deleted file mode 100644
index fb99c5e..0000000
--- a/openbsc/include/openbsc/linuxlist.h
+++ /dev/null
@@ -1,360 +0,0 @@
-#ifndef _LINUX_LLIST_H
-#define _LINUX_LLIST_H
-
-#include <stddef.h>
-
-#ifndef inline
-#define inline __inline__
-#endif
-
-static inline void prefetch(const void *x) {;}
-
-/**
- * container_of - cast a member of a structure out to the containing structure
- *
- * @ptr:	the pointer to the member.
- * @type:	the type of the container struct this is embedded in.
- * @member:	the name of the member within the struct.
- *
- */
-#define container_of(ptr, type, member) ({			\
-        const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr);	\
-        (type *)( (char *)__mptr - offsetof(type, member) );})
-
-
-/*
- * These are non-NULL pointers that will result in page faults
- * under normal circumstances, used to verify that nobody uses
- * non-initialized llist entries.
- */
-#define LLIST_POISON1  ((void *) 0x00100100)
-#define LLIST_POISON2  ((void *) 0x00200200)
-
-/*
- * Simple doubly linked llist implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole llists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct llist_head {
-	struct llist_head *next, *prev;
-};
-
-#define LLIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LLIST_HEAD(name) \
-	struct llist_head name = LLIST_HEAD_INIT(name)
-
-#define INIT_LLIST_HEAD(ptr) do { \
-	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
-} while (0)
-
-/*
- * Insert a new entry between two known consecutive entries. 
- *
- * This is only for internal llist manipulation where we know
- * the prev/next entries already!
- */
-static inline void __llist_add(struct llist_head *_new,
-			      struct llist_head *prev,
-			      struct llist_head *next)
-{
-	next->prev = _new;
-	_new->next = next;
-	_new->prev = prev;
-	prev->next = _new;
-}
-
-/**
- * llist_add - add a new entry
- * @new: new entry to be added
- * @head: llist head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void llist_add(struct llist_head *_new, struct llist_head *head)
-{
-	__llist_add(_new, head, head->next);
-}
-
-/**
- * llist_add_tail - add a new entry
- * @new: new entry to be added
- * @head: llist head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void llist_add_tail(struct llist_head *_new, struct llist_head *head)
-{
-	__llist_add(_new, head->prev, head);
-}
-
-/*
- * Delete a llist entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal llist manipulation where we know
- * the prev/next entries already!
- */
-static inline void __llist_del(struct llist_head * prev, struct llist_head * next)
-{
-	next->prev = prev;
-	prev->next = next;
-}
-
-/**
- * llist_del - deletes entry from llist.
- * @entry: the element to delete from the llist.
- * Note: llist_empty on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void llist_del(struct llist_head *entry)
-{
-	__llist_del(entry->prev, entry->next);
-	entry->next = (struct llist_head *)LLIST_POISON1;
-	entry->prev = (struct llist_head *)LLIST_POISON2;
-}
-
-/**
- * llist_del_init - deletes entry from llist and reinitialize it.
- * @entry: the element to delete from the llist.
- */
-static inline void llist_del_init(struct llist_head *entry)
-{
-	__llist_del(entry->prev, entry->next);
-	INIT_LLIST_HEAD(entry); 
-}
-
-/**
- * llist_move - delete from one llist and add as another's head
- * @llist: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void llist_move(struct llist_head *llist, struct llist_head *head)
-{
-        __llist_del(llist->prev, llist->next);
-        llist_add(llist, head);
-}
-
-/**
- * llist_move_tail - delete from one llist and add as another's tail
- * @llist: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void llist_move_tail(struct llist_head *llist,
-				  struct llist_head *head)
-{
-        __llist_del(llist->prev, llist->next);
-        llist_add_tail(llist, head);
-}
-
-/**
- * llist_empty - tests whether a llist is empty
- * @head: the llist to test.
- */
-static inline int llist_empty(const struct llist_head *head)
-{
-	return head->next == head;
-}
-
-static inline void __llist_splice(struct llist_head *llist,
-				 struct llist_head *head)
-{
-	struct llist_head *first = llist->next;
-	struct llist_head *last = llist->prev;
-	struct llist_head *at = head->next;
-
-	first->prev = head;
-	head->next = first;
-
-	last->next = at;
-	at->prev = last;
-}
-
-/**
- * llist_splice - join two llists
- * @llist: the new llist to add.
- * @head: the place to add it in the first llist.
- */
-static inline void llist_splice(struct llist_head *llist, struct llist_head *head)
-{
-	if (!llist_empty(llist))
-		__llist_splice(llist, head);
-}
-
-/**
- * llist_splice_init - join two llists and reinitialise the emptied llist.
- * @llist: the new llist to add.
- * @head: the place to add it in the first llist.
- *
- * The llist at @llist is reinitialised
- */
-static inline void llist_splice_init(struct llist_head *llist,
-				    struct llist_head *head)
-{
-	if (!llist_empty(llist)) {
-		__llist_splice(llist, head);
-		INIT_LLIST_HEAD(llist);
-	}
-}
-
-/**
- * llist_entry - get the struct for this entry
- * @ptr:	the &struct llist_head pointer.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the llist_struct within the struct.
- */
-#define llist_entry(ptr, type, member) \
-	container_of(ptr, type, member)
-
-/**
- * llist_for_each	-	iterate over a llist
- * @pos:	the &struct llist_head to use as a loop counter.
- * @head:	the head for your llist.
- */
-#define llist_for_each(pos, head) \
-	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
-        	pos = pos->next, prefetch(pos->next))
-
-/**
- * __llist_for_each	-	iterate over a llist
- * @pos:	the &struct llist_head to use as a loop counter.
- * @head:	the head for your llist.
- *
- * This variant differs from llist_for_each() in that it's the
- * simplest possible llist iteration code, no prefetching is done.
- * Use this for code that knows the llist to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __llist_for_each(pos, head) \
-	for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * llist_for_each_prev	-	iterate over a llist backwards
- * @pos:	the &struct llist_head to use as a loop counter.
- * @head:	the head for your llist.
- */
-#define llist_for_each_prev(pos, head) \
-	for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
-        	pos = pos->prev, prefetch(pos->prev))
-        	
-/**
- * llist_for_each_safe	-	iterate over a llist safe against removal of llist entry
- * @pos:	the &struct llist_head to use as a loop counter.
- * @n:		another &struct llist_head to use as temporary storage
- * @head:	the head for your llist.
- */
-#define llist_for_each_safe(pos, n, head) \
-	for (pos = (head)->next, n = pos->next; pos != (head); \
-		pos = n, n = pos->next)
-
-/**
- * llist_for_each_entry	-	iterate over llist of given type
- * @pos:	the type * to use as a loop counter.
- * @head:	the head for your llist.
- * @member:	the name of the llist_struct within the struct.
- */
-#define llist_for_each_entry(pos, head, member)				\
-	for (pos = llist_entry((head)->next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head); 					\
-	     pos = llist_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next))
-
-/**
- * llist_for_each_entry_reverse - iterate backwards over llist of given type.
- * @pos:	the type * to use as a loop counter.
- * @head:	the head for your llist.
- * @member:	the name of the llist_struct within the struct.
- */
-#define llist_for_each_entry_reverse(pos, head, member)			\
-	for (pos = llist_entry((head)->prev, typeof(*pos), member),	\
-		     prefetch(pos->member.prev);			\
-	     &pos->member != (head); 					\
-	     pos = llist_entry(pos->member.prev, typeof(*pos), member),	\
-		     prefetch(pos->member.prev))
-
-/**
- * llist_for_each_entry_continue -	iterate over llist of given type
- *			continuing after existing point
- * @pos:	the type * to use as a loop counter.
- * @head:	the head for your llist.
- * @member:	the name of the llist_struct within the struct.
- */
-#define llist_for_each_entry_continue(pos, head, member) 		\
-	for (pos = llist_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head);					\
-	     pos = llist_entry(pos->member.next, typeof(*pos), member),	\
-		     prefetch(pos->member.next))
-
-/**
- * llist_for_each_entry_safe - iterate over llist of given type safe against removal of llist entry
- * @pos:	the type * to use as a loop counter.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your llist.
- * @member:	the name of the llist_struct within the struct.
- */
-#define llist_for_each_entry_safe(pos, n, head, member)			\
-	for (pos = llist_entry((head)->next, typeof(*pos), member),	\
-		n = llist_entry(pos->member.next, typeof(*pos), member);	\
-	     &pos->member != (head); 					\
-	     pos = n, n = llist_entry(n->member.next, typeof(*n), member))
-
-/**
- * llist_for_each_rcu	-	iterate over an rcu-protected llist
- * @pos:	the &struct llist_head to use as a loop counter.
- * @head:	the head for your llist.
- */
-#define llist_for_each_rcu(pos, head) \
-	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
-        	pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
-        	
-#define __llist_for_each_rcu(pos, head) \
-	for (pos = (head)->next; pos != (head); \
-        	pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
-        	
-/**
- * llist_for_each_safe_rcu	-	iterate over an rcu-protected llist safe
- *					against removal of llist entry
- * @pos:	the &struct llist_head to use as a loop counter.
- * @n:		another &struct llist_head to use as temporary storage
- * @head:	the head for your llist.
- */
-#define llist_for_each_safe_rcu(pos, n, head) \
-	for (pos = (head)->next, n = pos->next; pos != (head); \
-		pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
-
-/**
- * llist_for_each_entry_rcu	-	iterate over rcu llist of given type
- * @pos:	the type * to use as a loop counter.
- * @head:	the head for your llist.
- * @member:	the name of the llist_struct within the struct.
- */
-#define llist_for_each_entry_rcu(pos, head, member)			\
-	for (pos = llist_entry((head)->next, typeof(*pos), member),	\
-		     prefetch(pos->member.next);			\
-	     &pos->member != (head); 					\
-	     pos = llist_entry(pos->member.next, typeof(*pos), member),	\
-		     ({ smp_read_barrier_depends(); 0;}),		\
-		     prefetch(pos->member.next))
-
-
-/**
- * llist_for_each_continue_rcu	-	iterate over an rcu-protected llist 
- *			continuing after existing point.
- * @pos:	the &struct llist_head to use as a loop counter.
- * @head:	the head for your llist.
- */
-#define llist_for_each_continue_rcu(pos, head) \
-	for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
-        	(pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next))
-
-
-#endif
diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index 004ae78..f7e800b 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -24,7 +24,7 @@
 #ifndef OPENBSC_MGCP_H
 #define OPENBSC_MGCP_H
 
-#include "msgb.h"
+#include <osmocore/msgb.h>
 
 #include <arpa/inet.h>
 
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 3df9869..10d0ca6 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -24,7 +24,7 @@
 #ifndef OPENBSC_MGCP_DATA_H
 #define OPENBSC_MGCP_DATA_H
 
-#include "select.h"
+#include <osmocore/select.h>
 
 #define CI_UNUSED 0
 
diff --git a/openbsc/include/openbsc/mncc.h b/openbsc/include/openbsc/mncc.h
index fbf3cab..06d5942 100644
--- a/openbsc/include/openbsc/mncc.h
+++ b/openbsc/include/openbsc/mncc.h
@@ -25,7 +25,7 @@
 #ifndef _MNCC_H
 #define _MNCC_H
 
-#include <openbsc/linuxlist.h>
+#include <osmocore/linuxlist.h>
 
 /* One end of a call */
 struct gsm_call {
diff --git a/openbsc/include/openbsc/msgb.h b/openbsc/include/openbsc/msgb.h
deleted file mode 100644
index ab3c033..0000000
--- a/openbsc/include/openbsc/msgb.h
+++ /dev/null
@@ -1,113 +0,0 @@
-#ifndef _MSGB_H
-#define _MSGB_H
-
-/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <openbsc/linuxlist.h>
-
-struct bts_link;
-
-struct msgb {
-	struct llist_head list;
-
-	/* ptr to the physical E1 link to the BTS(s) */
-	struct gsm_bts_link *bts_link;
-
-	/* Part of which TRX logical channel we were received / transmitted */
-	struct gsm_bts_trx *trx;
-	struct gsm_lchan *lchan;
-
-	unsigned char *l2h;
-	unsigned char *l3h;
-	unsigned char *smsh;
-
-	u_int16_t data_len;
-	u_int16_t len;
-
-	unsigned char *head;
-	unsigned char *tail;
-	unsigned char *data;
-	unsigned char _data[0];
-};
-
-extern struct msgb *msgb_alloc(u_int16_t size, const char *name);
-extern void msgb_free(struct msgb *m);
-extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
-extern struct msgb *msgb_dequeue(struct llist_head *queue);
-extern void msgb_reset(struct msgb *m);
-
-#define msgb_l2(m)	((void *)(m->l2h))
-#define msgb_l3(m)	((void *)(m->l3h))
-#define msgb_sms(m)	((void *)(m->smsh))
-
-static inline unsigned int msgb_l2len(const struct msgb *msgb)
-{
-	return msgb->tail - (u_int8_t *)msgb_l2(msgb);
-}
-
-static inline unsigned int msgb_l3len(const struct msgb *msgb)
-{
-	return msgb->tail - (u_int8_t *)msgb_l3(msgb);
-}
-
-static inline unsigned int msgb_headlen(const struct msgb *msgb)
-{
-	return msgb->len - msgb->data_len;
-}
-static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
-{
-	unsigned char *tmp = msgb->tail;
-	msgb->tail += len;
-	msgb->len += len;
-	return tmp;
-}
-static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
-{
-	msgb->data -= len;
-	msgb->len += len;
-	return msgb->data;
-}
-static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
-{
-	msgb->len -= len;
-	return msgb->data += len;
-}
-static inline int msgb_tailroom(const struct msgb *msgb)
-{
-	return (msgb->data + msgb->data_len) - msgb->tail;
-}
-
-/* increase the headroom of an empty msgb, reducing the tailroom */
-static inline void msgb_reserve(struct msgb *msg, int len)
-{
-	msg->data += len;
-	msg->tail += len;
-}
-
-static inline struct msgb *msgb_alloc_headroom(int size, int headroom,
-						const char *name)
-{
-	struct msgb *msg = msgb_alloc(size, name);
-	if (msg)
-		msgb_reserve(msg, headroom);
-	return msg;
-}
-
-#endif /* _MSGB_H */
diff --git a/openbsc/include/openbsc/paging.h b/openbsc/include/openbsc/paging.h
index ab6a274..6cbdca9 100644
--- a/openbsc/include/openbsc/paging.h
+++ b/openbsc/include/openbsc/paging.h
@@ -24,10 +24,10 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "linuxlist.h"
+#include <osmocore/linuxlist.h>
 #include "gsm_data.h"
 #include "gsm_subscriber.h"
-#include "timer.h"
+#include <osmocore/timer.h>
 
 /* call once for every gsm_bts... */
 void paging_init(struct gsm_bts *bts);
diff --git a/openbsc/include/openbsc/rtp_proxy.h b/openbsc/include/openbsc/rtp_proxy.h
index d128e4f..f82711a 100644
--- a/openbsc/include/openbsc/rtp_proxy.h
+++ b/openbsc/include/openbsc/rtp_proxy.h
@@ -25,8 +25,8 @@
 
 #include <netinet/in.h>
 
-#include <openbsc/linuxlist.h>
-#include <openbsc/select.h>
+#include <osmocore/linuxlist.h>
+#include <osmocore/select.h>
 
 enum rtp_rx_action {
 	RTP_NONE,
diff --git a/openbsc/include/openbsc/select.h b/openbsc/include/openbsc/select.h
deleted file mode 100644
index c2af1d7..0000000
--- a/openbsc/include/openbsc/select.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _BSC_SELECT_H
-#define _BSC_SELECT_H
-
-#include <openbsc/linuxlist.h>
-
-#define BSC_FD_READ	0x0001
-#define BSC_FD_WRITE	0x0002
-#define BSC_FD_EXCEPT	0x0004
-
-struct bsc_fd {
-	struct llist_head list;
-	int fd;
-	unsigned int when;
-	int (*cb)(struct bsc_fd *fd, unsigned int what);
-	void *data;
-	unsigned int priv_nr;
-};
-
-int bsc_register_fd(struct bsc_fd *fd);
-void bsc_unregister_fd(struct bsc_fd *fd);
-int bsc_select_main(int polling);
-#endif /* _BSC_SELECT_H */
diff --git a/openbsc/include/openbsc/signal.h b/openbsc/include/openbsc/signal.h
index 07b4e39..0c22869 100644
--- a/openbsc/include/openbsc/signal.h
+++ b/openbsc/include/openbsc/signal.h
@@ -28,6 +28,7 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_subscriber.h>
 
+#include <osmocore/signal.h>
 
 /*
  * Signalling subsystems
@@ -110,9 +111,6 @@
 	S_GLOBAL_SHUTDOWN,
 };
 
-typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
-			void *handler_data, void *signal_data);
-
 struct paging_signal_data {
 	struct gsm_subscriber *subscr;
 	struct gsm_bts *bts;
@@ -132,12 +130,4 @@
 	u_int8_t msg_type;	
 };
 
-/* Management */
-int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
-void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
-
-/* Dispatch */
-void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
-
-
 #endif
diff --git a/openbsc/include/openbsc/statistics.h b/openbsc/include/openbsc/statistics.h
deleted file mode 100644
index 1d56054..0000000
--- a/openbsc/include/openbsc/statistics.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _STATISTICS_H
-#define _STATISTICS_H
-
-struct counter {
-	struct llist_head list;
-	const char *name;
-	const char *description;
-	unsigned long value;
-};
-
-static inline void counter_inc(struct counter *ctr)
-{
-	ctr->value++;
-}
-
-static inline unsigned long counter_get(struct counter *ctr)
-{
-	return ctr->value;
-}
-
-static inline void counter_reset(struct counter *ctr)
-{
-	ctr->value = 0;
-}
-
-struct counter *counter_alloc(const char *name);
-void counter_free(struct counter *ctr);
-
-int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data);
-
-#endif /* _STATISTICS_H */
diff --git a/openbsc/include/openbsc/subchan_demux.h b/openbsc/include/openbsc/subchan_demux.h
index 9661b04..02fa023 100644
--- a/openbsc/include/openbsc/subchan_demux.h
+++ b/openbsc/include/openbsc/subchan_demux.h
@@ -22,7 +22,7 @@
  */
 
 #include <sys/types.h>
-#include <openbsc/linuxlist.h>
+#include <osmocore/linuxlist.h>
 
 #define NR_SUBCH	4
 #define TRAU_FRAME_SIZE	40
diff --git a/openbsc/include/openbsc/talloc.h b/openbsc/include/openbsc/talloc.h
deleted file mode 100644
index f7f7643..0000000
--- a/openbsc/include/openbsc/talloc.h
+++ /dev/null
@@ -1,192 +0,0 @@
-#ifndef _TALLOC_H_
-#define _TALLOC_H_
-/* 
-   Unix SMB/CIFS implementation.
-   Samba temporary memory allocation functions
-
-   Copyright (C) Andrew Tridgell 2004-2005
-   Copyright (C) Stefan Metzmacher 2006
-   
-     ** NOTE! The following LGPL license applies to the talloc
-     ** library. This does NOT imply that all of Samba is released
-     ** under the LGPL
-   
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 3 of the License, or (at your option) any later version.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#define HAVE_VA_COPY
-
-/* this is only needed for compatibility with the old talloc */
-typedef void TALLOC_CTX;
-
-/*
-  this uses a little trick to allow __LINE__ to be stringified
-*/
-#ifndef __location__
-#define __TALLOC_STRING_LINE1__(s)    #s
-#define __TALLOC_STRING_LINE2__(s)   __TALLOC_STRING_LINE1__(s)
-#define __TALLOC_STRING_LINE3__  __TALLOC_STRING_LINE2__(__LINE__)
-#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
-#endif
-
-#ifndef TALLOC_DEPRECATED
-#define TALLOC_DEPRECATED 0
-#endif
-
-#ifndef PRINTF_ATTRIBUTE
-#if (__GNUC__ >= 3)
-/** Use gcc attribute to check printf fns.  a1 is the 1-based index of
- * the parameter containing the format, and a2 the index of the first
- * argument. Note that some gcc 2.x versions don't handle this
- * properly **/
-#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
-#else
-#define PRINTF_ATTRIBUTE(a1, a2)
-#endif
-#endif
-
-/* try to make talloc_set_destructor() and talloc_steal() type safe,
-   if we have a recent gcc */
-#if (__GNUC__ >= 3)
-#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
-#define talloc_set_destructor(ptr, function)				      \
-	do {								      \
-		int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function);	      \
-		_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \
-	} while(0)
-/* this extremely strange macro is to avoid some braindamaged warning
-   stupidity in gcc 4.1.x */
-#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; })
-#else
-#define talloc_set_destructor(ptr, function) \
-	_talloc_set_destructor((ptr), (int (*)(void *))(function))
-#define _TALLOC_TYPEOF(ptr) void *
-#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr))
-#endif
-
-#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr))
-#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr))
-
-/* useful macros for creating type checked pointers */
-#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
-#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
-#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))
-
-#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
-
-#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
-#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
-
-#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
-#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
-#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
-#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)
-#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx))
-
-#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
-#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
-
-#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
-
-#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
-#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
-#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
-
-#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
-
-#if TALLOC_DEPRECATED
-#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
-#define talloc_p(ctx, type) talloc(ctx, type)
-#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
-#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
-#define talloc_destroy(ctx) talloc_free(ctx)
-#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
-#endif
-
-#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
-
-/* The following definitions come from talloc.c  */
-void *_talloc(const void *context, size_t size);
-void *talloc_pool(const void *context, size_t size);
-void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));
-int talloc_increase_ref_count(const void *ptr);
-size_t talloc_reference_count(const void *ptr);
-void *_talloc_reference(const void *context, const void *ptr);
-int talloc_unlink(const void *context, void *ptr);
-const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-void talloc_set_name_const(const void *ptr, const char *name);
-void *talloc_named(const void *context, size_t size, 
-		   const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
-void *talloc_named_const(const void *context, size_t size, const char *name);
-const char *talloc_get_name(const void *ptr);
-void *talloc_check_name(const void *ptr, const char *name);
-void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
-void *talloc_parent(const void *ptr);
-const char *talloc_parent_name(const void *ptr);
-void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
-int talloc_free(void *ptr);
-void talloc_free_children(void *ptr);
-void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
-void *_talloc_steal(const void *new_ctx, const void *ptr);
-void *_talloc_move(const void *new_ctx, const void *pptr);
-size_t talloc_total_size(const void *ptr);
-size_t talloc_total_blocks(const void *ptr);
-void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
-			    void (*callback)(const void *ptr,
-			  		     int depth, int max_depth,
-					     int is_ref,
-					     void *private_data),
-			    void *private_data);
-void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f);
-void talloc_report_full(const void *ptr, FILE *f);
-void talloc_report(const void *ptr, FILE *f);
-void talloc_enable_null_tracking(void);
-void talloc_disable_null_tracking(void);
-void talloc_enable_leak_report(void);
-void talloc_enable_leak_report_full(void);
-void *_talloc_zero(const void *ctx, size_t size, const char *name);
-void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
-void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
-void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
-void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
-void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
-void *talloc_autofree_context(void);
-size_t talloc_get_size(const void *ctx);
-void *talloc_find_parent_byname(const void *ctx, const char *name);
-void talloc_show_parents(const void *context, FILE *file);
-int talloc_is_parent(const void *context, const void *ptr);
-
-char *talloc_strdup(const void *t, const char *p);
-char *talloc_strdup_append(char *s, const char *a);
-char *talloc_strdup_append_buffer(char *s, const char *a);
-
-char *talloc_strndup(const void *t, const char *p, size_t n);
-char *talloc_strndup_append(char *s, const char *a, size_t n);
-char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
-
-char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-
-char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
-
-void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
-
-#endif
diff --git a/openbsc/include/openbsc/telnet_interface.h b/openbsc/include/openbsc/telnet_interface.h
index f4e976f..20e794b 100644
--- a/openbsc/include/openbsc/telnet_interface.h
+++ b/openbsc/include/openbsc/telnet_interface.h
@@ -23,13 +23,10 @@
 
 #include "gsm_data.h"
 #include "debug.h"
-#include "select.h"
+#include <osmocore/select.h>
 
 #include <vty/vty.h>
 
-#define TELNET_COMMAND_48	1
-#define TELNET_COMMAND_11	2
-
 struct telnet_connection {
 	struct llist_head entry;
 	struct gsm_network *network;
diff --git a/openbsc/include/openbsc/timer.h b/openbsc/include/openbsc/timer.h
deleted file mode 100644
index fee888b..0000000
--- a/openbsc/include/openbsc/timer.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef TIMER_H
-#define TIMER_H
-
-#include <sys/time.h>
-
-#include "linuxlist.h"
-
-/**
- * Timer management:
- *      - Create a struct timer_list
- *      - Fill out timeout and use add_timer or
- *        use schedule_timer to schedule a timer in
- *        x seconds and microseconds from now...
- *      - Use del_timer to remove the timer
- *
- *  Internally:
- *      - We hook into select.c to give a timeval of the
- *        nearest timer. On already passed timers we give
- *        it a 0 to immediately fire after the select
- *      - update_timers will call the callbacks and remove
- *        the timers.
- *
- */
-struct timer_list {
-	struct llist_head entry;
-	struct timeval timeout;
-	unsigned int active  : 1;
-	unsigned int handled : 1;
-	unsigned int in_list : 1;
-
-	void (*cb)(void*);
-	void *data;
-};
-
-/**
- * timer management
- */
-void bsc_add_timer(struct timer_list *timer);
-void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds);
-void bsc_del_timer(struct timer_list *timer);
-int bsc_timer_pending(struct timer_list *timer);
-
-
-/**
- * internal timer list management
- */
-struct timeval *bsc_nearest_timer();
-void bsc_prepare_timers();
-int bsc_update_timers();
-int bsc_timer_check(void);
-
-#endif
diff --git a/openbsc/include/openbsc/tlv.h b/openbsc/include/openbsc/tlv.h
deleted file mode 100644
index c90643e..0000000
--- a/openbsc/include/openbsc/tlv.h
+++ /dev/null
@@ -1,224 +0,0 @@
-#ifndef _TLV_H
-#define _TLV_H
-
-#include <sys/types.h>
-#include <string.h>
-
-#include <openbsc/msgb.h>
-
-/* Terminology / wording
-		tag	length		value	(in bits)
-
-	    V	-	-		8
-	   LV	-	8		N * 8
-	  TLV	8	8		N * 8
-	TL16V	8	16		N * 8
-	TLV16	8	8		N * 16
-	 TvLV	8	8/16		N * 8
-
-*/
-
-#define LV_GROSS_LEN(x)		(x+1)
-#define TLV_GROSS_LEN(x)	(x+2)
-#define TLV16_GROSS_LEN(x)	((2*x)+2)
-#define TL16V_GROSS_LEN(x)	(x+3)
-
-#define TVLV_MAX_ONEBYTE	0x7f
-
-static inline u_int16_t TVLV_GROSS_LEN(u_int16_t len)
-{
-	if (len <= TVLV_MAX_ONEBYTE)
-		return TLV_GROSS_LEN(len);
-	else
-		return TL16V_GROSS_LEN(len);
-}
-
-/* TLV generation */
-
-static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len,
-				const u_int8_t *val)
-{
-	*buf++ = len;
-	memcpy(buf, val, len);
-	return buf + len;
-}
-
-static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
-				const u_int8_t *val)
-{
-	*buf++ = tag;
-	*buf++ = len;
-	memcpy(buf, val, len);
-	return buf + len;
-}
-
-static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
-				const u_int16_t *val)
-{
-	*buf++ = tag;
-	*buf++ = len;
-	memcpy(buf, val, len*2);
-	return buf + len*2;
-}
-
-static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
-				const u_int8_t *val)
-{
-	*buf++ = tag;
-	*buf++ = len >> 8;
-	*buf++ = len & 0xff;
-	memcpy(buf, val, len);
-	return buf + len*2;
-}
-
-static inline u_int8_t *tvlv_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
-				 const u_int8_t *val)
-{
-	u_int8_t *ret;
-
-	if (len <= TVLV_MAX_ONEBYTE) {
-		ret = tlv_put(buf, tag, len, val);
-		buf[1] |= 0x80;
-	} else
-		ret = tl16v_put(buf, tag, len, val);
-
-	return ret;
-}
-
-static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val)
-{
-	u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
-	return tlv16_put(buf, tag, len, val);
-}
-
-static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
-					const u_int8_t *val)
-{
-	u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
-	return tl16v_put(buf, tag, len, val);
-}
-
-static inline u_int8_t *msgb_tvlv_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
-				      const u_int8_t *val)
-{
-	u_int8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
-	return tvlv_put(buf, tag, len, val);
-}
-
-static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val)
-{
-	*buf++ = val;
-	return buf;
-}
-
-static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag, 
-				u_int8_t val)
-{
-	*buf++ = tag;
-	*buf++ = val;
-	return buf;
-}
-
-/* 'val' is still in host byte order! */
-static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag, 
-				 u_int16_t val)
-{
-	*buf++ = tag;
-	*buf++ = val >> 8;
-	*buf++ = val & 0xff;
-	return buf;
-}
-
-static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val)
-{
-	u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
-	return lv_put(buf, len, val);
-}
-
-static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
-{
-	u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
-	return tlv_put(buf, tag, len, val);
-}
-
-static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val)
-{
-	u_int8_t *buf = msgb_put(msg, 2);
-	return tv_put(buf, tag, val);
-}
-
-static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val)
-{
-	u_int8_t *buf = msgb_put(msg, 1);
-	return v_put(buf, val);
-}
-
-static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
-{
-	u_int8_t *buf = msgb_put(msg, 3);
-	return tv16_put(buf, tag, val);
-}
-
-static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
-{
-	u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
-	return tlv_put(buf, tag, len, val);
-}
-
-static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val)
-{
-	u_int8_t *buf = msgb_push(msg, 2);
-	return tv_put(buf, tag, val);
-}
-
-static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val)
-{
-	u_int8_t *buf = msgb_push(msg, 3);
-	return tv16_put(buf, tag, val);
-}
-
-/* TLV parsing */
-
-struct tlv_p_entry {
-	u_int16_t len;
-	const u_int8_t *val;
-};
-
-enum tlv_type {
-	TLV_TYPE_NONE,
-	TLV_TYPE_FIXED,
-	TLV_TYPE_T,
-	TLV_TYPE_TV,
-	TLV_TYPE_TLV,
-	TLV_TYPE_TL16V,
-	TLV_TYPE_TvLV,
-};
-
-struct tlv_def {
-	enum tlv_type type;
-	u_int8_t fixed_len;
-};
-
-struct tlv_definition {
-	struct tlv_def def[0xff];
-};
-
-struct tlv_parsed {
-	struct tlv_p_entry lv[0xff];
-};
-
-extern struct tlv_definition tvlv_att_def;
-
-int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val,
-                  const struct tlv_definition *def,
-                  const u_int8_t *buf, int buf_len);
-int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
-	      const u_int8_t *buf, int buf_len, u_int8_t lv_tag, u_int8_t lv_tag2);
-/* take a master (src) tlvdev and fill up all empty slots in 'dst' */
-void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src);
-
-#define TLVP_PRESENT(x, y)	((x)->lv[y].val)
-#define TLVP_LEN(x, y)		(x)->lv[y].len
-#define TLVP_VAL(x, y)		(x)->lv[y].val
-
-#endif /* _TLV_H */
diff --git a/openbsc/include/openbsc/transaction.h b/openbsc/include/openbsc/transaction.h
index cf94100..50c3cc5 100644
--- a/openbsc/include/openbsc/transaction.h
+++ b/openbsc/include/openbsc/transaction.h
@@ -3,7 +3,7 @@
 
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_subscriber.h>
-#include <openbsc/linuxlist.h>
+#include <osmocore/linuxlist.h>
 #include <openbsc/gsm_04_11.h>
 
 /* One transaction */
diff --git a/openbsc/include/openbsc/ussd.h b/openbsc/include/openbsc/ussd.h
index e7bd6d6..63ea31c 100644
--- a/openbsc/include/openbsc/ussd.h
+++ b/openbsc/include/openbsc/ussd.h
@@ -3,7 +3,7 @@
 
 /* Handler function for mobile-originated USSD messages */
 
-#include <openbsc/msgb.h>
+#include <osmocore/msgb.h>
 
 int handle_rcv_ussd(struct msgb *msg);
 
diff --git a/openbsc/include/sccp/Makefile.am b/openbsc/include/sccp/Makefile.am
index 42fd310..6c8a517 100644
--- a/openbsc/include/sccp/Makefile.am
+++ b/openbsc/include/sccp/Makefile.am
@@ -1 +1,2 @@
-noinst_HEADERS = sccp_types.h sccp.h
+sccp_HEADERS = sccp_types.h sccp.h
+sccpdir = $(includedir)/sccp
diff --git a/openbsc/include/sccp/sccp.h b/openbsc/include/sccp/sccp.h
index 3ad568c..643479a 100644
--- a/openbsc/include/sccp/sccp.h
+++ b/openbsc/include/sccp/sccp.h
@@ -1,7 +1,7 @@
 /*
  * SCCP management code
  *
- * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
  *
  * All Rights Reserved
  *
@@ -27,11 +27,11 @@
 #include <stdlib.h>
 
 #include <sys/socket.h>
-
-#include <openbsc/msgb.h>
+#include <sys/types.h>
 
 #include "sccp_types.h"
 
+struct msgb;
 struct sccp_system;
 
 enum {
@@ -143,4 +143,25 @@
 u_int32_t sccp_src_ref_to_int(struct sccp_source_reference *ref);
 struct sccp_source_reference sccp_src_ref_from_int(u_int32_t);
 
+/**
+ * Below this are helper functions and structs for parsing SCCP messages
+ */
+struct sccp_parse_result {
+	struct sccp_address called;
+	struct sccp_address calling;
+
+	/* point to the msg packet */
+	struct sccp_source_reference *source_local_reference;
+	struct sccp_source_reference *destination_local_reference;
+
+	/* data pointer */
+	int data_len;
+};
+
+/*
+ * helper functions for the nat code
+ */
+int sccp_determine_msg_type(struct msgb *msg);
+int sccp_parse_header(struct msgb *msg, struct sccp_parse_result *result);
+
 #endif
diff --git a/openbsc/include/sccp/sccp_types.h b/openbsc/include/sccp/sccp_types.h
index 9310a6b..42fda96 100644
--- a/openbsc/include/sccp/sccp_types.h
+++ b/openbsc/include/sccp/sccp_types.h
@@ -24,6 +24,8 @@
 #ifndef SCCP_TYPES_H
 #define SCCP_TYPES_H
 
+#include <endian.h>
+
 /* Table 1/Q.713 - SCCP message types */
 enum sccp_message_types {
 	SCCP_MSG_TYPE_CR	= 1,
@@ -87,11 +89,19 @@
 };
 
 struct sccp_called_party_address {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 	u_int8_t	point_code_indicator : 1,
 			ssn_indicator	     : 1,
 			global_title_indicator : 4,
 			routing_indicator    : 1,
 			reserved	     : 1;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+	u_int8_t	reserved	     : 1,
+			routing_indicator    : 1,
+			global_title_indicator : 4,
+			ssn_indicator	     : 1,
+			point_code_indicator : 1;
+#endif
 	u_int8_t	data[0];
 } __attribute__((packed));
 
@@ -100,8 +110,13 @@
 /* Figure 6/Q.713 */
 struct sccp_signalling_point_code {
 	u_int8_t	lsb;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 	u_int8_t	msb : 6,
 			reserved : 2;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+	u_int8_t	reserved : 2,
+			msb : 6;
+#endif
 } __attribute__((packed));
 
 /* SSN == subsystem number */
@@ -137,8 +152,13 @@
 };
 
 struct sccp_global_title {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 	u_int8_t	nature_of_addr_ind : 7,
 			odd_even : 1;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+	u_int8_t	odd_even : 1,
+			nature_of_addr_ind : 7;
+#endif
 	u_int8_t	data[0];
 } __attribute__((packed));
 
diff --git a/openbsc/libsccp.pc.in b/openbsc/libsccp.pc.in
new file mode 100644
index 0000000..eda8d49
--- /dev/null
+++ b/openbsc/libsccp.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: OpenBSC SCCP Lib
+Description: OpenBSC SCCP Lib
+Version: @VERSION@
+Libs: -L${libdir} -lsccp
+Cflags: -I${includedir}/
diff --git a/openbsc/openbsc.pc.in b/openbsc/openbsc.pc.in
index 0d00831..aba07e2 100644
--- a/openbsc/openbsc.pc.in
+++ b/openbsc/openbsc.pc.in
@@ -1,7 +1,7 @@
 prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
-includedir=@includedir@/openbsc-1.0
+includedir=@includedir@/
 
 Name: OpenBSC
 Description: OpenBSC base station controller
diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am
index a73399e..5dac9de 100644
--- a/openbsc/src/Makefile.am
+++ b/openbsc/src/Makefile.am
@@ -1,24 +1,28 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS=-Wall
+AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
+AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
 
 sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config \
                 isdnsync bsc_mgcp ipaccess-proxy
-noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libsccp.a
+noinst_LIBRARIES = libbsc.a libmsc.a libvty.a
 noinst_HEADERS = vty/cardshell.h
 
+bscdir = $(libdir)
+bsc_LIBRARIES = libsccp.a
+
 libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
-		msgb.c select.c chan_alloc.c timer.c debug.c \
+		chan_alloc.c debug.c \
 		gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
-		trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \
-		input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \
-		talloc_ctx.c system_information.c bitvec.c rest_octets.c \
-		rtp_proxy.c statistics.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
+		trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
+		input/misdn.c input/ipaccess.c \
+		talloc_ctx.c system_information.c rest_octets.c \
+		rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
 		bts_unknown.c
 
 libmsc_a_SOURCES = gsm_subscriber.c db.c telnet_interface.c \
 		mncc.c gsm_04_08.c gsm_04_11.c transaction.c \
 		token_auth.c rrlp.c gsm_04_80.c ussd.c silent_call.c \
-		handover_logic.c handover_decision.c meas_rep.c comp128.c
+		handover_logic.c handover_decision.c meas_rep.c
 
 libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c
 
@@ -27,11 +31,10 @@
 bsc_hack_SOURCES = bsc_hack.c bsc_init.c vty_interface.c vty_interface_layer3.c
 bsc_hack_LDADD = libmsc.a libbsc.a libmsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
 
-bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c \
-		      select.c timer.c rs232.c tlv_parser.c signal.c talloc.c \
-		      bts_siemens_bs11.c
+bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c debug.c \
+		      rs232.c bts_siemens_bs11.c
 
-ipaccess_find_SOURCES = ipaccess/ipaccess-find.c select.c timer.c
+ipaccess_find_SOURCES = ipaccess/ipaccess-find.c
 
 ipaccess_config_SOURCES = ipaccess/ipaccess-config.c ipaccess/ipaccess-firmware.c
 ipaccess_config_LDADD = libbsc.a libmsc.a libbsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
@@ -39,7 +42,7 @@
 isdnsync_SOURCES = isdnsync.c
 
 bsc_mgcp_SOURCES = mgcp/mgcp_main.c mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c \
-		   msgb.c talloc.c debug.c select.c timer.c telnet_interface.c
+		   debug.c telnet_interface.c
 bsc_mgcp_LDADD = libvty.a
 
-ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c msgb.c select.c talloc.c debug.c timer.c
+ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c debug.c
diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c
index 82d7b02..99d8dd6 100644
--- a/openbsc/src/abis_nm.c
+++ b/openbsc/src/abis_nm.c
@@ -38,12 +38,12 @@
 
 #include <openbsc/gsm_data.h>
 #include <openbsc/debug.h>
-#include <openbsc/msgb.h>
-#include <openbsc/tlv.h>
+#include <osmocore/msgb.h>
+#include <osmocore/tlv.h>
+#include <osmocore/talloc.h>
 #include <openbsc/abis_nm.h>
 #include <openbsc/misdn.h>
 #include <openbsc/signal.h>
-#include <openbsc/talloc.h>
 
 #define OM_ALLOC_SIZE		1024
 #define OM_HEADROOM_SIZE	128
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index 10ebd6d..aebd02c 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -30,12 +30,12 @@
 
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_04_08.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/chan_alloc.h>
 #include <openbsc/bsc_rll.h>
 #include <openbsc/debug.h>
-#include <openbsc/tlv.h>
+#include <osmocore/tlv.h>
 #include <openbsc/paging.h>
 #include <openbsc/signal.h>
 #include <openbsc/meas_rep.h>
diff --git a/openbsc/src/bitvec.c b/openbsc/src/bitvec.c
deleted file mode 100644
index d6f5679..0000000
--- a/openbsc/src/bitvec.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/* bit vector utility routines */
-
-/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-#include <errno.h>
-#include <sys/types.h>
-
-#include <openbsc/bitvec.h>
-
-#define BITNUM_FROM_COMP(byte, bit)	((byte*8)+bit)
-
-static inline unsigned int bytenum_from_bitnum(unsigned int bitnum)
-{
-	unsigned int bytenum = bitnum / 8;
-
-	return bytenum;
-}
-
-/* convert ZERO/ONE/L/H to a bitmask at given pos in a byte */
-static u_int8_t bitval2mask(enum bit_value bit, u_int8_t bitnum)
-{
-	int bitval;
-
-	switch (bit) {
-	case ZERO:
-		bitval = (0 << bitnum);
-		break;
-	case ONE:
-		bitval = (1 << bitnum);
-		break;
-	case L:
-		bitval = ((0x2b ^ (0 << bitnum)) & (1 << bitnum));
-		break;
-	case H:
-		bitval = ((0x2b ^ (1 << bitnum)) & (1 << bitnum));
-		break;
-	default:
-		return 0;
-	}
-	return bitval;
-}
-
-/* check if the bit is 0 or 1 for a given position inside a bitvec */
-enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr)
-{
-	unsigned int bytenum = bytenum_from_bitnum(bitnr);
-	unsigned int bitnum = 7 - (bitnr % 8);
-	u_int8_t bitval;
-
-	if (bytenum >= bv->data_len)
-		return -EINVAL;
-
-	bitval = bitval2mask(ONE, bitnum);
-
-	if (bv->data[bytenum] & bitval)
-		return ONE;
-
-	return ZERO;
-}
-
-/* get the Nth set bit inside the bit vector */
-unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n)
-{
-	unsigned int i, k = 0;
-
-	for (i = 0; i < bv->data_len*8; i++) {
-		if (bitvec_get_bit_pos(bv, i) == ONE) {
-			k++;
-			if (k == n)
-				return i;
-		}
-	}
-
-	return 0;
-}
-
-/* set the bit at a given position inside a bitvec */
-int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
-			enum bit_value bit)
-{
-	unsigned int bytenum = bytenum_from_bitnum(bitnr);
-	unsigned int bitnum = 7 - (bitnr % 8);
-	u_int8_t bitval;
-
-	if (bytenum >= bv->data_len)
-		return -EINVAL;
-
-	/* first clear the bit */
-	bitval = bitval2mask(ONE, bitnum);
-	bv->data[bytenum] &= ~bitval;
-
-	/* then set it to desired value */
-	bitval = bitval2mask(bit, bitnum);
-	bv->data[bytenum] |= bitval;
-
-	return 0;
-}
-
-/* set the next bit inside a bitvec */
-int bitvec_set_bit(struct bitvec *bv, enum bit_value bit)
-{
-	int rc;
-
-	rc = bitvec_set_bit_pos(bv, bv->cur_bit, bit);
-	if (!rc)
-		bv->cur_bit++;
-
-	return rc;
-}
-
-/* set multiple bits (based on array of bitvals) at current pos */
-int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count)
-{
-	int i, rc;
-
-	for (i = 0; i < count; i++) {
-		rc = bitvec_set_bit(bv, bits[i]);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
-
-/* set multiple bits (based on numeric value) at current pos */
-int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits)
-{
-	int i, rc;
-
-	for (i = 0; i < num_bits; i++) {
-		int bit = 0;
-		if (ui & (1 << (num_bits - i - 1)))
-			bit = 1;
-		rc = bitvec_set_bit(bv, bit);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
-
-/* pad all remaining bits up to num_bits */
-int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit)
-{
-	unsigned int i;
-
-	for (i = bv->cur_bit; i <= up_to_bit; i++)
-		bitvec_set_bit(bv, L);
-
-	return 0;
-}
diff --git a/openbsc/src/bs11_config.c b/openbsc/src/bs11_config.c
index 703591e..80f9ba9 100644
--- a/openbsc/src/bs11_config.c
+++ b/openbsc/src/bs11_config.c
@@ -36,10 +36,10 @@
 
 #include <openbsc/gsm_data.h>
 #include <openbsc/abis_nm.h>
-#include <openbsc/msgb.h>
-#include <openbsc/tlv.h>
+#include <osmocore/msgb.h>
+#include <osmocore/tlv.h>
 #include <openbsc/debug.h>
-#include <openbsc/select.h>
+#include <osmocore/select.h>
 #include <openbsc/rs232.h>
 
 /* state of our bs11_config application */
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index 7755726..49c9d36 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -31,10 +31,10 @@
 #include <getopt.h>
 
 #include <openbsc/db.h>
-#include <openbsc/select.h>
+#include <osmocore/select.h>
 #include <openbsc/debug.h>
 #include <openbsc/e1_input.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/signal.h>
 
 /* MCC and MNC for the Location Area Identifier */
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index 622fb98..57fc4b3 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -21,7 +21,7 @@
  */
 
 #include <openbsc/gsm_data.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/abis_nm.h>
@@ -31,7 +31,7 @@
 #include <openbsc/system_information.h>
 #include <openbsc/paging.h>
 #include <openbsc/signal.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 /* global pointer to the gsm network data structure */
 extern struct gsm_network *bsc_gsmnet;
@@ -802,8 +802,10 @@
 		}
 		break;
 	case GSM_BAND_900:
-		if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
-			LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124.\n");
+		if (bts->c0->arfcn < 1 ||
+		   (bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
+		    bts->c0->arfcn > 1023)  {
+			LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
 			return -EINVAL;
 		}
 		break;
diff --git a/openbsc/src/bsc_rll.c b/openbsc/src/bsc_rll.c
index 780a84e..e9d6f25 100644
--- a/openbsc/src/bsc_rll.c
+++ b/openbsc/src/bsc_rll.c
@@ -24,9 +24,9 @@
 #include <errno.h>
 
 #include <openbsc/debug.h>
-#include <openbsc/talloc.h>
-#include <openbsc/timer.h>
-#include <openbsc/linuxlist.h>
+#include <osmocore/talloc.h>
+#include <osmocore/timer.h>
+#include <osmocore/linuxlist.h>
 #include <openbsc/bsc_rll.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/chan_alloc.h>
diff --git a/openbsc/src/bts_ipaccess_nanobts.c b/openbsc/src/bts_ipaccess_nanobts.c
index 6765517..cb48ea9 100644
--- a/openbsc/src/bts_ipaccess_nanobts.c
+++ b/openbsc/src/bts_ipaccess_nanobts.c
@@ -23,7 +23,7 @@
 #include <sys/types.h>
 
 #include <openbsc/gsm_data.h>
-#include <openbsc/tlv.h>
+#include <osmocore/tlv.h>
 #include <openbsc/abis_nm.h>
 
 static struct gsm_bts_model model_nanobts = {
diff --git a/openbsc/src/bts_siemens_bs11.c b/openbsc/src/bts_siemens_bs11.c
index 1c8f889..c966825 100644
--- a/openbsc/src/bts_siemens_bs11.c
+++ b/openbsc/src/bts_siemens_bs11.c
@@ -23,7 +23,7 @@
 #include <sys/types.h>
 
 #include <openbsc/gsm_data.h>
-#include <openbsc/tlv.h>
+#include <osmocore/tlv.h>
 #include <openbsc/abis_nm.h>
 
 static struct gsm_bts_model model_bs11 = {
diff --git a/openbsc/src/bts_unknown.c b/openbsc/src/bts_unknown.c
index 1e604a9..aac5d99 100644
--- a/openbsc/src/bts_unknown.c
+++ b/openbsc/src/bts_unknown.c
@@ -23,7 +23,7 @@
 #include <sys/types.h>
 
 #include <openbsc/gsm_data.h>
-#include <openbsc/tlv.h>
+#include <osmocore/tlv.h>
 #include <openbsc/abis_nm.h>
 
 static struct gsm_bts_model model_unknown = {
diff --git a/openbsc/src/comp128.c b/openbsc/src/comp128.c
deleted file mode 100644
index 9df5452..0000000
--- a/openbsc/src/comp128.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * COMP128 implementation
- *
- *
- * This code is inspired by original code from :
- *  Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>,
- *  and David Wagner <daw@cs.berkeley.edu>
- *
- * But it has been fully rewritten from various PDFs found online describing
- * the algorithm because the licence of the code referenced above was unclear.
- * A comment snippet from the original code is included below, it describes
- * where the doc came from and how the algorithm was reverse engineered.
- *
- *
- * (C) 2009 by Sylvain Munaut <tnt@246tNt.com>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/*
- * --- SNIP ---
- *
- * This code derived from a leaked document from the GSM standards.
- * Some missing pieces were filled in by reverse-engineering a working SIM.
- * We have verified that this is the correct COMP128 algorithm.
- *
- * The first page of the document identifies it as
- * 	_Technical Information: GSM System Security Study_.
- * 	10-1617-01, 10th June 1988.
- * The bottom of the title page is marked
- * 	Racal Research Ltd.
- * 	Worton Drive, Worton Grange Industrial Estate,
- * 	Reading, Berks. RG2 0SB, England.
- * 	Telephone: Reading (0734) 868601   Telex: 847152
- * The relevant bits are in Part I, Section 20 (pages 66--67).  Enjoy!
- *
- * Note: There are three typos in the spec (discovered by
- * reverse-engineering).
- * First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read
- * "z = (2 * x[m] + x[n]) mod 2^(9-j)".
- * Second, the "k" loop in the "Form bits from bytes" section is severely
- * botched: the k index should run only from 0 to 3, and clearly the range
- * on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8,
- * to be consistent with the subsequent section).
- * Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as
- * claimed in the document.  (And the document doesn't specify how Kc is
- * derived, but that was also easily discovered with reverse engineering.)
- * All of these typos have been corrected in the following code.
- *
- * --- /SNIP ---
- */
-
-#include <string.h>
-#include <sys/types.h>
-
-/* The compression tables (just copied ...) */
-static const u_int8_t table_0[512] = {
- 102, 177, 186, 162,   2, 156, 112,  75,  55,  25,   8,  12, 251, 193, 246, 188,
- 109, 213, 151,  53,  42,  79, 191, 115, 233, 242, 164, 223, 209, 148, 108, 161,
- 252,  37, 244,  47,  64, 211,   6, 237, 185, 160, 139, 113,  76, 138,  59,  70,
-  67,  26,  13, 157,  63, 179, 221,  30, 214,  36, 166,  69, 152, 124, 207, 116,
- 247, 194,  41,  84,  71,   1,  49,  14,  95,  35, 169,  21,  96,  78, 215, 225,
- 182, 243,  28,  92, 201, 118,   4,  74, 248, 128,  17,  11, 146, 132, 245,  48,
- 149,  90, 120,  39,  87, 230, 106, 232, 175,  19, 126, 190, 202, 141, 137, 176,
- 250,  27, 101,  40, 219, 227,  58,  20,  51, 178,  98, 216, 140,  22,  32, 121,
-  61, 103, 203,  72,  29, 110,  85, 212, 180, 204, 150, 183,  15,  66, 172, 196,
-  56, 197, 158,   0, 100,  45, 153,   7, 144, 222, 163, 167,  60, 135, 210, 231,
- 174, 165,  38, 249, 224,  34, 220, 229, 217, 208, 241,  68, 206, 189, 125, 255,
- 239,  54, 168,  89, 123, 122,  73, 145, 117, 234, 143,  99, 129, 200, 192,  82,
- 104, 170, 136, 235,  93,  81, 205, 173, 236,  94, 105,  52,  46, 228, 198,   5,
-  57, 254,  97, 155, 142, 133, 199, 171, 187,  50,  65, 181, 127, 107, 147, 226,
- 184, 218, 131,  33,  77,  86,  31,  44,  88,  62, 238,  18,  24,  43, 154,  23,
-  80, 159, 134, 111,   9, 114,   3,  91,  16, 130,  83,  10, 195, 240, 253, 119,
- 177, 102, 162, 186, 156,   2,  75, 112,  25,  55,  12,   8, 193, 251, 188, 246,
- 213, 109,  53, 151,  79,  42, 115, 191, 242, 233, 223, 164, 148, 209, 161, 108,
-  37, 252,  47, 244, 211,  64, 237,   6, 160, 185, 113, 139, 138,  76,  70,  59,
-  26,  67, 157,  13, 179,  63,  30, 221,  36, 214,  69, 166, 124, 152, 116, 207,
- 194, 247,  84,  41,   1,  71,  14,  49,  35,  95,  21, 169,  78,  96, 225, 215,
- 243, 182,  92,  28, 118, 201,  74,   4, 128, 248,  11,  17, 132, 146,  48, 245,
-  90, 149,  39, 120, 230,  87, 232, 106,  19, 175, 190, 126, 141, 202, 176, 137,
-  27, 250,  40, 101, 227, 219,  20,  58, 178,  51, 216,  98,  22, 140, 121,  32,
- 103,  61,  72, 203, 110,  29, 212,  85, 204, 180, 183, 150,  66,  15, 196, 172,
- 197,  56,   0, 158,  45, 100,   7, 153, 222, 144, 167, 163, 135,  60, 231, 210,
- 165, 174, 249,  38,  34, 224, 229, 220, 208, 217,  68, 241, 189, 206, 255, 125,
-  54, 239,  89, 168, 122, 123, 145,  73, 234, 117,  99, 143, 200, 129,  82, 192,
- 170, 104, 235, 136,  81,  93, 173, 205,  94, 236,  52, 105, 228,  46,   5, 198,
- 254,  57, 155,  97, 133, 142, 171, 199,  50, 187, 181,  65, 107, 127, 226, 147,
- 218, 184,  33, 131,  86,  77,  44,  31,  62,  88,  18, 238,  43,  24,  23, 154,
- 159,  80, 111, 134, 114,   9,  91,   3, 130,  16,  10,  83, 240, 195, 119, 253,
-}, table_1[256] = {
-  19,  11,  80, 114,  43,   1,  69,  94,  39,  18, 127, 117,  97,   3,  85,  43,
-  27, 124,  70,  83,  47,  71,  63,  10,  47,  89,  79,   4,  14,  59,  11,   5,
-  35, 107, 103,  68,  21,  86,  36,  91,  85, 126,  32,  50, 109,  94, 120,   6,
-  53,  79,  28,  45,  99,  95,  41,  34,  88,  68,  93,  55, 110, 125, 105,  20,
-  90,  80,  76,  96,  23,  60,  89,  64, 121,  56,  14,  74, 101,   8,  19,  78,
-  76,  66, 104,  46, 111,  50,  32,   3,  39,   0,  58,  25,  92,  22,  18,  51,
-  57,  65, 119, 116,  22, 109,   7,  86,  59,  93,  62, 110,  78,  99,  77,  67,
-  12, 113,  87,  98, 102,   5,  88,  33,  38,  56,  23,   8,  75,  45,  13,  75,
-  95,  63,  28,  49, 123, 120,  20, 112,  44,  30,  15,  98, 106,   2, 103,  29,
-  82, 107,  42, 124,  24,  30,  41,  16, 108, 100, 117,  40,  73,  40,   7, 114,
-  82, 115,  36, 112,  12, 102, 100,  84,  92,  48,  72,  97,   9,  54,  55,  74,
- 113, 123,  17,  26,  53,  58,   4,   9,  69, 122,  21, 118,  42,  60,  27,  73,
- 118, 125,  34,  15,  65, 115,  84,  64,  62,  81,  70,   1,  24, 111, 121,  83,
- 104,  81,  49, 127,  48, 105,  31,  10,   6,  91,  87,  37,  16,  54, 116, 126,
-  31,  38,  13,   0,  72, 106,  77,  61,  26,  67,  46,  29,  96,  37,  61,  52,
- 101,  17,  44, 108,  71,  52,  66,  57,  33,  51,  25,  90,   2, 119, 122,  35,
-}, table_2[128] = {
- 52,  50,  44,   6,  21,  49,  41,  59,  39,  51,  25,  32,  51,  47,  52,  43,
- 37,   4,  40,  34,  61,  12,  28,   4,  58,  23,   8,  15,  12,  22,   9,  18,
- 55,  10,  33,  35,  50,   1,  43,   3,  57,  13,  62,  14,   7,  42,  44,  59,
- 62,  57,  27,   6,   8,  31,  26,  54,  41,  22,  45,  20,  39,   3,  16,  56,
- 48,   2,  21,  28,  36,  42,  60,  33,  34,  18,   0,  11,  24,  10,  17,  61,
- 29,  14,  45,  26,  55,  46,  11,  17,  54,  46,   9,  24,  30,  60,  32,   0,
- 20,  38,   2,  30,  58,  35,   1,  16,  56,  40,  23,  48,  13,  19,  19,  27,
- 31,  53,  47,  38,  63,  15,  49,   5,  37,  53,  25,  36,  63,  29,   5,   7,
-}, table_3[64] = {
-  1,   5,  29,   6,  25,   1,  18,  23,  17,  19,   0,   9,  24,  25,   6,  31,
- 28,  20,  24,  30,   4,  27,   3,  13,  15,  16,  14,  18,   4,   3,   8,   9,
- 20,   0,  12,  26,  21,   8,  28,   2,  29,   2,  15,   7,  11,  22,  14,  10,
- 17,  21,  12,  30,  26,  27,  16,  31,  11,   7,  13,  23,  10,   5,  22,  19,
-}, table_4[32] = {
- 15,  12,  10,   4,   1,  14,  11,   7,   5,   0,  14,   7,   1,   2,  13,   8,
- 10,   3,   4,   9,   6,   0,   3,   2,   5,   6,   8,   9,  11,  13,  15,  12,
-};
-
-static const u_int8_t *_comp128_table[5] = { table_0, table_1, table_2, table_3, table_4 };
-
-
-static inline void
-_comp128_compression_round(u_int8_t *x, int n, const u_int8_t *tbl)
-{
-	int i, j, m, a, b, y, z;
-	m = 4 - n;
-	for (i=0; i<(1<<n); i++)
-		for (j=0; j<(1<<m); j++) {
-			a = j + i * (2<<m);
-			b = a + (1<<m);
-			y = (x[a] + (x[b]<<1)) & ((32<<m)-1);
-			z = ((x[a]<<1) + x[b]) & ((32<<m)-1);
-			x[a] = tbl[y];
-			x[b] = tbl[z];
-		}
-}
-
-static inline void
-_comp128_compression(u_int8_t *x)
-{
-	int n;
-	for (n=0; n<5; n++)
-		_comp128_compression_round(x, n, _comp128_table[n]);
-}
-
-static inline void
-_comp128_bitsfrombytes(u_int8_t *x, u_int8_t *bits)
-{
-	int i;
-	memset(bits, 0x00, 128);
-	for (i=0; i<128; i++)
-		if (x[i>>2] & (1<<(3-(i&3))))
-			bits[i] = 1;
-}
-
-static inline void
-_comp128_permutation(u_int8_t *x, u_int8_t *bits)
-{
-	int i;
-	memset(&x[16], 0x00, 16);
-	for (i=0; i<128; i++)
-		x[(i>>3)+16] |= bits[(i*17) & 127] << (7-(i&7));
-}
-
-void
-comp128(u_int8_t *ki, u_int8_t *rand, u_int8_t *sres, u_int8_t *kc)
-{
-	int i;
-	u_int8_t x[32], bits[128];
-
-	/* x[16-31] = RAND */
-	memcpy(&x[16], rand, 16);
-
-	/* Round 1-7 */
-	for (i=0; i<7; i++) {
-		/* x[0-15] = Ki */
-		memcpy(x, ki, 16);
-
-		/* Compression */
-		_comp128_compression(x);
-
-		/* FormBitFromBytes */
-		_comp128_bitsfrombytes(x, bits);
-
-		/* Permutation */
-		_comp128_permutation(x, bits);
-	}
-
-	/* Round 8 (final) */
-		/* x[0-15] = Ki */
-	memcpy(x, ki, 16);
-
-		/* Compression */
-	_comp128_compression(x);
-
-	/* Output stage */
-	for (i=0; i<8; i+=2)
-		sres[i>>1] = x[i]<<4 | x[i+1];
-
-	for (i=0; i<12; i+=2)
-		kc[i>>1] = (x[i + 18] << 6) |
-		           (x[i + 19] << 2) |
-		           (x[i + 20] >> 2);
-
-	kc[6] = (x[30]<<6) | (x[31]<<2);
-	kc[7] = 0;
-}
-
diff --git a/openbsc/src/db.c b/openbsc/src/db.c
index 5be47ff..10c1d6d 100644
--- a/openbsc/src/db.c
+++ b/openbsc/src/db.c
@@ -23,9 +23,9 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_04_11.h>
 #include <openbsc/db.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/debug.h>
-#include <openbsc/statistics.h>
+#include <osmocore/statistics.h>
 
 #include <libgen.h>
 #include <stdio.h>
diff --git a/openbsc/src/debug.c b/openbsc/src/debug.c
index 90a9fc7..7488cd6 100644
--- a/openbsc/src/debug.c
+++ b/openbsc/src/debug.c
@@ -28,7 +28,7 @@
 #include <errno.h>
 
 #include <openbsc/debug.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_subscriber.h>
 
diff --git a/openbsc/src/e1_config.c b/openbsc/src/e1_config.c
index 6a2abd8..50fbcec 100644
--- a/openbsc/src/e1_config.c
+++ b/openbsc/src/e1_config.c
@@ -9,7 +9,7 @@
 #include <openbsc/trau_mux.h>
 #include <openbsc/misdn.h>
 #include <openbsc/ipaccess.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/debug.h>
 
 #define SAPI_L2ML	0
diff --git a/openbsc/src/e1_input.c b/openbsc/src/e1_input.c
index c894fe4..c20359c 100644
--- a/openbsc/src/e1_input.c
+++ b/openbsc/src/e1_input.c
@@ -40,18 +40,18 @@
 #define PF_ISDN AF_ISDN
 #endif
 
-#include <openbsc/select.h>
-#include <openbsc/msgb.h>
+#include <osmocore/select.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/e1_input.h>
 #include <openbsc/abis_nm.h>
 #include <openbsc/abis_rsl.h>
-#include <openbsc/linuxlist.h>
+#include <osmocore/linuxlist.h>
 #include <openbsc/subchan_demux.h>
 #include <openbsc/trau_frame.h>
 #include <openbsc/trau_mux.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/signal.h>
 #include <openbsc/misdn.h>
 
diff --git a/openbsc/src/gsm_04_08.c b/openbsc/src/gsm_04_08.c
index 61eba2c..3aebd7f 100644
--- a/openbsc/src/gsm_04_08.c
+++ b/openbsc/src/gsm_04_08.c
@@ -31,12 +31,12 @@
 #include <netinet/in.h>
 
 #include <openbsc/db.h>
-#include <openbsc/msgb.h>
-#include <openbsc/bitvec.h>
-#include <openbsc/tlv.h>
+#include <osmocore/msgb.h>
+#include <osmocore/bitvec.h>
+#include <osmocore/tlv.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/gsm_04_11.h>
 #include <openbsc/gsm_04_08.h>
@@ -47,7 +47,7 @@
 #include <openbsc/trau_frame.h>
 #include <openbsc/trau_mux.h>
 #include <openbsc/rtp_proxy.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/transaction.h>
 #include <openbsc/ussd.h>
 #include <openbsc/silent_call.h>
diff --git a/openbsc/src/gsm_04_08_utils.c b/openbsc/src/gsm_04_08_utils.c
index 821bde2..53c57ca 100644
--- a/openbsc/src/gsm_04_08_utils.c
+++ b/openbsc/src/gsm_04_08_utils.c
@@ -28,7 +28,7 @@
 #include <errno.h>
 #include <netinet/in.h>
 
-#include <openbsc/msgb.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/transaction.h>
diff --git a/openbsc/src/gsm_04_11.c b/openbsc/src/gsm_04_11.c
index 7f570b8..f03c666 100644
--- a/openbsc/src/gsm_04_11.c
+++ b/openbsc/src/gsm_04_11.c
@@ -31,18 +31,18 @@
 #include <time.h>
 #include <netinet/in.h>
 
-#include <openbsc/msgb.h>
-#include <openbsc/tlv.h>
+#include <osmocore/msgb.h>
+#include <osmocore/tlv.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/gsm_04_11.h>
 #include <openbsc/gsm_04_08.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/signal.h>
 #include <openbsc/db.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/transaction.h>
 #include <openbsc/paging.h>
 #include <openbsc/bsc_rll.h>
diff --git a/openbsc/src/gsm_04_80.c b/openbsc/src/gsm_04_80.c
index d3b472f..8271274 100644
--- a/openbsc/src/gsm_04_80.c
+++ b/openbsc/src/gsm_04_80.c
@@ -29,11 +29,11 @@
 #include <string.h>
 #include <errno.h>
 
-#include <openbsc/msgb.h>
-#include <openbsc/tlv.h>
+#include <osmocore/msgb.h>
+#include <osmocore/tlv.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/gsm_04_80.h>
 
diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c
index 1f2e1a1..a6b060c 100644
--- a/openbsc/src/gsm_data.c
+++ b/openbsc/src/gsm_data.c
@@ -26,9 +26,9 @@
 #include <ctype.h>
 
 #include <openbsc/gsm_data.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/abis_nm.h>
-#include <openbsc/statistics.h>
+#include <osmocore/statistics.h>
 
 void *tall_bsc_ctx;
 
@@ -438,8 +438,14 @@
 char *gsm_band_name(enum gsm_band band)
 {
 	switch (band) {
-	case GSM_BAND_400:
-		return "GSM400";
+	case GSM_BAND_450:
+		return "GSM450";
+	case GSM_BAND_480:
+		return "GSM450";
+	case GSM_BAND_750:
+		return "GSM750";
+	case GSM_BAND_810:
+		return "GSM810";
 	case GSM_BAND_850:
 		return "GSM850";
 	case GSM_BAND_900:
@@ -461,8 +467,14 @@
 		return -EINVAL;
 
 	switch (atoi(mhz)) {
-	case 400:
-		return GSM_BAND_400;
+	case 450:
+		return GSM_BAND_450;
+	case 480:
+		return GSM_BAND_480;
+	case 750:
+		return GSM_BAND_750;
+	case 810:
+		return GSM_BAND_810;
 	case 850:
 		return GSM_BAND_850;
 	case 900:
diff --git a/openbsc/src/gsm_subscriber_base.c b/openbsc/src/gsm_subscriber_base.c
index 0570061..dee89c0 100644
--- a/openbsc/src/gsm_subscriber_base.c
+++ b/openbsc/src/gsm_subscriber_base.c
@@ -27,11 +27,10 @@
 #include <string.h>
 #include <assert.h>
 
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/paging.h>
 #include <openbsc/debug.h>
-#include <openbsc/paging.h>
 
 LLIST_HEAD(active_subscribers);
 void *tall_subscr_ctx;
diff --git a/openbsc/src/gsm_utils.c b/openbsc/src/gsm_utils.c
deleted file mode 100644
index 9439993..0000000
--- a/openbsc/src/gsm_utils.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
- * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <openbsc/gsm_data.h>
-#include <openbsc/gsm_utils.h>
-#include <execinfo.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-/* GSM 03.38 6.2.1 Charachter packing */
-int gsm_7bit_decode(char *text, const u_int8_t *user_data, u_int8_t length)
-{
-	int i = 0;
-	int l = 0;
-
-        /* FIXME: We need to account for user data headers here */
-	i += l;
-	for (; i < length; i ++)
-		*(text ++) =
-			((user_data[(i * 7 + 7) >> 3] <<
-			  (7 - ((i * 7 + 7) & 7))) |
-			 (user_data[(i * 7) >> 3] >>
-			  ((i * 7) & 7))) & 0x7f;
-	*text = '\0';
-
-	return i - l;
-}
-
-
-/* GSM 03.38 6.2.1 Charachter packing */
-int gsm_7bit_encode(u_int8_t *result, const char *data)
-{
-	int i,j = 0;
-	unsigned char ch1, ch2;
-	int shift = 0;
-
-	for ( i=0; i<strlen(data); i++ ) {
-
-		ch1 = data[i] & 0x7F;
-		ch1 = ch1 >> shift;
-		ch2 = data[(i+1)] & 0x7F;
-		ch2 = ch2 << (7-shift);
-
-		ch1 = ch1 | ch2;
-
-		result[j++] = ch1;
-
-		shift++;
-
-		if ((shift == 7) && (i+1<strlen(data))) {
-			shift = 0;
-			i++;
-		}
-	}
-
-	return i;
-}
-
-/* determine power control level for given dBm value, as indicated
- * by the tables in chapter 4.1.1 of GSM TS 05.05 */
-int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm)
-{
-	switch (band) {
-	case GSM_BAND_400:
-	case GSM_BAND_900:
-	case GSM_BAND_850:
-		if (dbm >= 39)
-			return 0;
-		else if (dbm < 5)
-			return 19;
-		else {
-			/* we are guaranteed to have (5 <= dbm < 39) */
-			return 2 + ((39 - dbm) / 2);
-		}
-		break;
-	case GSM_BAND_1800:
-		if (dbm >= 36)
-			return 29;
-		else if (dbm >= 34)	
-			return 30;
-		else if (dbm >= 32)
-			return 31;
-		else if (dbm == 31)
-			return 0;
-		else {
-			/* we are guaranteed to have (0 <= dbm < 31) */
-			return (30 - dbm) / 2;
-		}
-		break;
-	case GSM_BAND_1900:
-		if (dbm >= 33)
-			return 30;
-		else if (dbm >= 32)
-			return 31;
-		else if (dbm == 31)
-			return 0;
-		else {
-			/* we are guaranteed to have (0 <= dbm < 31) */
-			return (30 - dbm) / 2;
-		}
-		break;
-	}
-	return -EINVAL;
-}
-
-int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl)
-{
-	lvl &= 0x1f;
-
-	switch (band) {
-	case GSM_BAND_400:
-	case GSM_BAND_900:
-	case GSM_BAND_850:
-		if (lvl < 2)
-			return 39;
-		else if (lvl < 20)
-			return 39 - ((lvl - 2) * 2) ;
-		else
-			return 5;
-		break;
-	case GSM_BAND_1800:
-		if (lvl < 16)
-			return 30 - (lvl * 2);
-		else if (lvl < 29)
-			return 0;
-		else
-			return 36 - ((lvl - 29) * 2);
-		break;
-	case GSM_BAND_1900:
-		if (lvl < 16)
-			return 30 - (lvl * 2);
-		else if (lvl < 30)
-			return -EINVAL;
-		else
-			return 33 - (lvl - 30);
-		break;
-	}
-	return -EINVAL;
-}
-
-/* According to TS 08.05 Chapter 8.1.4 */
-int rxlev2dbm(u_int8_t rxlev)
-{
-	if (rxlev > 63)
-		rxlev = 63;
-
-	return -110 + rxlev;
-}
-
-/* According to TS 08.05 Chapter 8.1.4 */
-u_int8_t dbm2rxlev(int dbm)
-{
-	int rxlev = dbm + 110;
-
-	if (rxlev > 63)
-		rxlev = 63;
-	else if (rxlev < 0)
-		rxlev = 0;
-
-	return rxlev;
-}
-
-void generate_backtrace()
-{
-	int i, nptrs;
-	void *buffer[100];
-	char **strings;
-
-	nptrs = backtrace(buffer, ARRAY_SIZE(buffer));
-	printf("backtrace() returned %d addresses\n", nptrs);
-
-	strings = backtrace_symbols(buffer, nptrs);
-	if (!strings)
-		return;
-
-	for (i = 1; i < nptrs; i++)
-		printf("%s\n", strings[i]);
-
-	free(strings);
-}
diff --git a/openbsc/src/handover_decision.c b/openbsc/src/handover_decision.c
index b37cecd..efafca6 100644
--- a/openbsc/src/handover_decision.c
+++ b/openbsc/src/handover_decision.c
@@ -25,14 +25,14 @@
 #include <stdlib.h>
 #include <errno.h>
 
-#include <openbsc/msgb.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/meas_rep.h>
 #include <openbsc/signal.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/handover.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 
 /* issue handover to a cell identified by ARFCN and BSIC */
 static int handover_to_arfcn_bsic(struct gsm_lchan *lchan,
diff --git a/openbsc/src/handover_logic.c b/openbsc/src/handover_logic.c
index 1bf048f..bd4c563 100644
--- a/openbsc/src/handover_logic.c
+++ b/openbsc/src/handover_logic.c
@@ -29,16 +29,16 @@
 #include <time.h>
 #include <netinet/in.h>
 
-#include <openbsc/msgb.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/chan_alloc.h>
 #include <openbsc/signal.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/transaction.h>
 #include <openbsc/rtp_proxy.h>
 
diff --git a/openbsc/src/input/ipaccess.c b/openbsc/src/input/ipaccess.c
index 90d7cea..943a5e8 100644
--- a/openbsc/src/input/ipaccess.c
+++ b/openbsc/src/input/ipaccess.c
@@ -32,9 +32,9 @@
 #include <sys/ioctl.h>
 #include <arpa/inet.h>
 
-#include <openbsc/select.h>
-#include <openbsc/tlv.h>
-#include <openbsc/msgb.h>
+#include <osmocore/select.h>
+#include <osmocore/tlv.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/abis_nm.h>
@@ -42,7 +42,7 @@
 #include <openbsc/subchan_demux.h>
 #include <openbsc/e1_input.h>
 #include <openbsc/ipaccess.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 /* data structure for one E1 interface with A-bis */
 struct ia_e1_handle {
@@ -89,7 +89,7 @@
 	return idtag_names[tag];
 }
 
-static int ipac_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len)
+int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len)
 {
 	u_int8_t t_len;
 	u_int8_t t_tag;
@@ -164,6 +164,17 @@
 	return 0;
 }
 
+/* send the id ack */
+int ipaccess_send_id_ack(int fd)
+{
+	return write(fd, id_ack, sizeof(id_ack));
+}
+
+int ipaccess_send_id_req(int fd)
+{
+	return write(fd, id_req, sizeof(id_req));
+}
+
 /* base handling of the ip.access protocol */
 int ipaccess_rcvmsg_base(struct msgb *msg,
 			 struct bsc_fd *bfd)
@@ -180,7 +191,7 @@
 		break;
 	case IPAC_MSGT_ID_ACK:
 		DEBUGP(DMI, "ID_ACK? -> ACK!\n");
-		ret = write(bfd->fd, id_ack, sizeof(id_ack));
+		ret = ipaccess_send_id_ack(bfd->fd);
 		break;
 	}
 	return 0;
@@ -201,7 +212,7 @@
 	case IPAC_MSGT_ID_RESP:
 		DEBUGP(DMI, "ID_RESP ");
 		/* parse tags, search for Unit ID */
-		ipac_idtag_parse(&tlvp, (u_int8_t *)msg->l2h + 2,
+		ipaccess_idtag_parse(&tlvp, (u_int8_t *)msg->l2h + 2,
 				 msgb_l2len(msg)-2);
 		DEBUGP(DMI, "\n");
 
@@ -530,7 +541,7 @@
 	}
 
 	/* Request ID. FIXME: request LOCATION, HW/SW VErsion, Unit Name, Serno */
-	ret = write(bfd->fd, id_req, sizeof(id_req));
+	ret = ipaccess_send_id_req(bfd->fd);
 
         return ret;
 	//return e1inp_line_register(line);
@@ -587,6 +598,11 @@
 	bfd->when = BSC_FD_READ;
 	//bfd->data = line;
 
+	if (bfd->fd < 0) {
+		LOGP(DINP, LOGL_ERROR, "could not create TCP socket.\n");
+		return -EIO;
+	}
+
 	memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
 	addr.sin_port = htons(port);
@@ -598,18 +614,21 @@
 	if (ret < 0) {
 		LOGP(DINP, LOGL_ERROR, "could not bind l2 socket %s\n",
 			strerror(errno));
+		close(bfd->fd);
 		return -EIO;
 	}
 
 	ret = listen(bfd->fd, 1);
 	if (ret < 0) {
 		perror("listen");
+		close(bfd->fd);
 		return ret;
 	}
 	
 	ret = bsc_register_fd(bfd);
 	if (ret < 0) {
 		perror("register_listen_fd");
+		close(bfd->fd);
 		return ret;
 	}
 	return 0;
@@ -628,6 +647,11 @@
 	bfd->data = line;
 	bfd->priv_nr = 1;
 
+	if (bfd->fd < 0) {
+		LOGP(DINP, LOGL_ERROR, "could not create TCP socket.\n");
+		return -EIO;
+	}
+
 	setsockopt(bfd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
 
 	ret = connect(bfd->fd, (struct sockaddr *) sa, sizeof(*sa));
diff --git a/openbsc/src/input/misdn.c b/openbsc/src/input/misdn.c
index 135cfad..56930d4 100644
--- a/openbsc/src/input/misdn.c
+++ b/openbsc/src/input/misdn.c
@@ -41,15 +41,15 @@
 #define PF_ISDN AF_ISDN
 #endif
 
-#include <openbsc/select.h>
-#include <openbsc/msgb.h>
+#include <osmocore/select.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/abis_nm.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/subchan_demux.h>
 #include <openbsc/e1_input.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 #define TS1_ALLOC_SIZE	300
 
diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c
index 7d559b0..037ed60 100644
--- a/openbsc/src/ipaccess/ipaccess-config.c
+++ b/openbsc/src/ipaccess/ipaccess-config.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <getopt.h>
+#include <errno.h>
 #include <sys/fcntl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -35,15 +36,15 @@
 #include <arpa/inet.h>
 
 
-#include <openbsc/select.h>
-#include <openbsc/timer.h>
+#include <osmocore/select.h>
+#include <osmocore/timer.h>
 #include <openbsc/ipaccess.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/e1_input.h>
 #include <openbsc/abis_nm.h>
 #include <openbsc/signal.h>
 #include <openbsc/debug.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 static struct gsm_network *gsmnet;
 
diff --git a/openbsc/src/ipaccess/ipaccess-find.c b/openbsc/src/ipaccess/ipaccess-find.c
index f469b67..01f8a2d 100644
--- a/openbsc/src/ipaccess/ipaccess-find.c
+++ b/openbsc/src/ipaccess/ipaccess-find.c
@@ -8,8 +8,8 @@
 #include <arpa/inet.h>
 
 
-#include <openbsc/select.h>
-#include <openbsc/timer.h>
+#include <osmocore/select.h>
+#include <osmocore/timer.h>
 #include <openbsc/ipaccess.h>
 #include <openbsc/gsm_data.h>
 
diff --git a/openbsc/src/ipaccess/ipaccess-firmware.c b/openbsc/src/ipaccess/ipaccess-firmware.c
index ed4bc9a..8aba509 100644
--- a/openbsc/src/ipaccess/ipaccess-firmware.c
+++ b/openbsc/src/ipaccess/ipaccess-firmware.c
@@ -21,7 +21,7 @@
 
 #include <openbsc/debug.h>
 #include <openbsc/ipaccess.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/openbsc/src/ipaccess/ipaccess-proxy.c b/openbsc/src/ipaccess/ipaccess-proxy.c
index d018b6e..217e0bd 100644
--- a/openbsc/src/ipaccess/ipaccess-proxy.c
+++ b/openbsc/src/ipaccess/ipaccess-proxy.c
@@ -35,12 +35,12 @@
 #include <netinet/in.h>
 
 #include <openbsc/gsm_data.h>
-#include <openbsc/select.h>
-#include <openbsc/tlv.h>
-#include <openbsc/msgb.h>
+#include <osmocore/select.h>
+#include <osmocore/tlv.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/ipaccess.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 static struct debug_target *stderr_target;
 
diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c
index 32abef2..cea0ba4 100644
--- a/openbsc/src/mgcp/mgcp_main.c
+++ b/openbsc/src/mgcp/mgcp_main.c
@@ -33,10 +33,10 @@
 #include <sys/socket.h>
 
 #include <openbsc/debug.h>
-#include <openbsc/msgb.h>
-#include <openbsc/talloc.h>
+#include <osmocore/msgb.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_data.h>
-#include <openbsc/select.h>
+#include <osmocore/select.h>
 #include <openbsc/mgcp.h>
 #include <openbsc/telnet_interface.h>
 
diff --git a/openbsc/src/mgcp/mgcp_network.c b/openbsc/src/mgcp/mgcp_network.c
index c61f0a8..b76ca47 100644
--- a/openbsc/src/mgcp/mgcp_network.c
+++ b/openbsc/src/mgcp/mgcp_network.c
@@ -29,12 +29,13 @@
 #include <sys/socket.h>
 #include <arpa/inet.h>
 
+#include <osmocore/msgb.h>
+#include <osmocore/talloc.h>
+#include <osmocore/select.h>
+
 #include <openbsc/debug.h>
 #include <openbsc/mgcp.h>
 #include <openbsc/mgcp_internal.h>
-#include <openbsc/msgb.h>
-#include <openbsc/talloc.h>
-#include <openbsc/select.h>
 
 #warning "Make use of the rtp proxy code"
 
diff --git a/openbsc/src/mgcp/mgcp_protocol.c b/openbsc/src/mgcp/mgcp_protocol.c
index e97f1f4..f7ef547 100644
--- a/openbsc/src/mgcp/mgcp_protocol.c
+++ b/openbsc/src/mgcp/mgcp_protocol.c
@@ -31,10 +31,10 @@
 #include <unistd.h>
 
 #include <openbsc/debug.h>
-#include <openbsc/msgb.h>
-#include <openbsc/talloc.h>
+#include <osmocore/msgb.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_data.h>
-#include <openbsc/select.h>
+#include <osmocore/select.h>
 #include <openbsc/mgcp.h>
 #include <openbsc/mgcp_internal.h>
 
diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c
index d77646d..f13b3cf 100644
--- a/openbsc/src/mgcp/mgcp_vty.c
+++ b/openbsc/src/mgcp/mgcp_vty.c
@@ -24,10 +24,11 @@
 
 #include <sys/types.h>
 
+#include <osmocore/talloc.h>
+
 #include <openbsc/debug.h>
 #include <openbsc/mgcp.h>
 #include <openbsc/mgcp_internal.h>
-#include <openbsc/talloc.h>
 
 #include <vty/command.h>
 #include <vty/vty.h>
diff --git a/openbsc/src/mncc.c b/openbsc/src/mncc.c
index 15e2978..01d59aa 100644
--- a/openbsc/src/mncc.c
+++ b/openbsc/src/mncc.c
@@ -28,7 +28,7 @@
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/debug.h>
 #include <openbsc/mncc.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/transaction.h>
 #include <openbsc/rtp_proxy.h>
diff --git a/openbsc/src/msgb.c b/openbsc/src/msgb.c
deleted file mode 100644
index 9f2fcfa..0000000
--- a/openbsc/src/msgb.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-
-#include <openbsc/msgb.h>
-#include <openbsc/gsm_data.h>
-#include <openbsc/talloc.h>
-#include <openbsc/debug.h>
-
-void *tall_msgb_ctx;
-
-struct msgb *msgb_alloc(u_int16_t size, const char *name)
-{
-	struct msgb *msg;
-
-	msg = _talloc_zero(tall_msgb_ctx, sizeof(*msg) + size, name);
-
-	if (!msg) {
-		LOGP(DRSL, LOGL_FATAL, "unable to allocate msgb\n");
-		return NULL;
-	}
-
-	msg->data_len = size;
-	msg->len = 0;
-	msg->data = msg->_data;
-
-	msg->head = msg->data;
-	msg->data = msg->data;
-	/* reset tail pointer */
-	msg->tail = msg->data;
-	//msg->end = msg->tail + size;
-
-	return msg;
-}
-
-void msgb_free(struct msgb *m)
-{
-	talloc_free(m);
-}
-
-void msgb_enqueue(struct llist_head *queue, struct msgb *msg)
-{
-	llist_add_tail(&msg->list, queue);
-}
-
-struct msgb *msgb_dequeue(struct llist_head *queue)
-{
-	struct llist_head *lh;
-
-	if (llist_empty(queue))
-		return NULL;
-
-	lh = queue->next;
-	llist_del(lh);
-	
-	return llist_entry(lh, struct msgb, list);
-}
-
-void msgb_reset(struct msgb *msg)
-{
-	msg->len = 0;
-	msg->len = 0;
-	msg->data = msg->_data;
-
-	msg->head = msg->data;
-	msg->data = msg->data;
-	/* reset tail pointer */
-	msg->tail = msg->data;
-
-	/* reset pointers */
-	msg->bts_link = NULL;
-	msg->trx = NULL;
-	msg->lchan = NULL;
-	msg->l2h = NULL;
-	msg->l3h = NULL;
-	msg->smsh = NULL;
-}
diff --git a/openbsc/src/paging.c b/openbsc/src/paging.c
index 91de702..7c3750d 100644
--- a/openbsc/src/paging.c
+++ b/openbsc/src/paging.c
@@ -40,7 +40,7 @@
 #include <assert.h>
 
 #include <openbsc/paging.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/debug.h>
 #include <openbsc/signal.h>
 #include <openbsc/abis_rsl.h>
diff --git a/openbsc/src/rest_octets.c b/openbsc/src/rest_octets.c
index 74874bd..a57e7df 100644
--- a/openbsc/src/rest_octets.c
+++ b/openbsc/src/rest_octets.c
@@ -27,7 +27,7 @@
 #include <errno.h>
 
 #include <openbsc/gsm_data.h>
-#include <openbsc/bitvec.h>
+#include <osmocore/bitvec.h>
 #include <openbsc/rest_octets.h>
 
 /* generate SI1 rest octets */
diff --git a/openbsc/src/rs232.c b/openbsc/src/rs232.c
index a584723..36af59c 100644
--- a/openbsc/src/rs232.c
+++ b/openbsc/src/rs232.c
@@ -28,8 +28,8 @@
 #include <termios.h>
 #include <fcntl.h>
 
-#include <openbsc/select.h>
-#include <openbsc/msgb.h>
+#include <osmocore/select.h>
+#include <osmocore/msgb.h>
 #include <openbsc/debug.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/rs232.h>
diff --git a/openbsc/src/rtp_proxy.c b/openbsc/src/rtp_proxy.c
index 83b774f..9f2e2fd 100644
--- a/openbsc/src/rtp_proxy.c
+++ b/openbsc/src/rtp_proxy.c
@@ -19,6 +19,7 @@
  *
  */
 
+#include <endian.h>
 #include <errno.h>
 #include <unistd.h>
 #include <sys/socket.h>
@@ -29,10 +30,10 @@
 #include <time.h>        /* clock() */
 #include <sys/utsname.h> /* uname() */
 
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_data.h>
-#include <openbsc/msgb.h>
-#include <openbsc/select.h>
+#include <osmocore/msgb.h>
+#include <osmocore/select.h>
 #include <openbsc/debug.h>
 #include <openbsc/rtp_proxy.h>
 
@@ -63,12 +64,21 @@
 
 /* according to RFC 3550 */
 struct rtp_hdr {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
 	u_int8_t  csrc_count:4,
 		  extension:1,
 		  padding:1,
 		  version:2;
 	u_int8_t  payload_type:7,
 		  marker:1;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+	u_int8_t  version:2,
+		  padding:1,
+		  extension:1,
+		  csrc_count:4;
+	u_int8_t  marker:1,
+		  payload_type:7;
+#endif
 	u_int16_t sequence;
 	u_int32_t timestamp;
 	u_int32_t ssrc;
diff --git a/openbsc/src/sccp/sccp.c b/openbsc/src/sccp/sccp.c
index 522afcf..9cd7c9c 100644
--- a/openbsc/src/sccp/sccp.c
+++ b/openbsc/src/sccp/sccp.c
@@ -1,8 +1,8 @@
 /*
  * SCCP management code
  *
- * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by on-waves.com
+ * (C) 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009, 2010 by On-Waves
  *
  * All Rights Reserved
  *
@@ -24,11 +24,12 @@
 
 #include <string.h>
 
+#include <osmocore/msgb.h>
+#include <openbsc/debug.h>
+#include <osmocore/talloc.h>
+
 #include <sccp/sccp.h>
 
-#include <openbsc/debug.h>
-#include <openbsc/talloc.h>
-#include <openbsc/linuxlist.h>
 
 static void *tall_sccp_ctx;
 static LLIST_HEAD(sccp_connections);
@@ -199,6 +200,278 @@
 	return -1;
 }
 
+int _sccp_parse_connection_request(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static const u_int32_t header_size =
+			sizeof(struct sccp_connection_request);
+	static const u_int32_t optional_offset =
+			offsetof(struct sccp_connection_request, optional_start);
+	static const u_int32_t called_offset =
+			offsetof(struct sccp_connection_request, variable_called);
+
+	struct sccp_connection_request *req = (struct sccp_connection_request *)msgb->l2h;
+	struct sccp_optional_data optional_data;
+
+	/* header check */
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	/* copy out the calling and called address. Add the offset */
+	if (copy_address(&result->called, called_offset + req->variable_called, msgb) != 0)
+		return -1;
+
+	if (check_address(&result->called) != 0) {
+		DEBUGP(DSCCP, "Invalid called address according to 08.06: 0x%x 0x%x\n",
+			*(u_int8_t *)&result->called.address, result->called.ssn);
+		return -1;
+	}
+
+	result->source_local_reference = &req->source_local_reference;
+
+	/*
+	 * parse optional data.
+	 */
+	memset(&optional_data, 0, sizeof(optional_data));
+	if (_sccp_parse_optional_data(optional_offset + req->optional_start, msgb, &optional_data) != 0) {
+		DEBUGP(DSCCP, "parsing of optional data failed.\n");
+		return -1;
+	}
+
+	if (optional_data.data_len != 0) {
+		msgb->l3h = &msgb->l2h[optional_data.data_start];
+		result->data_len = optional_data.data_len;
+	} else {
+		result->data_len = 0;
+	}
+
+	return 0;
+}
+
+int _sccp_parse_connection_released(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static int header_size = sizeof(struct sccp_connection_released);
+	static int optional_offset = offsetof(struct sccp_connection_released, optional_start);
+
+	struct sccp_optional_data optional_data;
+	struct sccp_connection_released *rls = (struct sccp_connection_released *) msgb->l2h;
+
+	/* we don't have enough size for the struct */
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb > header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	memset(&optional_data, 0, sizeof(optional_data));
+	if (_sccp_parse_optional_data(optional_offset + rls->optional_start, msgb, &optional_data) != 0) {
+		DEBUGP(DSCCP, "parsing of optional data failed.\n");
+		return -1;
+	}
+
+	result->source_local_reference = &rls->source_local_reference;
+	result->destination_local_reference = &rls->destination_local_reference;
+
+	if (optional_data.data_len != 0) {
+		msgb->l3h = &msgb->l2h[optional_data.data_start];
+		result->data_len = optional_data.data_len;
+	} else {
+		result->data_len = 0;
+	}
+
+	return 0;
+}
+
+int _sccp_parse_connection_refused(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static const u_int32_t header_size =
+			sizeof(struct sccp_connection_refused);
+	static int optional_offset = offsetof(struct sccp_connection_refused, optional_start);
+
+	struct sccp_optional_data optional_data;
+	struct sccp_connection_refused *ref;
+
+	/* header check */
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	ref = (struct sccp_connection_refused *) msgb->l2h;
+
+	result->destination_local_reference = &ref->destination_local_reference;
+
+	memset(&optional_data, 0, sizeof(optional_data));
+	if (_sccp_parse_optional_data(optional_offset + ref->optional_start, msgb, &optional_data) != 0) {
+		DEBUGP(DSCCP, "parsing of optional data failed.\n");
+		return -1;
+	}
+
+	/* optional data */
+	if (optional_data.data_len != 0) {
+		msgb->l3h = &msgb->l2h[optional_data.data_start];
+		result->data_len = optional_data.data_len;
+	} else {
+		result->data_len = 0;
+	}
+
+	return 0;
+}
+
+int _sccp_parse_connection_confirm(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static u_int32_t header_size =
+		    sizeof(struct sccp_connection_confirm);
+	static const u_int32_t optional_offset =
+			offsetof(struct sccp_connection_confirm, optional_start);
+
+	struct sccp_optional_data optional_data;
+	struct sccp_connection_confirm *con;
+
+	/* header check */
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	con = (struct sccp_connection_confirm *) msgb->l2h;
+	result->destination_local_reference = &con->destination_local_reference;
+	result->source_local_reference = &con->source_local_reference;
+
+	memset(&optional_data, 0, sizeof(optional_data));
+	if (_sccp_parse_optional_data(optional_offset + con->optional_start, msgb, &optional_data) != 0) {
+		DEBUGP(DSCCP, "parsing of optional data failed.\n");
+		return -1;
+	}
+
+	if (optional_data.data_len != 0) {
+		msgb->l3h = &msgb->l2h[optional_data.data_start];
+		result->data_len = optional_data.data_len;
+	} else {
+		result->data_len = 0;
+	}
+
+	return 0;
+}
+
+int _sccp_parse_connection_release_complete(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static int header_size = sizeof(struct sccp_connection_release_complete);
+
+	struct sccp_connection_release_complete *cmpl;
+
+	/* header check */
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	cmpl = (struct sccp_connection_release_complete *) msgb->l2h;
+	result->source_local_reference = &cmpl->source_local_reference;
+	result->destination_local_reference = &cmpl->destination_local_reference;
+
+	return 0;
+}
+
+int _sccp_parse_connection_dt1(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static int header_size = sizeof(struct sccp_data_form1);
+	static int variable_offset = offsetof(struct sccp_data_form1, variable_start);
+
+	struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *)msgb->l2h;
+
+	/* we don't have enough size for the struct */
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb > header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	if (dt1->segmenting != 0) {
+		DEBUGP(DSCCP, "This packet has segmenting, not supported: %d\n", dt1->segmenting);
+		return -1;
+	}
+
+	result->destination_local_reference = &dt1->destination_local_reference;
+
+	/* some more  size checks in here */
+	if (msgb_l2len(msgb) < variable_offset + dt1->variable_start + 1) {
+		DEBUGP(DSCCP, "Not enough space for variable start: %u %u\n",
+			msgb_l2len(msgb), dt1->variable_start);
+		return -1;
+	}
+
+	result->data_len = msgb->l2h[variable_offset + dt1->variable_start];
+	msgb->l3h = &msgb->l2h[dt1->variable_start + variable_offset + 1];
+
+	if (msgb_l3len(msgb) < result->data_len) {
+		DEBUGP(DSCCP, "Not enough room for the payload: %u %u\n",
+			msgb_l3len(msgb), result->data_len);
+		return -1;
+	}
+
+	return 0;
+}
+
+int _sccp_parse_udt(struct msgb *msgb, struct sccp_parse_result *result)
+{
+	static const u_int32_t header_size = sizeof(struct sccp_data_unitdata);
+	static const u_int32_t called_offset = offsetof(struct sccp_data_unitdata, variable_called);
+	static const u_int32_t calling_offset = offsetof(struct sccp_data_unitdata, variable_calling);
+	static const u_int32_t data_offset = offsetof(struct sccp_data_unitdata, variable_data);
+
+	struct sccp_data_unitdata *udt = (struct sccp_data_unitdata *)msgb->l2h;
+
+	if (msgb_l2len(msgb) < header_size) {
+		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
+		        msgb_l2len(msgb), header_size);
+		return -1;
+	}
+
+	/* copy out the calling and called address. Add the off */
+	if (copy_address(&result->called, called_offset + udt->variable_called, msgb) != 0)
+		return -1;
+
+	if (check_address(&result->called) != 0) {
+		DEBUGP(DSCCP, "Invalid called address according to 08.06: 0x%x 0x%x\n",
+			*(u_int8_t *)&result->called.address, result->called.ssn);
+		return -1;
+	}
+
+	if (copy_address(&result->calling, calling_offset + udt->variable_calling, msgb) != 0)
+		return -1;
+
+	if (check_address(&result->calling) != 0) {
+		DEBUGP(DSCCP, "Invalid called address according to 08.06: 0x%x 0x%x\n",
+			*(u_int8_t *)&result->called.address, result->called.ssn);
+	}
+
+	/* we don't have enough size for the data */
+	if (msgb_l2len(msgb) < data_offset + udt->variable_data + 1) {
+		DEBUGP(DSCCP, "msgb < header + offset %u %u %u\n",
+			msgb_l2len(msgb), header_size, udt->variable_data);
+		return -1;
+	}
+
+
+	msgb->l3h = &udt->data[udt->variable_data];
+	result->data_len = msgb_l3len(msgb);
+
+	if (msgb_l3len(msgb) !=  msgb->l3h[-1]) {
+		DEBUGP(DSCCP, "msgb is truncated is: %u should: %u\n",
+			msgb_l3len(msgb), msgb->l3h[-1]);
+		return -1;
+	}
+
+	return 0;
+}
+
+
 /*
  * Send UDT. Currently we have a fixed address...
  */
@@ -249,59 +522,15 @@
 
 static int _sccp_handle_read(struct msgb *msgb)
 {
-	static const u_int32_t header_size = sizeof(struct sccp_data_unitdata);
-	static const u_int32_t called_offset = offsetof(struct sccp_data_unitdata, variable_called);
-	static const u_int32_t calling_offset = offsetof(struct sccp_data_unitdata, variable_calling);
-	static const u_int32_t data_offset = offsetof(struct sccp_data_unitdata, variable_data);
-
 	struct sccp_data_callback *cb;
-	struct sccp_data_unitdata *udt = (struct sccp_data_unitdata *)msgb->l2h;
-	struct sccp_address called, calling;
+	struct sccp_parse_result result;
 
-	/* we don't have enough size for the struct */
-	if (msgb_l2len(msgb) < header_size) {
-		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
-		        msgb_l2len(msgb), header_size);
-		return -1;
-	}
-
-	/* copy out the calling and called address. Add the off */
-	if (copy_address(&called, called_offset + udt->variable_called, msgb) != 0)
+	if (_sccp_parse_udt(msgb, &result) != 0)
 		return -1;
 
-	if (check_address(&called) != 0) {
-		DEBUGP(DSCCP, "Invalid called address according to 08.06: 0x%x 0x%x\n",
-			*(u_int8_t *)&called.address, called.ssn);
-		return -1;
-	}
-
-	cb = _find_ssn(called.ssn);
+	cb = _find_ssn(result.called.ssn);
 	if (!cb || !cb->read_cb) {
-		DEBUGP(DSCCP, "No routing for UDT for called SSN: %u\n", called.ssn);
-		return -1;
-	}
-
-	if (copy_address(&calling, calling_offset + udt->variable_calling, msgb) != 0)
-		return -1;
-
-	if (check_address(&calling) != 0) {
-		DEBUGP(DSCCP, "Invalid called address according to 08.06: 0x%x 0x%x\n",
-			*(u_int8_t *)&called.address, called.ssn);
-	}
-
-	/* we don't have enough size for the data */
-	if (msgb_l2len(msgb) < data_offset + udt->variable_data + 1) {
-		DEBUGP(DSCCP, "msgb < header + offset %u %u %u\n",
-			msgb_l2len(msgb), header_size, udt->variable_data);
-		return -1;
-	}
-
-
-	msgb->l3h = &udt->data[udt->variable_data];
-
-	if (msgb_l3len(msgb) !=  msgb->l3h[-1]) {
-		DEBUGP(DSCCP, "msgb is truncated %u %u\n",
-			msgb_l3len(msgb), msgb->l3h[-1]);
+		DEBUGP(DSCCP, "No routing for UDT for called SSN: %u\n", result.called.ssn);
 		return -1;
 	}
 
@@ -374,7 +603,7 @@
 		connection->state_cb(connection, old_state);
 }
 
-static int _sccp_send_refuse(struct sccp_connection_request *req, int cause)
+static int _sccp_send_refuse(struct sccp_source_reference *src_ref, int cause)
 {
 	struct msgb *msgb;
 	struct sccp_connection_refused *ref;
@@ -387,7 +616,7 @@
 
 	ref = (struct sccp_connection_refused *) msgb_put(msgb, sizeof(*ref));
 	ref->type = SCCP_MSG_TYPE_CREF;
-	memcpy(&ref->destination_local_reference, &req->source_local_reference,
+	memcpy(&ref->destination_local_reference, src_ref,
 	       sizeof(struct sccp_source_reference));
 	ref->cause = cause;
 	ref->optional_start = 1;
@@ -601,39 +830,17 @@
  */
 static int _sccp_handle_connection_request(struct msgb *msgb)
 {
-	static const u_int32_t header_size =
-			sizeof(struct sccp_connection_request);
-	static const u_int32_t optional_offset =
-			offsetof(struct sccp_connection_request, optional_start);
-	static const u_int32_t called_offset =
-			offsetof(struct sccp_connection_request, variable_called);
+	struct sccp_parse_result result;
 
 	struct sccp_data_callback *cb;
-	struct sccp_connection_request *req = (struct sccp_connection_request *)msgb->data;
-	struct sccp_address called;
 	struct sccp_connection *connection;
-	struct sccp_optional_data optional_data;
 
-	/* header check */
-	if (msgb_l2len(msgb) < header_size) {
-		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
-		        msgb_l2len(msgb), header_size);
-		return -1;
-	}
-
-	/* copy out the calling and called address. Add the offset */
-	if (copy_address(&called, called_offset + req->variable_called, msgb) != 0)
+	if (_sccp_parse_connection_request(msgb, &result) != 0)
 		return -1;
 
-	if (check_address(&called) != 0) {
-		DEBUGP(DSCCP, "Invalid called address according to 08.06: 0x%x 0x%x\n",
-			*(u_int8_t *)&called.address, called.ssn);
-		return -1;
-	}
-
-	cb = _find_ssn(called.ssn);
+	cb = _find_ssn(result.called.ssn);
 	if (!cb || !cb->accept_cb) {
-		DEBUGP(DSCCP, "No routing for CR for called SSN: %u\n", called.ssn);
+		DEBUGP(DSCCP, "No routing for CR for called SSN: %u\n", result.called.ssn);
 		return -1;
 	}
 
@@ -651,28 +858,18 @@
 	 * and send a connection confirm, otherwise we will send a refuseed
 	 * one....
 	 */
-	if (destination_local_reference_is_free(&req->source_local_reference) != 0) {
+	if (destination_local_reference_is_free(result.source_local_reference) != 0) {
 		DEBUGP(DSCCP, "Need to reject connection with existing reference\n");
-		_sccp_send_refuse(req, SCCP_REFUSAL_SCCP_FAILURE);
+		_sccp_send_refuse(result.source_local_reference, SCCP_REFUSAL_SCCP_FAILURE);
 		talloc_free(connection);
 		return -1;
 	}
 
 	connection->incoming = 1;
-	connection->destination_local_reference = req->source_local_reference;
-
-	/*
-	 * parse optional data.
-	 */
-	memset(&optional_data, 0, sizeof(optional_data));
-	if (_sccp_parse_optional_data(optional_offset + req->optional_start, msgb, &optional_data) != 0) {
-		DEBUGP(DSCCP, "parsing of optional data failed.\n");
-		talloc_free(connection);
-		return -1;
-	}
+	connection->destination_local_reference = *result.source_local_reference;
 
 	if (cb->accept_cb(connection, cb->accept_context) != 0) {
-		_sccp_send_refuse(req, SCCP_REFUSAL_END_USER_ORIGINATED);
+		_sccp_send_refuse(result.source_local_reference, SCCP_REFUSAL_END_USER_ORIGINATED);
 		_sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_REFUSED);
 		talloc_free(connection);
 		return 0;
@@ -684,7 +881,7 @@
 	if (_sccp_send_connection_confirm(connection) != 0) {
 		DEBUGP(DSCCP, "Sending confirm failed... no available source reference?\n");
 
-		_sccp_send_refuse(req, SCCP_REFUSAL_SCCP_FAILURE);
+		_sccp_send_refuse(result.source_local_reference, SCCP_REFUSAL_SCCP_FAILURE);
 		_sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_REFUSED);
 		llist_del(&connection->list);
 		talloc_free(connection);
@@ -695,39 +892,30 @@
 	/*
 	 * If we have data let us forward things.
 	 */
-	if (optional_data.data_len != 0 && connection->data_cb) {
-		msgb->l3h = &msgb->l2h[optional_data.data_start];
-		connection->data_cb(connection, msgb, optional_data.data_len);
+	if (result.data_len != 0 && connection->data_cb) {
+		connection->data_cb(connection, msgb, result.data_len);
 	}
 
 	return 0;
 }
 
 /* Handle the release confirmed */
-static int _sccp_handle_connection_release_complete(struct msgb *data)
+static int _sccp_handle_connection_release_complete(struct msgb *msgb)
 {
-	static int header_size = sizeof(struct sccp_connection_release_complete);
-
-	struct sccp_connection_release_complete *cmpl;
+	struct sccp_parse_result result;
 	struct sccp_connection *conn;
 
-	/* header check */
-	if (msgb_l2len(data) < header_size) {
-		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
-		        msgb_l2len(data), header_size);
+	if (_sccp_parse_connection_release_complete(msgb, &result) != 0)
 		return -1;
-	}
-
-	cmpl = (struct sccp_connection_release_complete *) data->l2h;
 
 	/* find the connection */
 	llist_for_each_entry(conn, &sccp_connections, list) {
 		if (conn->data_cb
 		    && memcmp(&conn->source_local_reference,
-			      &cmpl->destination_local_reference,
+			      result.destination_local_reference,
 			      sizeof(conn->source_local_reference)) == 0
 		    && memcmp(&conn->destination_local_reference,
-			      &cmpl->source_local_reference,
+			      result.source_local_reference,
 			      sizeof(conn->destination_local_reference)) == 0) {
 		    goto found;
 		}
@@ -744,57 +932,30 @@
 }
 
 /* Handle the Data Form 1 message */
-static int _sccp_handle_connection_dt1(struct msgb *data)
+static int _sccp_handle_connection_dt1(struct msgb *msgb)
 {
-	static int variable_offset = offsetof(struct sccp_data_form1, variable_start);
-	static int header_size = sizeof(struct sccp_data_form1);
-
-	struct sccp_data_form1 *dt1 = (struct sccp_data_form1 *)data->l2h;
+	struct sccp_parse_result result;
 	struct sccp_connection *conn;
-	int size;
 
-	/* we don't have enough size for the struct */
-	if (msgb_l2len(data) < header_size) {
-		DEBUGP(DSCCP, "msgb > header_size %u %u\n",
-		        msgb_l2len(data), header_size);
+	if (_sccp_parse_connection_dt1(msgb, &result) != 0)
 		return -1;
-	}
-
-	if (dt1->segmenting != 0) {
-		DEBUGP(DSCCP, "This packet has segmenting, not supported: %d\n", dt1->segmenting);
-		return -1;
-	}
 
 	/* lookup if we have a connection with the given reference */
 	llist_for_each_entry(conn, &sccp_connections, list) {
 		if (conn->data_cb
 		    && memcmp(&conn->source_local_reference,
-			      &dt1->destination_local_reference,
+			      result.destination_local_reference,
 			      sizeof(conn->source_local_reference)) == 0) {
-
-			/* some more  size checks in here */
-			if (msgb_l2len(data) < variable_offset + dt1->variable_start + 1) {
-				DEBUGP(DSCCP, "Not enough space for variable start: %u %u\n",
-					msgb_l2len(data), dt1->variable_start);
-				return -1;
-			}
-
-			size = data->l2h[variable_offset + dt1->variable_start];
-			data->l3h = &data->l2h[dt1->variable_start + variable_offset + 1];
-
-			if (msgb_l3len(data) < size) {
-				DEBUGP(DSCCP, "Not enough room for the payload: %u %u\n",
-					msgb_l3len(data), size);
-				return -1;
-			}
-
-			conn->data_cb(conn, data, size);
-			return 0;
+			goto found;
 		}
 	}
 
 	DEBUGP(DSCCP, "No connection found for dt1 data\n");
 	return -1;
+
+found:
+	conn->data_cb(conn, msgb, result.data_len);
+	return 0;
 }
 
 /* confirm a connection release */
@@ -829,30 +990,22 @@
 }
 
 /* connection released, send a released confirm */
-static int _sccp_handle_connection_released(struct msgb *data)
+static int _sccp_handle_connection_released(struct msgb *msgb)
 {
-	static int header_size = sizeof(struct sccp_connection_released);
-	static int optional_offset = offsetof(struct sccp_connection_released, optional_start);
-
-	struct sccp_optional_data optional_data;
-	struct sccp_connection_released *rls = (struct sccp_connection_released *)data->l2h;
+	struct sccp_parse_result result;
 	struct sccp_connection *conn;
 
-	/* we don't have enough size for the struct */
-	if (msgb_l2len(data) < header_size) {
-		DEBUGP(DSCCP, "msgb > header_size %u %u\n",
-		        msgb_l2len(data), header_size);
+	if (_sccp_parse_connection_released(msgb, &result) == -1)
 		return -1;
-	}
 
 	/* lookup if we have a connection with the given reference */
 	llist_for_each_entry(conn, &sccp_connections, list) {
 		if (conn->data_cb
 		    && memcmp(&conn->source_local_reference,
-			      &rls->destination_local_reference,
+			      result.destination_local_reference,
 			      sizeof(conn->source_local_reference)) == 0
 		    && memcmp(&conn->destination_local_reference,
-			      &rls->source_local_reference,
+			      result.source_local_reference,
 			      sizeof(conn->destination_local_reference)) == 0) {
 		    goto found;
 		}
@@ -864,16 +1017,9 @@
 
 	/* we have found a connection */
 found:
-	memset(&optional_data, 0, sizeof(optional_data));
-	if (_sccp_parse_optional_data(optional_offset + rls->optional_start, data, &optional_data) != 0) {
-		DEBUGP(DSCCP, "parsing of optional data failed.\n");
-		return -1;
-	}
-
 	/* optional data */
-	if (optional_data.data_len != 0 && conn->data_cb) {
-		data->l3h = &data->l2h[optional_data.data_start];
-		conn->data_cb(conn, data, optional_data.data_len);
+	if (result.data_len != 0 && conn->data_cb) {
+		conn->data_cb(conn, msgb, result.data_len);
 	}
 
 	/* generate a response */
@@ -887,28 +1033,17 @@
 
 static int _sccp_handle_connection_refused(struct msgb *msgb)
 {
-	static const u_int32_t header_size =
-			sizeof(struct sccp_connection_refused);
-	static int optional_offset = offsetof(struct sccp_connection_refused, optional_start);
-
-	struct sccp_optional_data optional_data;
+	struct sccp_parse_result result;
 	struct sccp_connection *conn;
-	struct sccp_connection_refused *ref;
 
-	/* header check */
-	if (msgb_l2len(msgb) < header_size) {
-		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
-		        msgb_l2len(msgb), header_size);
+	if (_sccp_parse_connection_refused(msgb, &result) != 0)
 		return -1;
-	}
-
-	ref = (struct sccp_connection_refused *) msgb->l2h;
 
 	/* lookup if we have a connection with the given reference */
 	llist_for_each_entry(conn, &sccp_connections, list) {
 		if (conn->incoming == 0 && conn->data_cb
 		    && memcmp(&conn->source_local_reference,
-			      &ref->destination_local_reference,
+			      result.destination_local_reference,
 			      sizeof(conn->source_local_reference)) == 0) {
 		    goto found;
 		}
@@ -918,16 +1053,9 @@
 	return -1;
 
 found:
-	memset(&optional_data, 0, sizeof(optional_data));
-	if (_sccp_parse_optional_data(optional_offset + ref->optional_start, msgb, &optional_data) != 0) {
-		DEBUGP(DSCCP, "parsing of optional data failed.\n");
-		return -1;
-	}
-
 	/* optional data */
-	if (optional_data.data_len != 0 && conn->data_cb) {
-		msgb->l3h = &msgb->l2h[optional_data.data_start];
-		conn->data_cb(conn, msgb, optional_data.data_len);
+	if (result.data_len != 0 && conn->data_cb) {
+		conn->data_cb(conn, msgb, result.data_len);
 	}
 
 
@@ -938,29 +1066,17 @@
 
 static int _sccp_handle_connection_confirm(struct msgb *msgb)
 {
-	static u_int32_t header_size =
-		    sizeof(struct sccp_connection_confirm);
-	static const u_int32_t optional_offset =
-			offsetof(struct sccp_connection_confirm, optional_start);
-
-	struct sccp_optional_data optional_data;
+	struct sccp_parse_result result;
 	struct sccp_connection *conn;
-	struct sccp_connection_confirm *con;
 
-	/* header check */
-	if (msgb_l2len(msgb) < header_size) {
-		DEBUGP(DSCCP, "msgb < header_size %u %u\n",
-		        msgb_l2len(msgb), header_size);
+	if (_sccp_parse_connection_confirm(msgb, &result) != 0)
 		return -1;
-	}
-
-	con = (struct sccp_connection_confirm *) msgb->l2h;
 
 	/* lookup if we have a connection with the given reference */
 	llist_for_each_entry(conn, &sccp_connections, list) {
 		if (conn->incoming == 0 && conn->data_cb
 		    && memcmp(&conn->source_local_reference,
-			      &con->destination_local_reference,
+			      result.destination_local_reference,
 			      sizeof(conn->source_local_reference)) == 0) {
 		    goto found;
 		}
@@ -971,19 +1087,12 @@
 
 found:
 	/* copy the addresses of the connection */
-	conn->destination_local_reference = con->source_local_reference;
+	conn->destination_local_reference = *result.source_local_reference;
 	_sccp_set_connection_state(conn, SCCP_CONNECTION_STATE_ESTABLISHED);
 
-	memset(&optional_data, 0, sizeof(optional_data));
-	if (_sccp_parse_optional_data(optional_offset + con->optional_start, msgb, &optional_data) != 0) {
-		DEBUGP(DSCCP, "parsing of optional data failed.\n");
-		return -1;
-	}
-
 	/* optional data */
-	if (optional_data.data_len != 0 && conn->data_cb) {
-		msgb->l3h = &msgb->l2h[optional_data.data_start];
-		conn->data_cb(conn, msgb, optional_data.data_len);
+	if (result.data_len != 0 && conn->data_cb) {
+		conn->data_cb(conn, msgb, result.data_len);
 	}
 
 	return 0;
@@ -1160,6 +1269,49 @@
 	return ref;
 }
 
+int sccp_determine_msg_type(struct msgb *msg)
+{
+	if (msgb_l2len(msg) < 1)
+		return -1;
+
+	return msg->l2h[0];
+}
+
+int sccp_parse_header(struct msgb *msg, struct sccp_parse_result *result)
+{
+	int type;
+
+	if (msgb_l2len(msg) < 1)
+		return -1;
+
+	type = msg->l2h[0];
+	switch(type) {
+	case SCCP_MSG_TYPE_CR:
+		return _sccp_parse_connection_request(msg, result);
+		break;
+	case SCCP_MSG_TYPE_RLSD:
+		return _sccp_parse_connection_released(msg, result);
+		break;
+	case SCCP_MSG_TYPE_CREF:
+		return _sccp_parse_connection_refused(msg, result);
+		break;
+	case SCCP_MSG_TYPE_CC:
+		return _sccp_parse_connection_confirm(msg, result);
+		break;
+	case SCCP_MSG_TYPE_RLC:
+		return _sccp_parse_connection_release_complete(msg, result);
+		break;
+	case SCCP_MSG_TYPE_DT1:
+		return _sccp_parse_connection_dt1(msg, result);
+		break;
+	case SCCP_MSG_TYPE_UDT:
+		return _sccp_parse_udt(msg, result);
+		break;
+	};
+
+	return -1;
+}
+
 static __attribute__((constructor)) void on_dso_load(void)
 {
 	tall_sccp_ctx = talloc_named_const(NULL, 1, "sccp");
diff --git a/openbsc/src/select.c b/openbsc/src/select.c
deleted file mode 100644
index bed9649..0000000
--- a/openbsc/src/select.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* select filedescriptor handling, taken from:
- * userspace logging daemon for the iptables ULOG target
- * of the linux 2.4 netfilter subsystem.
- *
- * (C) 2000-2009 by Harald Welte <laforge@gnumonks.org>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 
- *  as published by the Free Software Foundation
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <fcntl.h>
-#include <openbsc/select.h>
-#include <openbsc/linuxlist.h>
-#include <openbsc/timer.h>
-
-static int maxfd = 0;
-static LLIST_HEAD(bsc_fds);
-static int unregistered_count;
-
-int bsc_register_fd(struct bsc_fd *fd)
-{
-	int flags;
-
-	/* make FD nonblocking */
-	flags = fcntl(fd->fd, F_GETFL);
-	if (flags < 0)
-		return flags;
-	flags |= O_NONBLOCK;
-	flags = fcntl(fd->fd, F_SETFL, flags);
-	if (flags < 0)
-		return flags;
-
-	/* Register FD */
-	if (fd->fd > maxfd)
-		maxfd = fd->fd;
-
-	llist_add_tail(&fd->list, &bsc_fds);
-
-	return 0;
-}
-
-void bsc_unregister_fd(struct bsc_fd *fd)
-{
-	unregistered_count++;
-	llist_del(&fd->list);
-}
-
-int bsc_select_main(int polling)
-{
-	struct bsc_fd *ufd, *tmp;
-	fd_set readset, writeset, exceptset;
-	int work = 0, rc;
-	struct timeval no_time = {0, 0};
-
-	FD_ZERO(&readset);
-	FD_ZERO(&writeset);
-	FD_ZERO(&exceptset);
-
-	/* prepare read and write fdsets */
-	llist_for_each_entry(ufd, &bsc_fds, list) {
-		if (ufd->when & BSC_FD_READ)
-			FD_SET(ufd->fd, &readset);
-
-		if (ufd->when & BSC_FD_WRITE)
-			FD_SET(ufd->fd, &writeset);
-
-		if (ufd->when & BSC_FD_EXCEPT)
-			FD_SET(ufd->fd, &exceptset);
-	}
-
-	bsc_timer_check();
-
-	if (!polling)
-		bsc_prepare_timers();
-	rc = select(maxfd+1, &readset, &writeset, &exceptset, polling ? &no_time : bsc_nearest_timer());
-	if (rc < 0)
-		return 0;
-
-	/* fire timers */
-	bsc_update_timers();
-
-	/* call registered callback functions */
-restart:
-	unregistered_count = 0;
-	llist_for_each_entry_safe(ufd, tmp, &bsc_fds, list) {
-		int flags = 0;
-
-		if (FD_ISSET(ufd->fd, &readset)) {
-			flags |= BSC_FD_READ;
-			FD_CLR(ufd->fd, &readset);
-		}
-
-		if (FD_ISSET(ufd->fd, &writeset)) {
-			flags |= BSC_FD_WRITE;
-			FD_CLR(ufd->fd, &writeset);
-		}
-
-		if (FD_ISSET(ufd->fd, &exceptset)) {
-			flags |= BSC_FD_EXCEPT;
-			FD_CLR(ufd->fd, &exceptset);
-		}
-
-		if (flags) {
-			work = 1;
-			ufd->cb(ufd, flags);
-		}
-		/* ugly, ugly hack. If more than one filedescriptors were
-		 * unregistered, they might have been consecutive and
-		 * llist_for_each_entry_safe() is no longer safe */
-		if (unregistered_count > 1)
-			goto restart;
-	}
-	return work;
-}
diff --git a/openbsc/src/signal.c b/openbsc/src/signal.c
deleted file mode 100644
index e04cadf..0000000
--- a/openbsc/src/signal.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/* Generic signalling/notification infrastructure */
-/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <openbsc/signal.h>
-#include <openbsc/talloc.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-void *tall_sigh_ctx;
-static LLIST_HEAD(signal_handler_list);
-
-struct signal_handler {
-	struct llist_head entry;
-	unsigned int subsys;
-	signal_cbfn *cbfn;
-	void *data;
-};
-
-
-int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data)
-{
-	struct signal_handler *sig_data;
-
-	sig_data = talloc(tall_sigh_ctx, struct signal_handler);
-	if (!sig_data)
-		return -ENOMEM;
-
-	memset(sig_data, 0, sizeof(*sig_data));
-
-	sig_data->subsys = subsys;
-	sig_data->data = data;
-	sig_data->cbfn = cbfn;
-
-	/* FIXME: check if we already have a handler for this subsys/cbfn/data */
-
-	llist_add_tail(&sig_data->entry, &signal_handler_list);
-
-	return 0;
-}
-
-void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data)
-{
-	struct signal_handler *handler;
-
-	llist_for_each_entry(handler, &signal_handler_list, entry) {
-		if (handler->cbfn == cbfn && handler->data == data 
-		    && subsys == handler->subsys) {
-			llist_del(&handler->entry);
-			talloc_free(handler);
-			break;
-		}
-	}
-}
-
-
-void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data)
-{
-	struct signal_handler *handler;
-
-	llist_for_each_entry(handler, &signal_handler_list, entry) {
-		if (handler->subsys != subsys)
-			continue;
-		(*handler->cbfn)(subsys, signal, handler->data, signal_data);
-	}
-}
diff --git a/openbsc/src/silent_call.c b/openbsc/src/silent_call.c
index a0c166e..cada24e 100644
--- a/openbsc/src/silent_call.c
+++ b/openbsc/src/silent_call.c
@@ -25,7 +25,7 @@
 #include <unistd.h>
 #include <errno.h>
 
-#include <openbsc/msgb.h>
+#include <osmocore/msgb.h>
 #include <openbsc/signal.h>
 #include <openbsc/debug.h>
 #include <openbsc/paging.h>
diff --git a/openbsc/src/statistics.c b/openbsc/src/statistics.c
deleted file mode 100644
index 9452b16..0000000
--- a/openbsc/src/statistics.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* utility routines for keeping some statistics */
-
-/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-#include <sys/types.h>
-
-#include <openbsc/gsm_data.h>
-#include <openbsc/signal.h>
-#include <openbsc/linuxlist.h>
-#include <openbsc/talloc.h>
-#include <openbsc/statistics.h>
-#include <openbsc/db.h>
-#include <openbsc/timer.h>
-
-static LLIST_HEAD(counters);
-
-void *tall_ctr_ctx;
-
-struct counter *counter_alloc(const char *name)
-{
-	struct counter *ctr = talloc_zero(tall_ctr_ctx, struct counter);
-
-	if (!ctr)
-		return NULL;
-
-	ctr->name = name;
-	llist_add_tail(&ctr->list, &counters);
-
-	return ctr;
-}
-
-void counter_free(struct counter *ctr)
-{
-	llist_del(&ctr->list);
-	talloc_free(ctr);
-}
-
-int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data)
-{
-	struct counter *ctr;
-	int rc = 0;
-
-	llist_for_each_entry(ctr, &counters, list) {
-		rc = handle_counter(ctr, data);
-		if (rc < 0)
-			return rc;
-	}
-
-	return rc;
-}
-
diff --git a/openbsc/src/subchan_demux.c b/openbsc/src/subchan_demux.c
index 63be533..0d6c1fe 100644
--- a/openbsc/src/subchan_demux.c
+++ b/openbsc/src/subchan_demux.c
@@ -28,7 +28,7 @@
 #include <openbsc/subchan_demux.h>
 #include <openbsc/trau_frame.h>
 #include <openbsc/debug.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_data.h>
 
 void *tall_tqe_ctx;
diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c
index 9bdf2c1..36dc6b9 100644
--- a/openbsc/src/system_information.c
+++ b/openbsc/src/system_information.c
@@ -31,7 +31,7 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/rest_octets.h>
-#include <openbsc/bitvec.h>
+#include <osmocore/bitvec.h>
 #include <openbsc/debug.h>
 
 #define GSM48_CELL_CHAN_DESC_SIZE	16
diff --git a/openbsc/src/talloc.c b/openbsc/src/talloc.c
deleted file mode 100644
index d821323..0000000
--- a/openbsc/src/talloc.c
+++ /dev/null
@@ -1,1805 +0,0 @@
-/* 
-   Samba Unix SMB/CIFS implementation.
-
-   Samba trivial allocation library - new interface
-
-   NOTE: Please read talloc_guide.txt for full documentation
-
-   Copyright (C) Andrew Tridgell 2004
-   Copyright (C) Stefan Metzmacher 2006
-   
-     ** NOTE! The following LGPL license applies to the talloc
-     ** library. This does NOT imply that all of Samba is released
-     ** under the LGPL
-   
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 3 of the License, or (at your option) any later version.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
-  inspired by http://swapped.cc/halloc/
-*/
-
-#ifdef _SAMBA_BUILD_
-#include "version.h"
-#if (SAMBA_VERSION_MAJOR<4)
-#include "includes.h"
-/* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
- * we trust ourselves... */
-#ifdef malloc
-#undef malloc
-#endif
-#ifdef realloc
-#undef realloc
-#endif
-#define _TALLOC_SAMBA3
-#endif /* (SAMBA_VERSION_MAJOR<4) */
-#endif /* _SAMBA_BUILD_ */
-
-#ifndef _TALLOC_SAMBA3
-//#include "replace.h"
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <stdbool.h>
-#define __USE_GNU
-#include <string.h>
-#undef __USE_GNU
-#include <openbsc/talloc.h>
-#define MIN(x,y) ((x) < (y) ? (x) : (y))
-#endif /* not _TALLOC_SAMBA3 */
-
-/* use this to force every realloc to change the pointer, to stress test
-   code that might not cope */
-#define ALWAYS_REALLOC 0
-
-
-#define MAX_TALLOC_SIZE 0x10000000
-#define TALLOC_MAGIC 0xe814ec70
-#define TALLOC_FLAG_FREE 0x01
-#define TALLOC_FLAG_LOOP 0x02
-#define TALLOC_FLAG_POOL 0x04		/* This is a talloc pool */
-#define TALLOC_FLAG_POOLMEM 0x08	/* This is allocated in a pool */
-#define TALLOC_MAGIC_REFERENCE ((const char *)1)
-
-/* by default we abort when given a bad pointer (such as when talloc_free() is called 
-   on a pointer that came from malloc() */
-#ifndef TALLOC_ABORT
-#define TALLOC_ABORT(reason) abort()
-#endif
-
-#ifndef discard_const_p
-#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
-# define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
-#else
-# define discard_const_p(type, ptr) ((type *)(ptr))
-#endif
-#endif
-
-/* these macros gain us a few percent of speed on gcc */
-#if (__GNUC__ >= 3)
-/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
-   as its first argument */
-#ifndef likely
-#define likely(x)   __builtin_expect(!!(x), 1)
-#endif
-#ifndef unlikely
-#define unlikely(x) __builtin_expect(!!(x), 0)
-#endif
-#else
-#ifndef likely
-#define likely(x) (x)
-#endif
-#ifndef unlikely
-#define unlikely(x) (x)
-#endif
-#endif
-
-#ifdef __APPLE__
-/* taken from http://insanecoding.blogspot.com/2007/03/methods-for-safe-string-handling.html */
-size_t strnlen(const char *s, size_t n)
-{
-  const char *p = (const char *)memchr(s, 0, n);
-  return(p ? p-s : n);
-}
-#endif
-
-/* this null_context is only used if talloc_enable_leak_report() or
-   talloc_enable_leak_report_full() is called, otherwise it remains
-   NULL
-*/
-static void *null_context;
-static void *autofree_context;
-
-struct talloc_reference_handle {
-	struct talloc_reference_handle *next, *prev;
-	void *ptr;
-};
-
-typedef int (*talloc_destructor_t)(void *);
-
-struct talloc_chunk {
-	struct talloc_chunk *next, *prev;
-	struct talloc_chunk *parent, *child;
-	struct talloc_reference_handle *refs;
-	talloc_destructor_t destructor;
-	const char *name;
-	size_t size;
-	unsigned flags;
-
-	/*
-	 * "pool" has dual use:
-	 *
-	 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
-	 * marks the end of the currently allocated area.
-	 *
-	 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
-	 * is a pointer to the struct talloc_chunk of the pool that it was
-	 * allocated from. This way children can quickly find the pool to chew
-	 * from.
-	 */
-	void *pool;
-};
-
-/* 16 byte alignment seems to keep everyone happy */
-#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
-#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
-
-static void (*talloc_abort_fn)(const char *reason);
-
-void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
-{
-	talloc_abort_fn = abort_fn;
-}
-
-static void talloc_abort(const char *reason)
-{
-	if (!talloc_abort_fn) {
-		TALLOC_ABORT(reason);
-	}
-
-	talloc_abort_fn(reason);
-}
-
-static void talloc_abort_double_free(void)
-{
-	talloc_abort("Bad talloc magic value - double free");
-}
-
-static void talloc_abort_unknown_value(void)
-{
-	talloc_abort("Bad talloc magic value - unknown value");
-}
-
-/* panic if we get a bad magic value */
-static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
-{
-	const char *pp = (const char *)ptr;
-	struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
-	if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { 
-		if (tc->flags & TALLOC_FLAG_FREE) {
-			talloc_abort_double_free();
-		} else {
-			talloc_abort_unknown_value();
-		}
-	}
-	return tc;
-}
-
-/* hook into the front of the list */
-#define _TLIST_ADD(list, p) \
-do { \
-        if (!(list)) { \
-		(list) = (p); \
-		(p)->next = (p)->prev = NULL; \
-	} else { \
-		(list)->prev = (p); \
-		(p)->next = (list); \
-		(p)->prev = NULL; \
-		(list) = (p); \
-	}\
-} while (0)
-
-/* remove an element from a list - element doesn't have to be in list. */
-#define _TLIST_REMOVE(list, p) \
-do { \
-	if ((p) == (list)) { \
-		(list) = (p)->next; \
-		if (list) (list)->prev = NULL; \
-	} else { \
-		if ((p)->prev) (p)->prev->next = (p)->next; \
-		if ((p)->next) (p)->next->prev = (p)->prev; \
-	} \
-	if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
-} while (0)
-
-
-/*
-  return the parent chunk of a pointer
-*/
-static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
-{
-	struct talloc_chunk *tc;
-
-	if (unlikely(ptr == NULL)) {
-		return NULL;
-	}
-
-	tc = talloc_chunk_from_ptr(ptr);
-	while (tc->prev) tc=tc->prev;
-
-	return tc->parent;
-}
-
-void *talloc_parent(const void *ptr)
-{
-	struct talloc_chunk *tc = talloc_parent_chunk(ptr);
-	return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
-}
-
-/*
-  find parents name
-*/
-const char *talloc_parent_name(const void *ptr)
-{
-	struct talloc_chunk *tc = talloc_parent_chunk(ptr);
-	return tc? tc->name : NULL;
-}
-
-/*
-  A pool carries an in-pool object count count in the first 16 bytes.
-  bytes. This is done to support talloc_steal() to a parent outside of the
-  pool. The count includes the pool itself, so a talloc_free() on a pool will
-  only destroy the pool if the count has dropped to zero. A talloc_free() of a
-  pool member will reduce the count, and eventually also call free(3) on the
-  pool memory.
-
-  The object count is not put into "struct talloc_chunk" because it is only
-  relevant for talloc pools and the alignment to 16 bytes would increase the
-  memory footprint of each talloc chunk by those 16 bytes.
-*/
-
-#define TALLOC_POOL_HDR_SIZE 16
-
-static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
-{
-	return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
-}
-
-/*
-  Allocate from a pool
-*/
-
-static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
-					      size_t size)
-{
-	struct talloc_chunk *pool_ctx = NULL;
-	size_t space_left;
-	struct talloc_chunk *result;
-	size_t chunk_size;
-
-	if (parent == NULL) {
-		return NULL;
-	}
-
-	if (parent->flags & TALLOC_FLAG_POOL) {
-		pool_ctx = parent;
-	}
-	else if (parent->flags & TALLOC_FLAG_POOLMEM) {
-		pool_ctx = (struct talloc_chunk *)parent->pool;
-	}
-
-	if (pool_ctx == NULL) {
-		return NULL;
-	}
-
-	space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
-		- ((char *)pool_ctx->pool);
-
-	/*
-	 * Align size to 16 bytes
-	 */
-	chunk_size = ((size + 15) & ~15);
-
-	if (space_left < chunk_size) {
-		return NULL;
-	}
-
-	result = (struct talloc_chunk *)pool_ctx->pool;
-
-#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
-	VALGRIND_MAKE_MEM_UNDEFINED(result, size);
-#endif
-
-	pool_ctx->pool = (void *)((char *)result + chunk_size);
-
-	result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
-	result->pool = pool_ctx;
-
-	*talloc_pool_objectcount(pool_ctx) += 1;
-
-	return result;
-}
-
-/* 
-   Allocate a bit of memory as a child of an existing pointer
-*/
-static inline void *__talloc(const void *context, size_t size)
-{
-	struct talloc_chunk *tc = NULL;
-
-	if (unlikely(context == NULL)) {
-		context = null_context;
-	}
-
-	if (unlikely(size >= MAX_TALLOC_SIZE)) {
-		return NULL;
-	}
-
-	if (context != NULL) {
-		tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
-				       TC_HDR_SIZE+size);
-	}
-
-	if (tc == NULL) {
-		tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
-		if (unlikely(tc == NULL)) return NULL;
-		tc->flags = TALLOC_MAGIC;
-		tc->pool  = NULL;
-	}
-
-	tc->size = size;
-	tc->destructor = NULL;
-	tc->child = NULL;
-	tc->name = NULL;
-	tc->refs = NULL;
-
-	if (likely(context)) {
-		struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
-
-		if (parent->child) {
-			parent->child->parent = NULL;
-			tc->next = parent->child;
-			tc->next->prev = tc;
-		} else {
-			tc->next = NULL;
-		}
-		tc->parent = parent;
-		tc->prev = NULL;
-		parent->child = tc;
-	} else {
-		tc->next = tc->prev = tc->parent = NULL;
-	}
-
-	return TC_PTR_FROM_CHUNK(tc);
-}
-
-/*
- * Create a talloc pool
- */
-
-void *talloc_pool(const void *context, size_t size)
-{
-	void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
-	struct talloc_chunk *tc;
-
-	if (unlikely(result == NULL)) {
-		return NULL;
-	}
-
-	tc = talloc_chunk_from_ptr(result);
-
-	tc->flags |= TALLOC_FLAG_POOL;
-	tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
-
-	*talloc_pool_objectcount(tc) = 1;
-
-#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
-	VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
-#endif
-
-	return result;
-}
-
-/*
-  setup a destructor to be called on free of a pointer
-  the destructor should return 0 on success, or -1 on failure.
-  if the destructor fails then the free is failed, and the memory can
-  be continued to be used
-*/
-void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
-{
-	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
-	tc->destructor = destructor;
-}
-
-/*
-  increase the reference count on a piece of memory. 
-*/
-int talloc_increase_ref_count(const void *ptr)
-{
-	if (unlikely(!talloc_reference(null_context, ptr))) {
-		return -1;
-	}
-	return 0;
-}
-
-/*
-  helper for talloc_reference()
-
-  this is referenced by a function pointer and should not be inline
-*/
-static int talloc_reference_destructor(struct talloc_reference_handle *handle)
-{
-	struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
-	_TLIST_REMOVE(ptr_tc->refs, handle);
-	return 0;
-}
-
-/*
-   more efficient way to add a name to a pointer - the name must point to a 
-   true string constant
-*/
-static inline void _talloc_set_name_const(const void *ptr, const char *name)
-{
-	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
-	tc->name = name;
-}
-
-/*
-  internal talloc_named_const()
-*/
-static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
-{
-	void *ptr;
-
-	ptr = __talloc(context, size);
-	if (unlikely(ptr == NULL)) {
-		return NULL;
-	}
-
-	_talloc_set_name_const(ptr, name);
-
-	return ptr;
-}
-
-/*
-  make a secondary reference to a pointer, hanging off the given context.
-  the pointer remains valid until both the original caller and this given
-  context are freed.
-  
-  the major use for this is when two different structures need to reference the 
-  same underlying data, and you want to be able to free the two instances separately,
-  and in either order
-*/
-void *_talloc_reference(const void *context, const void *ptr)
-{
-	struct talloc_chunk *tc;
-	struct talloc_reference_handle *handle;
-	if (unlikely(ptr == NULL)) return NULL;
-
-	tc = talloc_chunk_from_ptr(ptr);
-	handle = (struct talloc_reference_handle *)_talloc_named_const(context,
-						   sizeof(struct talloc_reference_handle),
-						   TALLOC_MAGIC_REFERENCE);
-	if (unlikely(handle == NULL)) return NULL;
-
-	/* note that we hang the destructor off the handle, not the
-	   main context as that allows the caller to still setup their
-	   own destructor on the context if they want to */
-	talloc_set_destructor(handle, talloc_reference_destructor);
-	handle->ptr = discard_const_p(void, ptr);
-	_TLIST_ADD(tc->refs, handle);
-	return handle->ptr;
-}
-
-
-/* 
-   internal talloc_free call
-*/
-static inline int _talloc_free(void *ptr)
-{
-	struct talloc_chunk *tc;
-
-	if (unlikely(ptr == NULL)) {
-		return -1;
-	}
-
-	tc = talloc_chunk_from_ptr(ptr);
-
-	if (unlikely(tc->refs)) {
-		int is_child;
-		/* check this is a reference from a child or grantchild
-		 * back to it's parent or grantparent
-		 *
-		 * in that case we need to remove the reference and
-		 * call another instance of talloc_free() on the current
-		 * pointer.
-		 */
-		is_child = talloc_is_parent(tc->refs, ptr);
-		_talloc_free(tc->refs);
-		if (is_child) {
-			return _talloc_free(ptr);
-		}
-		return -1;
-	}
-
-	if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
-		/* we have a free loop - stop looping */
-		return 0;
-	}
-
-	if (unlikely(tc->destructor)) {
-		talloc_destructor_t d = tc->destructor;
-		if (d == (talloc_destructor_t)-1) {
-			return -1;
-		}
-		tc->destructor = (talloc_destructor_t)-1;
-		if (d(ptr) == -1) {
-			tc->destructor = d;
-			return -1;
-		}
-		tc->destructor = NULL;
-	}
-
-	if (tc->parent) {
-		_TLIST_REMOVE(tc->parent->child, tc);
-		if (tc->parent->child) {
-			tc->parent->child->parent = tc->parent;
-		}
-	} else {
-		if (tc->prev) tc->prev->next = tc->next;
-		if (tc->next) tc->next->prev = tc->prev;
-	}
-
-	tc->flags |= TALLOC_FLAG_LOOP;
-
-	while (tc->child) {
-		/* we need to work out who will own an abandoned child
-		   if it cannot be freed. In priority order, the first
-		   choice is owner of any remaining reference to this
-		   pointer, the second choice is our parent, and the
-		   final choice is the null context. */
-		void *child = TC_PTR_FROM_CHUNK(tc->child);
-		const void *new_parent = null_context;
-		if (unlikely(tc->child->refs)) {
-			struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
-			if (p) new_parent = TC_PTR_FROM_CHUNK(p);
-		}
-		if (unlikely(_talloc_free(child) == -1)) {
-			if (new_parent == null_context) {
-				struct talloc_chunk *p = talloc_parent_chunk(ptr);
-				if (p) new_parent = TC_PTR_FROM_CHUNK(p);
-			}
-			talloc_steal(new_parent, child);
-		}
-	}
-
-	tc->flags |= TALLOC_FLAG_FREE;
-
-	if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
-		struct talloc_chunk *pool;
-		unsigned int *pool_object_count;
-
-		pool = (tc->flags & TALLOC_FLAG_POOL)
-			? tc : (struct talloc_chunk *)tc->pool;
-
-		pool_object_count = talloc_pool_objectcount(pool);
-
-		if (*pool_object_count == 0) {
-			talloc_abort("Pool object count zero!");
-		}
-
-		*pool_object_count -= 1;
-
-		if (*pool_object_count == 0) {
-			free(pool);
-		}
-	}
-	else {
-		free(tc);
-	}
-	return 0;
-}
-
-/* 
-   move a lump of memory from one talloc context to another return the
-   ptr on success, or NULL if it could not be transferred.
-   passing NULL as ptr will always return NULL with no side effects.
-*/
-void *_talloc_steal(const void *new_ctx, const void *ptr)
-{
-	struct talloc_chunk *tc, *new_tc;
-
-	if (unlikely(!ptr)) {
-		return NULL;
-	}
-
-	if (unlikely(new_ctx == NULL)) {
-		new_ctx = null_context;
-	}
-
-	tc = talloc_chunk_from_ptr(ptr);
-
-	if (unlikely(new_ctx == NULL)) {
-		if (tc->parent) {
-			_TLIST_REMOVE(tc->parent->child, tc);
-			if (tc->parent->child) {
-				tc->parent->child->parent = tc->parent;
-			}
-		} else {
-			if (tc->prev) tc->prev->next = tc->next;
-			if (tc->next) tc->next->prev = tc->prev;
-		}
-		
-		tc->parent = tc->next = tc->prev = NULL;
-		return discard_const_p(void, ptr);
-	}
-
-	new_tc = talloc_chunk_from_ptr(new_ctx);
-
-	if (unlikely(tc == new_tc || tc->parent == new_tc)) {
-		return discard_const_p(void, ptr);
-	}
-
-	if (tc->parent) {
-		_TLIST_REMOVE(tc->parent->child, tc);
-		if (tc->parent->child) {
-			tc->parent->child->parent = tc->parent;
-		}
-	} else {
-		if (tc->prev) tc->prev->next = tc->next;
-		if (tc->next) tc->next->prev = tc->prev;
-	}
-
-	tc->parent = new_tc;
-	if (new_tc->child) new_tc->child->parent = NULL;
-	_TLIST_ADD(new_tc->child, tc);
-
-	return discard_const_p(void, ptr);
-}
-
-
-
-/*
-  remove a secondary reference to a pointer. This undo's what
-  talloc_reference() has done. The context and pointer arguments
-  must match those given to a talloc_reference()
-*/
-static inline int talloc_unreference(const void *context, const void *ptr)
-{
-	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
-	struct talloc_reference_handle *h;
-
-	if (unlikely(context == NULL)) {
-		context = null_context;
-	}
-
-	for (h=tc->refs;h;h=h->next) {
-		struct talloc_chunk *p = talloc_parent_chunk(h);
-		if (p == NULL) {
-			if (context == NULL) break;
-		} else if (TC_PTR_FROM_CHUNK(p) == context) {
-			break;
-		}
-	}
-	if (h == NULL) {
-		return -1;
-	}
-
-	return _talloc_free(h);
-}
-
-/*
-  remove a specific parent context from a pointer. This is a more
-  controlled varient of talloc_free()
-*/
-int talloc_unlink(const void *context, void *ptr)
-{
-	struct talloc_chunk *tc_p, *new_p;
-	void *new_parent;
-
-	if (ptr == NULL) {
-		return -1;
-	}
-
-	if (context == NULL) {
-		context = null_context;
-	}
-
-	if (talloc_unreference(context, ptr) == 0) {
-		return 0;
-	}
-
-	if (context == NULL) {
-		if (talloc_parent_chunk(ptr) != NULL) {
-			return -1;
-		}
-	} else {
-		if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
-			return -1;
-		}
-	}
-	
-	tc_p = talloc_chunk_from_ptr(ptr);
-
-	if (tc_p->refs == NULL) {
-		return _talloc_free(ptr);
-	}
-
-	new_p = talloc_parent_chunk(tc_p->refs);
-	if (new_p) {
-		new_parent = TC_PTR_FROM_CHUNK(new_p);
-	} else {
-		new_parent = NULL;
-	}
-
-	if (talloc_unreference(new_parent, ptr) != 0) {
-		return -1;
-	}
-
-	talloc_steal(new_parent, ptr);
-
-	return 0;
-}
-
-/*
-  add a name to an existing pointer - va_list version
-*/
-static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
-
-static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
-{
-	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
-	tc->name = talloc_vasprintf(ptr, fmt, ap);
-	if (likely(tc->name)) {
-		_talloc_set_name_const(tc->name, ".name");
-	}
-	return tc->name;
-}
-
-/*
-  add a name to an existing pointer
-*/
-const char *talloc_set_name(const void *ptr, const char *fmt, ...)
-{
-	const char *name;
-	va_list ap;
-	va_start(ap, fmt);
-	name = talloc_set_name_v(ptr, fmt, ap);
-	va_end(ap);
-	return name;
-}
-
-
-/*
-  create a named talloc pointer. Any talloc pointer can be named, and
-  talloc_named() operates just like talloc() except that it allows you
-  to name the pointer.
-*/
-void *talloc_named(const void *context, size_t size, const char *fmt, ...)
-{
-	va_list ap;
-	void *ptr;
-	const char *name;
-
-	ptr = __talloc(context, size);
-	if (unlikely(ptr == NULL)) return NULL;
-
-	va_start(ap, fmt);
-	name = talloc_set_name_v(ptr, fmt, ap);
-	va_end(ap);
-
-	if (unlikely(name == NULL)) {
-		_talloc_free(ptr);
-		return NULL;
-	}
-
-	return ptr;
-}
-
-/*
-  return the name of a talloc ptr, or "UNNAMED"
-*/
-const char *talloc_get_name(const void *ptr)
-{
-	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
-	if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
-		return ".reference";
-	}
-	if (likely(tc->name)) {
-		return tc->name;
-	}
-	return "UNNAMED";
-}
-
-
-/*
-  check if a pointer has the given name. If it does, return the pointer,
-  otherwise return NULL
-*/
-void *talloc_check_name(const void *ptr, const char *name)
-{
-	const char *pname;
-	if (unlikely(ptr == NULL)) return NULL;
-	pname = talloc_get_name(ptr);
-	if (likely(pname == name || strcmp(pname, name) == 0)) {
-		return discard_const_p(void, ptr);
-	}
-	return NULL;
-}
-
-static void talloc_abort_type_missmatch(const char *location,
-					const char *name,
-					const char *expected)
-{
-	const char *reason;
-
-	reason = talloc_asprintf(NULL,
-				 "%s: Type mismatch: name[%s] expected[%s]",
-				 location,
-				 name?name:"NULL",
-				 expected);
-	if (!reason) {
-		reason = "Type mismatch";
-	}
-
-	talloc_abort(reason);
-}
-
-void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
-{
-	const char *pname;
-
-	if (unlikely(ptr == NULL)) {
-		talloc_abort_type_missmatch(location, NULL, name);
-		return NULL;
-	}
-
-	pname = talloc_get_name(ptr);
-	if (likely(pname == name || strcmp(pname, name) == 0)) {
-		return discard_const_p(void, ptr);
-	}
-
-	talloc_abort_type_missmatch(location, pname, name);
-	return NULL;
-}
-
-/*
-  this is for compatibility with older versions of talloc
-*/
-void *talloc_init(const char *fmt, ...)
-{
-	va_list ap;
-	void *ptr;
-	const char *name;
-
-	/*
-	 * samba3 expects talloc_report_depth_cb(NULL, ...)
-	 * reports all talloc'ed memory, so we need to enable
-	 * null_tracking
-	 */
-	talloc_enable_null_tracking();
-
-	ptr = __talloc(NULL, 0);
-	if (unlikely(ptr == NULL)) return NULL;
-
-	va_start(ap, fmt);
-	name = talloc_set_name_v(ptr, fmt, ap);
-	va_end(ap);
-
-	if (unlikely(name == NULL)) {
-		_talloc_free(ptr);
-		return NULL;
-	}
-
-	return ptr;
-}
-
-/*
-  this is a replacement for the Samba3 talloc_destroy_pool functionality. It
-  should probably not be used in new code. It's in here to keep the talloc
-  code consistent across Samba 3 and 4.
-*/
-void talloc_free_children(void *ptr)
-{
-	struct talloc_chunk *tc;
-
-	if (unlikely(ptr == NULL)) {
-		return;
-	}
-
-	tc = talloc_chunk_from_ptr(ptr);
-
-	while (tc->child) {
-		/* we need to work out who will own an abandoned child
-		   if it cannot be freed. In priority order, the first
-		   choice is owner of any remaining reference to this
-		   pointer, the second choice is our parent, and the
-		   final choice is the null context. */
-		void *child = TC_PTR_FROM_CHUNK(tc->child);
-		const void *new_parent = null_context;
-		if (unlikely(tc->child->refs)) {
-			struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
-			if (p) new_parent = TC_PTR_FROM_CHUNK(p);
-		}
-		if (unlikely(_talloc_free(child) == -1)) {
-			if (new_parent == null_context) {
-				struct talloc_chunk *p = talloc_parent_chunk(ptr);
-				if (p) new_parent = TC_PTR_FROM_CHUNK(p);
-			}
-			talloc_steal(new_parent, child);
-		}
-	}
-
-	if ((tc->flags & TALLOC_FLAG_POOL)
-	    && (*talloc_pool_objectcount(tc) == 1)) {
-		tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
-#if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
-		VALGRIND_MAKE_MEM_NOACCESS(
-			tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
-#endif
-	}
-}
-
-/* 
-   Allocate a bit of memory as a child of an existing pointer
-*/
-void *_talloc(const void *context, size_t size)
-{
-	return __talloc(context, size);
-}
-
-/*
-  externally callable talloc_set_name_const()
-*/
-void talloc_set_name_const(const void *ptr, const char *name)
-{
-	_talloc_set_name_const(ptr, name);
-}
-
-/*
-  create a named talloc pointer. Any talloc pointer can be named, and
-  talloc_named() operates just like talloc() except that it allows you
-  to name the pointer.
-*/
-void *talloc_named_const(const void *context, size_t size, const char *name)
-{
-	return _talloc_named_const(context, size, name);
-}
-
-/* 
-   free a talloc pointer. This also frees all child pointers of this 
-   pointer recursively
-
-   return 0 if the memory is actually freed, otherwise -1. The memory
-   will not be freed if the ref_count is > 1 or the destructor (if
-   any) returns non-zero
-*/
-int talloc_free(void *ptr)
-{
-	return _talloc_free(ptr);
-}
-
-
-
-/*
-  A talloc version of realloc. The context argument is only used if
-  ptr is NULL
-*/
-void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
-{
-	struct talloc_chunk *tc;
-	void *new_ptr;
-	bool malloced = false;
-
-	/* size zero is equivalent to free() */
-	if (unlikely(size == 0)) {
-		_talloc_free(ptr);
-		return NULL;
-	}
-
-	if (unlikely(size >= MAX_TALLOC_SIZE)) {
-		return NULL;
-	}
-
-	/* realloc(NULL) is equivalent to malloc() */
-	if (ptr == NULL) {
-		return _talloc_named_const(context, size, name);
-	}
-
-	tc = talloc_chunk_from_ptr(ptr);
-
-	/* don't allow realloc on referenced pointers */
-	if (unlikely(tc->refs)) {
-		return NULL;
-	}
-
-	/* don't let anybody try to realloc a talloc_pool */
-	if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
-		return NULL;
-	}
-
-	/* don't shrink if we have less than 1k to gain */
-	if ((size < tc->size) && ((tc->size - size) < 1024)) {
-		tc->size = size;
-		return ptr;
-	}
-
-	/* by resetting magic we catch users of the old memory */
-	tc->flags |= TALLOC_FLAG_FREE;
-
-#if ALWAYS_REALLOC
-	new_ptr = malloc(size + TC_HDR_SIZE);
-	if (new_ptr) {
-		memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
-		free(tc);
-	}
-#else
-	if (tc->flags & TALLOC_FLAG_POOLMEM) {
-
-		new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
-		*talloc_pool_objectcount((struct talloc_chunk *)
-					 (tc->pool)) -= 1;
-
-		if (new_ptr == NULL) {
-			new_ptr = malloc(TC_HDR_SIZE+size);
-			malloced = true;
-		}
-
-		if (new_ptr) {
-			memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
-		}
-	}
-	else {
-		new_ptr = realloc(tc, size + TC_HDR_SIZE);
-	}
-#endif
-	if (unlikely(!new_ptr)) {	
-		tc->flags &= ~TALLOC_FLAG_FREE; 
-		return NULL; 
-	}
-
-	tc = (struct talloc_chunk *)new_ptr;
-	tc->flags &= ~TALLOC_FLAG_FREE;
-	if (malloced) {
-		tc->flags &= ~TALLOC_FLAG_POOLMEM;
-	}
-	if (tc->parent) {
-		tc->parent->child = tc;
-	}
-	if (tc->child) {
-		tc->child->parent = tc;
-	}
-
-	if (tc->prev) {
-		tc->prev->next = tc;
-	}
-	if (tc->next) {
-		tc->next->prev = tc;
-	}
-
-	tc->size = size;
-	_talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
-
-	return TC_PTR_FROM_CHUNK(tc);
-}
-
-/*
-  a wrapper around talloc_steal() for situations where you are moving a pointer
-  between two structures, and want the old pointer to be set to NULL
-*/
-void *_talloc_move(const void *new_ctx, const void *_pptr)
-{
-	const void **pptr = discard_const_p(const void *,_pptr);
-	void *ret = _talloc_steal(new_ctx, *pptr);
-	(*pptr) = NULL;
-	return ret;
-}
-
-/*
-  return the total size of a talloc pool (subtree)
-*/
-size_t talloc_total_size(const void *ptr)
-{
-	size_t total = 0;
-	struct talloc_chunk *c, *tc;
-
-	if (ptr == NULL) {
-		ptr = null_context;
-	}
-	if (ptr == NULL) {
-		return 0;
-	}
-
-	tc = talloc_chunk_from_ptr(ptr);
-
-	if (tc->flags & TALLOC_FLAG_LOOP) {
-		return 0;
-	}
-
-	tc->flags |= TALLOC_FLAG_LOOP;
-
-	total = tc->size;
-	for (c=tc->child;c;c=c->next) {
-		total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
-	}
-
-	tc->flags &= ~TALLOC_FLAG_LOOP;
-
-	return total;
-}
-
-/*
-  return the total number of blocks in a talloc pool (subtree)
-*/
-size_t talloc_total_blocks(const void *ptr)
-{
-	size_t total = 0;
-	struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
-
-	if (tc->flags & TALLOC_FLAG_LOOP) {
-		return 0;
-	}
-
-	tc->flags |= TALLOC_FLAG_LOOP;
-
-	total++;
-	for (c=tc->child;c;c=c->next) {
-		total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
-	}
-
-	tc->flags &= ~TALLOC_FLAG_LOOP;
-
-	return total;
-}
-
-/*
-  return the number of external references to a pointer
-*/
-size_t talloc_reference_count(const void *ptr)
-{
-	struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
-	struct talloc_reference_handle *h;
-	size_t ret = 0;
-
-	for (h=tc->refs;h;h=h->next) {
-		ret++;
-	}
-	return ret;
-}
-
-/*
-  report on memory usage by all children of a pointer, giving a full tree view
-*/
-void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
-			    void (*callback)(const void *ptr,
-			  		     int depth, int max_depth,
-					     int is_ref,
-					     void *private_data),
-			    void *private_data)
-{
-	struct talloc_chunk *c, *tc;
-
-	if (ptr == NULL) {
-		ptr = null_context;
-	}
-	if (ptr == NULL) return;
-
-	tc = talloc_chunk_from_ptr(ptr);
-
-	if (tc->flags & TALLOC_FLAG_LOOP) {
-		return;
-	}
-
-	callback(ptr, depth, max_depth, 0, private_data);
-
-	if (max_depth >= 0 && depth >= max_depth) {
-		return;
-	}
-
-	tc->flags |= TALLOC_FLAG_LOOP;
-	for (c=tc->child;c;c=c->next) {
-		if (c->name == TALLOC_MAGIC_REFERENCE) {
-			struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
-			callback(h->ptr, depth + 1, max_depth, 1, private_data);
-		} else {
-			talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
-		}
-	}
-	tc->flags &= ~TALLOC_FLAG_LOOP;
-}
-
-static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
-{
-	const char *name = talloc_get_name(ptr);
-	FILE *f = (FILE *)_f;
-
-	if (is_ref) {
-		fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
-		return;
-	}
-
-	if (depth == 0) {
-		fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
-			(max_depth < 0 ? "full " :""), name,
-			(unsigned long)talloc_total_size(ptr),
-			(unsigned long)talloc_total_blocks(ptr));
-		return;
-	}
-
-	fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", 
-		depth*4, "",
-		name,
-		(unsigned long)talloc_total_size(ptr),
-		(unsigned long)talloc_total_blocks(ptr),
-		(int)talloc_reference_count(ptr), ptr);
-
-#if 0
-	fprintf(f, "content: ");
-	if (talloc_total_size(ptr)) {
-		int tot = talloc_total_size(ptr);
-		int i;
-
-		for (i = 0; i < tot; i++) {
-			if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
-				fprintf(f, "%c", ((char *)ptr)[i]);
-			} else {
-				fprintf(f, "~%02x", ((char *)ptr)[i]);
-			}
-		}
-	}
-	fprintf(f, "\n");
-#endif
-}
-
-/*
-  report on memory usage by all children of a pointer, giving a full tree view
-*/
-void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
-{
-	talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
-	fflush(f);
-}
-
-/*
-  report on memory usage by all children of a pointer, giving a full tree view
-*/
-void talloc_report_full(const void *ptr, FILE *f)
-{
-	talloc_report_depth_file(ptr, 0, -1, f);
-}
-
-/*
-  report on memory usage by all children of a pointer
-*/
-void talloc_report(const void *ptr, FILE *f)
-{
-	talloc_report_depth_file(ptr, 0, 1, f);
-}
-
-/*
-  report on any memory hanging off the null context
-*/
-static void talloc_report_null(void)
-{
-	if (talloc_total_size(null_context) != 0) {
-		talloc_report(null_context, stderr);
-	}
-}
-
-/*
-  report on any memory hanging off the null context
-*/
-static void talloc_report_null_full(void)
-{
-	if (talloc_total_size(null_context) != 0) {
-		talloc_report_full(null_context, stderr);
-	}
-}
-
-/*
-  enable tracking of the NULL context
-*/
-void talloc_enable_null_tracking(void)
-{
-	if (null_context == NULL) {
-		null_context = _talloc_named_const(NULL, 0, "null_context");
-	}
-}
-
-/*
-  disable tracking of the NULL context
-*/
-void talloc_disable_null_tracking(void)
-{
-	_talloc_free(null_context);
-	null_context = NULL;
-}
-
-/*
-  enable leak reporting on exit
-*/
-void talloc_enable_leak_report(void)
-{
-	talloc_enable_null_tracking();
-	atexit(talloc_report_null);
-}
-
-/*
-  enable full leak reporting on exit
-*/
-void talloc_enable_leak_report_full(void)
-{
-	talloc_enable_null_tracking();
-	atexit(talloc_report_null_full);
-}
-
-/* 
-   talloc and zero memory. 
-*/
-void *_talloc_zero(const void *ctx, size_t size, const char *name)
-{
-	void *p = _talloc_named_const(ctx, size, name);
-
-	if (p) {
-		memset(p, '\0', size);
-	}
-
-	return p;
-}
-
-/*
-  memdup with a talloc. 
-*/
-void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
-{
-	void *newp = _talloc_named_const(t, size, name);
-
-	if (likely(newp)) {
-		memcpy(newp, p, size);
-	}
-
-	return newp;
-}
-
-static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
-{
-	char *ret;
-
-	ret = (char *)__talloc(t, len + 1);
-	if (unlikely(!ret)) return NULL;
-
-	memcpy(ret, p, len);
-	ret[len] = 0;
-
-	_talloc_set_name_const(ret, ret);
-	return ret;
-}
-
-/*
-  strdup with a talloc
-*/
-char *talloc_strdup(const void *t, const char *p)
-{
-	if (unlikely(!p)) return NULL;
-	return __talloc_strlendup(t, p, strlen(p));
-}
-
-/*
-  strndup with a talloc
-*/
-char *talloc_strndup(const void *t, const char *p, size_t n)
-{
-	if (unlikely(!p)) return NULL;
-	return __talloc_strlendup(t, p, strnlen(p, n));
-}
-
-static inline char *__talloc_strlendup_append(char *s, size_t slen,
-					      const char *a, size_t alen)
-{
-	char *ret;
-
-	ret = talloc_realloc(NULL, s, char, slen + alen + 1);
-	if (unlikely(!ret)) return NULL;
-
-	/* append the string and the trailing \0 */
-	memcpy(&ret[slen], a, alen);
-	ret[slen+alen] = 0;
-
-	_talloc_set_name_const(ret, ret);
-	return ret;
-}
-
-/*
- * Appends at the end of the string.
- */
-char *talloc_strdup_append(char *s, const char *a)
-{
-	if (unlikely(!s)) {
-		return talloc_strdup(NULL, a);
-	}
-
-	if (unlikely(!a)) {
-		return s;
-	}
-
-	return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
-}
-
-/*
- * Appends at the end of the talloc'ed buffer,
- * not the end of the string.
- */
-char *talloc_strdup_append_buffer(char *s, const char *a)
-{
-	size_t slen;
-
-	if (unlikely(!s)) {
-		return talloc_strdup(NULL, a);
-	}
-
-	if (unlikely(!a)) {
-		return s;
-	}
-
-	slen = talloc_get_size(s);
-	if (likely(slen > 0)) {
-		slen--;
-	}
-
-	return __talloc_strlendup_append(s, slen, a, strlen(a));
-}
-
-/*
- * Appends at the end of the string.
- */
-char *talloc_strndup_append(char *s, const char *a, size_t n)
-{
-	if (unlikely(!s)) {
-		return talloc_strdup(NULL, a);
-	}
-
-	if (unlikely(!a)) {
-		return s;
-	}
-
-	return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
-}
-
-/*
- * Appends at the end of the talloc'ed buffer,
- * not the end of the string.
- */
-char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
-{
-	size_t slen;
-
-	if (unlikely(!s)) {
-		return talloc_strdup(NULL, a);
-	}
-
-	if (unlikely(!a)) {
-		return s;
-	}
-
-	slen = talloc_get_size(s);
-	if (likely(slen > 0)) {
-		slen--;
-	}
-
-	return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
-}
-
-#ifndef HAVE_VA_COPY
-#ifdef HAVE___VA_COPY
-#define va_copy(dest, src) __va_copy(dest, src)
-#else
-#define va_copy(dest, src) (dest) = (src)
-#endif
-#endif
-
-char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
-{
-	int len;
-	char *ret;
-	va_list ap2;
-	char c;
-
-	/* this call looks strange, but it makes it work on older solaris boxes */
-	va_copy(ap2, ap);
-	len = vsnprintf(&c, 1, fmt, ap2);
-	va_end(ap2);
-	if (unlikely(len < 0)) {
-		return NULL;
-	}
-
-	ret = (char *)__talloc(t, len+1);
-	if (unlikely(!ret)) return NULL;
-
-	va_copy(ap2, ap);
-	vsnprintf(ret, len+1, fmt, ap2);
-	va_end(ap2);
-
-	_talloc_set_name_const(ret, ret);
-	return ret;
-}
-
-
-/*
-  Perform string formatting, and return a pointer to newly allocated
-  memory holding the result, inside a memory pool.
- */
-char *talloc_asprintf(const void *t, const char *fmt, ...)
-{
-	va_list ap;
-	char *ret;
-
-	va_start(ap, fmt);
-	ret = talloc_vasprintf(t, fmt, ap);
-	va_end(ap);
-	return ret;
-}
-
-static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
-						 const char *fmt, va_list ap)
-						 PRINTF_ATTRIBUTE(3,0);
-
-static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
-						 const char *fmt, va_list ap)
-{
-	ssize_t alen;
-	va_list ap2;
-	char c;
-
-	va_copy(ap2, ap);
-	alen = vsnprintf(&c, 1, fmt, ap2);
-	va_end(ap2);
-
-	if (alen <= 0) {
-		/* Either the vsnprintf failed or the format resulted in
-		 * no characters being formatted. In the former case, we
-		 * ought to return NULL, in the latter we ought to return
-		 * the original string. Most current callers of this
-		 * function expect it to never return NULL.
-		 */
-		return s;
-	}
-
-	s = talloc_realloc(NULL, s, char, slen + alen + 1);
-	if (!s) return NULL;
-
-	va_copy(ap2, ap);
-	vsnprintf(s + slen, alen + 1, fmt, ap2);
-	va_end(ap2);
-
-	_talloc_set_name_const(s, s);
-	return s;
-}
-
-/**
- * Realloc @p s to append the formatted result of @p fmt and @p ap,
- * and return @p s, which may have moved.  Good for gradually
- * accumulating output into a string buffer. Appends at the end
- * of the string.
- **/
-char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
-{
-	if (unlikely(!s)) {
-		return talloc_vasprintf(NULL, fmt, ap);
-	}
-
-	return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
-}
-
-/**
- * Realloc @p s to append the formatted result of @p fmt and @p ap,
- * and return @p s, which may have moved. Always appends at the
- * end of the talloc'ed buffer, not the end of the string.
- **/
-char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
-{
-	size_t slen;
-
-	if (unlikely(!s)) {
-		return talloc_vasprintf(NULL, fmt, ap);
-	}
-
-	slen = talloc_get_size(s);
-	if (likely(slen > 0)) {
-		slen--;
-	}
-
-	return __talloc_vaslenprintf_append(s, slen, fmt, ap);
-}
-
-/*
-  Realloc @p s to append the formatted result of @p fmt and return @p
-  s, which may have moved.  Good for gradually accumulating output
-  into a string buffer.
- */
-char *talloc_asprintf_append(char *s, const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	s = talloc_vasprintf_append(s, fmt, ap);
-	va_end(ap);
-	return s;
-}
-
-/*
-  Realloc @p s to append the formatted result of @p fmt and return @p
-  s, which may have moved.  Good for gradually accumulating output
-  into a buffer.
- */
-char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
-{
-	va_list ap;
-
-	va_start(ap, fmt);
-	s = talloc_vasprintf_append_buffer(s, fmt, ap);
-	va_end(ap);
-	return s;
-}
-
-/*
-  alloc an array, checking for integer overflow in the array size
-*/
-void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
-{
-	if (count >= MAX_TALLOC_SIZE/el_size) {
-		return NULL;
-	}
-	return _talloc_named_const(ctx, el_size * count, name);
-}
-
-/*
-  alloc an zero array, checking for integer overflow in the array size
-*/
-void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
-{
-	if (count >= MAX_TALLOC_SIZE/el_size) {
-		return NULL;
-	}
-	return _talloc_zero(ctx, el_size * count, name);
-}
-
-/*
-  realloc an array, checking for integer overflow in the array size
-*/
-void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
-{
-	if (count >= MAX_TALLOC_SIZE/el_size) {
-		return NULL;
-	}
-	return _talloc_realloc(ctx, ptr, el_size * count, name);
-}
-
-/*
-  a function version of talloc_realloc(), so it can be passed as a function pointer
-  to libraries that want a realloc function (a realloc function encapsulates
-  all the basic capabilities of an allocation library, which is why this is useful)
-*/
-void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
-{
-	return _talloc_realloc(context, ptr, size, NULL);
-}
-
-
-static int talloc_autofree_destructor(void *ptr)
-{
-	autofree_context = NULL;
-	return 0;
-}
-
-static void talloc_autofree(void)
-{
-	_talloc_free(autofree_context);
-}
-
-/*
-  return a context which will be auto-freed on exit
-  this is useful for reducing the noise in leak reports
-*/
-void *talloc_autofree_context(void)
-{
-	if (autofree_context == NULL) {
-		autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
-		talloc_set_destructor(autofree_context, talloc_autofree_destructor);
-		atexit(talloc_autofree);
-	}
-	return autofree_context;
-}
-
-size_t talloc_get_size(const void *context)
-{
-	struct talloc_chunk *tc;
-
-	if (context == NULL)
-		return 0;
-
-	tc = talloc_chunk_from_ptr(context);
-
-	return tc->size;
-}
-
-/*
-  find a parent of this context that has the given name, if any
-*/
-void *talloc_find_parent_byname(const void *context, const char *name)
-{
-	struct talloc_chunk *tc;
-
-	if (context == NULL) {
-		return NULL;
-	}
-
-	tc = talloc_chunk_from_ptr(context);
-	while (tc) {
-		if (tc->name && strcmp(tc->name, name) == 0) {
-			return TC_PTR_FROM_CHUNK(tc);
-		}
-		while (tc && tc->prev) tc = tc->prev;
-		if (tc) {
-			tc = tc->parent;
-		}
-	}
-	return NULL;
-}
-
-/*
-  show the parentage of a context
-*/
-void talloc_show_parents(const void *context, FILE *file)
-{
-	struct talloc_chunk *tc;
-
-	if (context == NULL) {
-		fprintf(file, "talloc no parents for NULL\n");
-		return;
-	}
-
-	tc = talloc_chunk_from_ptr(context);
-	fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
-	while (tc) {
-		fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
-		while (tc && tc->prev) tc = tc->prev;
-		if (tc) {
-			tc = tc->parent;
-		}
-	}
-	fflush(file);
-}
-
-/*
-  return 1 if ptr is a parent of context
-*/
-int talloc_is_parent(const void *context, const void *ptr)
-{
-	struct talloc_chunk *tc;
-
-	if (context == NULL) {
-		return 0;
-	}
-
-	tc = talloc_chunk_from_ptr(context);
-	while (tc) {
-		if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
-		while (tc && tc->prev) tc = tc->prev;
-		if (tc) {
-			tc = tc->parent;
-		}
-	}
-	return 0;
-}
diff --git a/openbsc/src/talloc_ctx.c b/openbsc/src/talloc_ctx.c
index 5f0ee4d..6379e13 100644
--- a/openbsc/src/talloc_ctx.c
+++ b/openbsc/src/talloc_ctx.c
@@ -1,4 +1,4 @@
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_data.h>
 
 extern void *tall_msgb_ctx;
diff --git a/openbsc/src/telnet_interface.c b/openbsc/src/telnet_interface.c
index 6f452a5..805dd12 100644
--- a/openbsc/src/telnet_interface.c
+++ b/openbsc/src/telnet_interface.c
@@ -30,11 +30,11 @@
 #include <openbsc/chan_alloc.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/gsm_04_11.h>
-#include <openbsc/msgb.h>
+#include <osmocore/msgb.h>
 #include <openbsc/abis_rsl.h>
 #include <openbsc/paging.h>
 #include <openbsc/signal.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/debug.h>
 
 #include <vty/buffer.h>
diff --git a/openbsc/src/timer.c b/openbsc/src/timer.c
deleted file mode 100644
index ffeb4ab..0000000
--- a/openbsc/src/timer.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * (C) 2008,2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <assert.h>
-#include <string.h>
-#include <openbsc/timer.h>
-
-static LLIST_HEAD(timer_list);
-static struct timeval s_nearest_time;
-static struct timeval s_select_time;
-
-#define MICRO_SECONDS  1000000LL
-
-#define TIME_SMALLER(left, right) \
-        (left.tv_sec*MICRO_SECONDS+left.tv_usec) <= (right.tv_sec*MICRO_SECONDS+right.tv_usec)
-
-void bsc_add_timer(struct timer_list *timer)
-{
-	struct timer_list *list_timer;
-
-	/* TODO: Optimize and remember the closest item... */
-	timer->active = 1;
-
-	/* this might be called from within update_timers */
-	llist_for_each_entry(list_timer, &timer_list, entry)
-		if (timer == list_timer)
-			return;
-
-	timer->in_list = 1;
-	llist_add(&timer->entry, &timer_list);
-}
-
-void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds)
-{
-	struct timeval current_time;
-
-	gettimeofday(&current_time, NULL);
-	unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
-	currentTime += seconds * MICRO_SECONDS + microseconds;
-	timer->timeout.tv_sec = currentTime / MICRO_SECONDS;
-	timer->timeout.tv_usec = currentTime % MICRO_SECONDS;
-	bsc_add_timer(timer);
-}
-
-void bsc_del_timer(struct timer_list *timer)
-{
-	if (timer->in_list) {
-		timer->active = 0;
-		timer->in_list = 0;
-		llist_del(&timer->entry);
-	}
-}
-
-int bsc_timer_pending(struct timer_list *timer)
-{
-	return timer->active;
-}
-
-/*
- * if we have a nearest time return the delta between the current
- * time and the time of the nearest timer.
- * If the nearest timer timed out return NULL and then we will
- * dispatch everything after the select
- */
-struct timeval *bsc_nearest_timer()
-{
-	struct timeval current_time;
-
-	if (s_nearest_time.tv_sec == 0 && s_nearest_time.tv_usec == 0)
-		return NULL;
-
-	if (gettimeofday(&current_time, NULL) == -1)
-		return NULL;
-
-	unsigned long long nearestTime = s_nearest_time.tv_sec * MICRO_SECONDS + s_nearest_time.tv_usec;
-	unsigned long long currentTime = current_time.tv_sec * MICRO_SECONDS + current_time.tv_usec;
-
-	if (nearestTime < currentTime) {
-		s_select_time.tv_sec = 0;
-		s_select_time.tv_usec = 0;
-	} else {
-		s_select_time.tv_sec = (nearestTime - currentTime) / MICRO_SECONDS;
-		s_select_time.tv_usec = (nearestTime - currentTime) % MICRO_SECONDS;
-	}
-
-	return &s_select_time;
-}
-
-/*
- * Find the nearest time and update s_nearest_time
- */
-void bsc_prepare_timers()
-{
-	struct timer_list *timer, *nearest_timer = NULL;
-	llist_for_each_entry(timer, &timer_list, entry) {
-		if (!nearest_timer || TIME_SMALLER(timer->timeout, nearest_timer->timeout)) {
-			nearest_timer = timer;
-		}
-	}
-
-	if (nearest_timer) {
-		s_nearest_time = nearest_timer->timeout;
-	} else {
-		memset(&s_nearest_time, 0, sizeof(struct timeval));
-	}
-}
-
-/*
- * fire all timers... and remove them
- */
-int bsc_update_timers()
-{
-	struct timeval current_time;
-	struct timer_list *timer, *tmp;
-	int work = 0;
-
-	gettimeofday(&current_time, NULL);
-
-	/*
-	 * The callbacks might mess with our list and in this case
-	 * even llist_for_each_entry_safe is not safe to use. To allow
-	 * del_timer, add_timer, schedule_timer to be called from within
-	 * the callback we jump through some loops.
-	 *
-	 * First we set the handled flag of each active timer to zero,
-	 * then we iterate over the list and execute the callbacks. As the
-	 * list might have been changed (specially the next) from within
-	 * the callback we have to start over again. Once every callback
-	 * is dispatched we will remove the non-active from the list.
-	 *
-	 * TODO: If this is a performance issue we can poison a global
-	 * variable in add_timer and del_timer and only then restart.
-	 */
-	llist_for_each_entry(timer, &timer_list, entry) {
-		timer->handled = 0;
-	}
-
-restart:
-	llist_for_each_entry(timer, &timer_list, entry) {
-		if (!timer->handled && TIME_SMALLER(timer->timeout, current_time)) {
-			timer->handled = 1;
-			timer->active = 0;
-			(*timer->cb)(timer->data);
-			work = 1;
-			goto restart;
-		}
-	}
-
-	llist_for_each_entry_safe(timer, tmp, &timer_list, entry) {
-		timer->handled = 0;
-		if (!timer->active) {
-			bsc_del_timer(timer);
-		}
-	}
-
-	return work;
-}
-
-int bsc_timer_check(void)
-{
-	struct timer_list *timer;
-	int i = 0;
-
-	llist_for_each_entry(timer, &timer_list, entry) {
-		i++;
-	}
-	return i;
-}
diff --git a/openbsc/src/tlv_parser.c b/openbsc/src/tlv_parser.c
deleted file mode 100644
index 13ca7b1..0000000
--- a/openbsc/src/tlv_parser.c
+++ /dev/null
@@ -1,170 +0,0 @@
-#include <stdio.h>
-#include <openbsc/tlv.h>
-#include <openbsc/gsm_data.h>
-
-struct tlv_definition tvlv_att_def;
-
-int tlv_dump(struct tlv_parsed *dec)
-{
-	int i;
-
-	for (i = 0; i <= 0xff; i++) {
-		if (!dec->lv[i].val)
-			continue;
-		printf("T=%02x L=%d\n", i, dec->lv[i].len);
-	}
-	return 0;
-}
-
-/* o_tag:  output: tag found
- * o_len:  output: length of the data
- * o_val:  output: pointer to the data
- * def:     input: a structure defining the valid TLV tags / configurations
- * buf:     input: the input data buffer to be parsed
- * buf_len: input: the length of the input data buffer
- *
- * Also, returns the number of bytes consumed by the TLV entry
- */
-int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val,
-		  const struct tlv_definition *def,
-		  const u_int8_t *buf, int buf_len)
-{
-	u_int8_t tag;
-	int len;
-
-	tag = *buf;
-	*o_tag = tag;
-
-	/* FIXME: use tables for knwon IEI */
-	switch (def->def[tag].type) {
-	case TLV_TYPE_T:
-		/* GSM TS 04.07 11.2.4: Type 1 TV or Type 2 T */
-		*o_val = buf;
-		*o_len = 0;
-		len = 1;
-		break;
-	case TLV_TYPE_TV:
-		*o_val = buf+1;
-		*o_len = 1;
-		len = 2;
-		break;
-	case TLV_TYPE_FIXED:
-		*o_val = buf+1;
-		*o_len = def->def[tag].fixed_len;
-		len = def->def[tag].fixed_len + 1;
-		break;
-	case TLV_TYPE_TLV:
-		/* GSM TS 04.07 11.2.4: Type 4 TLV */
-		if (buf + 1 > buf + buf_len)
-			return -1;
-		*o_val = buf+2;
-		*o_len = *(buf+1);
-		len = *o_len + 2;
-		if (len > buf_len)
-			return -2;
-		break;
-	case TLV_TYPE_TvLV:
-		if (*(buf+1) & 0x80) {
-			/* like TLV, but without highest bit of len */
-			if (buf + 1 > buf + buf_len)
-				return -1;
-			*o_val = buf+2;
-			*o_len = *(buf+1) & 0x7f;
-			len = *o_len + 2;
-			if (len > buf_len)
-				return -2;
-			break;
-		}
-		/* like TL16V, fallthrough */
-	case TLV_TYPE_TL16V:
-		if (2 > buf_len)
-			return -1;
-		*o_val = buf+3;
-		*o_len = *(buf+1) << 8 | *(buf+2);
-		len = *o_len + 3;
-		if (len > buf_len)
-			return -2;
-		break;
-	default:
-		return -3;
-	}
-
-	return len;
-}
-
-/* dec:    output: a caller-allocated pointer to a struct tlv_parsed,
- * def:     input: a structure defining the valid TLV tags / configurations
- * buf:     input: the input data buffer to be parsed
- * buf_len: input: the length of the input data buffer
- * lv_tag:  input: an initial LV tag at the start of the buffer
- * lv_tag2: input: a second initial LV tag following lv_tag 
- */
-int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
-	      const u_int8_t *buf, int buf_len, u_int8_t lv_tag,
-	      u_int8_t lv_tag2)
-{
-	int ofs = 0, num_parsed = 0;
-	u_int16_t len;
-
-	memset(dec, 0, sizeof(*dec));
-
-	if (lv_tag) {
-		if (ofs > buf_len)
-			return -1;
-		dec->lv[lv_tag].val = &buf[ofs+1];
-		dec->lv[lv_tag].len = buf[ofs];
-		len = dec->lv[lv_tag].len + 1;
-		if (ofs + len > buf_len)
-			return -2;
-		num_parsed++;
-		ofs += len;
-	}
-	if (lv_tag2) {
-		if (ofs > buf_len)
-			return -1;
-		dec->lv[lv_tag2].val = &buf[ofs+1];
-		dec->lv[lv_tag2].len = buf[ofs];
-		len = dec->lv[lv_tag2].len + 1;
-		if (ofs + len > buf_len)
-			return -2;
-		num_parsed++;
-		ofs += len;
-	}
-
-	while (ofs < buf_len) {
-		int rv;
-		u_int8_t tag;
-		const u_int8_t *val;
-
-		rv = tlv_parse_one(&tag, &len, &val, def,
-		                   &buf[ofs], buf_len-ofs);
-		if (rv < 0)
-			return rv;
-		dec->lv[tag].val = val;
-		dec->lv[tag].len = len;
-		ofs += rv;
-		num_parsed++;
-	}
-	//tlv_dump(dec);
-	return num_parsed;
-}
-
-/* take a master (src) tlvdev and fill up all empty slots in 'dst' */
-void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dst->def); i++) {
-		if (src->def[i].type == TLV_TYPE_NONE)
-			continue;
-		if (dst->def[i].type == TLV_TYPE_NONE)
-			dst->def[i] = src->def[i];
-	}
-}
-
-static __attribute__((constructor)) void on_dso_load_tlv(void)
-{
-	int i;
-	for (i = 0; i < ARRAY_SIZE(tvlv_att_def.def); i++)
-		tvlv_att_def.def[i].type = TLV_TYPE_TvLV;
-}
diff --git a/openbsc/src/token_auth.c b/openbsc/src/token_auth.c
index fd81f03..7fefea5 100644
--- a/openbsc/src/token_auth.c
+++ b/openbsc/src/token_auth.c
@@ -21,7 +21,7 @@
  */
 
 #include <stdio.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/signal.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_04_11.h>
diff --git a/openbsc/src/transaction.c b/openbsc/src/transaction.c
index c972037..75a279d 100644
--- a/openbsc/src/transaction.c
+++ b/openbsc/src/transaction.c
@@ -23,7 +23,7 @@
 #include <openbsc/gsm_data.h>
 #include <openbsc/mncc.h>
 #include <openbsc/debug.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/gsm_04_08.h>
 #include <openbsc/mncc.h>
diff --git a/openbsc/src/trau_mux.c b/openbsc/src/trau_mux.c
index 9930751..f2fa5c0 100644
--- a/openbsc/src/trau_mux.c
+++ b/openbsc/src/trau_mux.c
@@ -30,7 +30,7 @@
 #include <openbsc/subchan_demux.h>
 #include <openbsc/e1_input.h>
 #include <openbsc/debug.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 u_int8_t gsm_fr_map[] = {
 	6, 6, 5, 5, 4, 4, 3, 3,
diff --git a/openbsc/src/vty/buffer.c b/openbsc/src/vty/buffer.c
index 8ab7311..195d062 100644
--- a/openbsc/src/vty/buffer.c
+++ b/openbsc/src/vty/buffer.c
@@ -28,7 +28,7 @@
 #include <stddef.h>
 #include <sys/uio.h>
 
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <vty/buffer.h>
 #include <vty/vty.h>
 
diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c
index 5b1dcb9..2faed35 100644
--- a/openbsc/src/vty/command.c
+++ b/openbsc/src/vty/command.c
@@ -47,7 +47,7 @@
 
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_subscriber.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 void *tall_vty_cmd_ctx;
 
diff --git a/openbsc/src/vty/vector.c b/openbsc/src/vty/vector.c
index 06e1aaa..db47ae5 100644
--- a/openbsc/src/vty/vector.c
+++ b/openbsc/src/vty/vector.c
@@ -24,7 +24,7 @@
 
 #include <vty/vector.h>
 #include <vty/vty.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <memory.h>
 
 void *tall_vty_vec_ctx;
diff --git a/openbsc/src/vty/vty.c b/openbsc/src/vty/vty.c
index 2339bbd..1260f38 100644
--- a/openbsc/src/vty/vty.c
+++ b/openbsc/src/vty/vty.c
@@ -17,7 +17,7 @@
 #include <vty/vty.h>
 #include <vty/command.h>
 #include <vty/buffer.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 
 /* our callback, located in telnet_interface.c */
 void vty_event(enum event event, int sock, struct vty *vty);
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 76598d3..dc70e98 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -28,15 +28,15 @@
 
 #include <arpa/inet.h>
 
-#include <openbsc/linuxlist.h>
+#include <osmocore/linuxlist.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/e1_input.h>
 #include <openbsc/abis_nm.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/chan_alloc.h>
 #include <openbsc/meas_rep.h>
 #include <openbsc/db.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/telnet_interface.h>
 
 static struct gsm_network *gsmnet;
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index f2b5728..b824c3d 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -29,16 +29,16 @@
 
 #include <arpa/inet.h>
 
-#include <openbsc/linuxlist.h>
+#include <osmocore/linuxlist.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/silent_call.h>
 #include <openbsc/gsm_04_11.h>
 #include <openbsc/e1_input.h>
 #include <openbsc/abis_nm.h>
-#include <openbsc/gsm_utils.h>
+#include <osmocore/gsm_utils.h>
 #include <openbsc/db.h>
-#include <openbsc/talloc.h>
+#include <osmocore/talloc.h>
 #include <openbsc/signal.h>
 #include <openbsc/debug.h>
 
diff --git a/openbsc/tests/Makefile.am b/openbsc/tests/Makefile.am
index f40105f..3b1b931 100644
--- a/openbsc/tests/Makefile.am
+++ b/openbsc/tests/Makefile.am
@@ -1 +1 @@
-SUBDIRS = debug timer sms gsm0408 db channel sccp
+SUBDIRS = debug gsm0408 db channel sccp
diff --git a/openbsc/tests/channel/Makefile.am b/openbsc/tests/channel/Makefile.am
index 6b9f6e3..7729659 100644
--- a/openbsc/tests/channel/Makefile.am
+++ b/openbsc/tests/channel/Makefile.am
@@ -1,5 +1,5 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS=-Wall -ggdb3
+AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS)
 
 noinst_PROGRAMS = channel_test
 
@@ -8,14 +8,8 @@
 	$(top_srcdir)/src/gsm_subscriber_base.c \
 	$(top_srcdir)/src/gsm_subscriber.c \
 	$(top_srcdir)/src/debug.c \
-	$(top_srcdir)/src/timer.c \
-	$(top_srcdir)/src/select.c \
-	$(top_srcdir)/src/talloc.c \
 	$(top_srcdir)/src/gsm_data.c \
-	$(top_srcdir)/src/signal.c \
-	$(top_srcdir)/src/statistics.c \
 	$(top_srcdir)/src/bts_ipaccess_nanobts.c \
-	$(top_srcdir)/src/bts_siemens_bs11.c \
-	$(top_srcdir)/src/tlv_parser.c
-channel_test_LDADD = -ldl -ldbi
+	$(top_srcdir)/src/bts_siemens_bs11.c
+channel_test_LDADD = -ldl -ldbi $(LIBOSMOCORE_LIBS)
 
diff --git a/openbsc/tests/channel/channel_test.c b/openbsc/tests/channel/channel_test.c
index 36d0572..759001c 100644
--- a/openbsc/tests/channel/channel_test.c
+++ b/openbsc/tests/channel/channel_test.c
@@ -23,7 +23,7 @@
 
 #include <assert.h>
 
-#include <openbsc/select.h>
+#include <osmocore/select.h>
 #include <openbsc/gsm_subscriber.h>
 #include <openbsc/abis_rsl.h>
 
diff --git a/openbsc/tests/db/Makefile.am b/openbsc/tests/db/Makefile.am
index 8ce7e3c..6eb9180 100644
--- a/openbsc/tests/db/Makefile.am
+++ b/openbsc/tests/db/Makefile.am
@@ -1,8 +1,8 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS=-Wall -ggdb3
+AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS)
 
 noinst_PROGRAMS = db_test
 
 db_test_SOURCES = db_test.c
-db_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libmsc.a $(top_builddir)/src/libbsc.a -ldl -ldbi
+db_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libmsc.a $(top_builddir)/src/libbsc.a $(LIBOSMOCORE_LIBS) -ldl -ldbi
 
diff --git a/openbsc/tests/debug/Makefile.am b/openbsc/tests/debug/Makefile.am
index 62c906e..8423fd1 100644
--- a/openbsc/tests/debug/Makefile.am
+++ b/openbsc/tests/debug/Makefile.am
@@ -1,4 +1,6 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
 noinst_PROGRAMS = debug_test
 
-debug_test_SOURCES = debug_test.c $(top_srcdir)/src/debug.c $(top_srcdir)/src/talloc.c
+debug_test_SOURCES = debug_test.c $(top_srcdir)/src/debug.c 
+debug_test_LDADD = $(LIBOSMOCORE_LIBS)
diff --git a/openbsc/tests/gsm0408/Makefile.am b/openbsc/tests/gsm0408/Makefile.am
index ff8caf9..f98c673 100644
--- a/openbsc/tests/gsm0408/Makefile.am
+++ b/openbsc/tests/gsm0408/Makefile.am
@@ -1,5 +1,6 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
 noinst_PROGRAMS = gsm0408_test
 
 gsm0408_test_SOURCES = gsm0408_test.c
-gsm0408_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libmsc.a $(top_builddir)/src/libbsc.a -ldbi
+gsm0408_test_LDADD = $(top_builddir)/src/libbsc.a $(top_builddir)/src/libmsc.a $(top_builddir)/src/libbsc.a $(LIBOSMOCORE_LIBS) -ldbi
diff --git a/openbsc/tests/sccp/Makefile.am b/openbsc/tests/sccp/Makefile.am
index 5a275fc..b35693e 100644
--- a/openbsc/tests/sccp/Makefile.am
+++ b/openbsc/tests/sccp/Makefile.am
@@ -1,8 +1,8 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS=-Wall -ggdb3
+AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS)
 
 noinst_PROGRAMS = sccp_test
 
 sccp_test_SOURCES = sccp_test.c
-sccp_test_LDADD = $(top_builddir)/src/libsccp.a $(top_builddir)/src/libbsc.a
+sccp_test_LDADD = $(top_builddir)/src/libsccp.a $(top_builddir)/src/libbsc.a $(LIBOSMOCORE_LIBS)
 
diff --git a/openbsc/tests/sccp/sccp_test.c b/openbsc/tests/sccp/sccp_test.c
index 37615e0..982c168 100644
--- a/openbsc/tests/sccp/sccp_test.c
+++ b/openbsc/tests/sccp/sccp_test.c
@@ -2,7 +2,7 @@
  * SCCP testing code
  *
  * (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by on-waves.com
+ * (C) 2009 by On-Waves
  *
  * All Rights Reserved
  *
@@ -26,9 +26,11 @@
 
 #include <arpa/inet.h>
 
-#include <sccp/sccp.h>
 #include <openbsc/gsm_data.h>
 #include <openbsc/debug.h>
+#include <osmocore/msgb.h>
+
+#include <sccp/sccp.h>
 
 #define MIN(x, y) ((x) < (y) ? (x) : (y))
 
diff --git a/openbsc/tests/sms/Makefile.am b/openbsc/tests/sms/Makefile.am
deleted file mode 100644
index 807c674..0000000
--- a/openbsc/tests/sms/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
-noinst_PROGRAMS = sms_test
-
-sms_test_SOURCES = sms_test.c
-sms_test_LDADD = $(top_builddir)/src/libmsc.a $(top_builddir)/src/libbsc.a -ldl -ldbi
diff --git a/openbsc/tests/sms/sms_test.c b/openbsc/tests/sms/sms_test.c
deleted file mode 100644
index 2ce2cc6..0000000
--- a/openbsc/tests/sms/sms_test.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <openbsc/debug.h>
-#include <openbsc/msgb.h>
-#include <openbsc/gsm_data.h>
-#include <openbsc/gsm_utils.h>
-
-int main(int argc, char** argv)
-{
-	DEBUGP(DSMS, "SMS testing\n");
-	struct msgb *msg;
-	u_int8_t *sms;
-	u_int8_t i;
-
-        /* test 7-bit coding/decoding */
-	const char *input = "test text";
-	u_int8_t length;
-	u_int8_t coded[256];
-	char result[256];
-
-	length = gsm_7bit_encode(coded, input);
-	gsm_7bit_decode(result, coded, length);
-	if (strcmp(result, input) != 0) {
-		printf("7 Bit coding failed... life sucks\n");
-		printf("Wanted: '%s' got '%s'\n", input, result);
-	}
-}
-
-/* stubs */
-void input_event(void) {}
-void nm_state_event(void) {}
diff --git a/openbsc/tests/timer/Makefile.am b/openbsc/tests/timer/Makefile.am
deleted file mode 100644
index 9f12d23..0000000
--- a/openbsc/tests/timer/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
-noinst_PROGRAMS = timer_test
-
-timer_test_SOURCES = timer_test.c $(top_srcdir)/src/timer.c $(top_srcdir)/src/select.c
-
diff --git a/openbsc/tests/timer/timer_test.c b/openbsc/tests/timer/timer_test.c
deleted file mode 100644
index 26fcbc9..0000000
--- a/openbsc/tests/timer/timer_test.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-
-#include <openbsc/timer.h>
-#include <openbsc/select.h>
-
-static void timer_fired(unsigned long data);
-
-static struct timer_list timer_one = {
-    .cb = timer_fired,
-    .data = (void*)1,
-};
-
-static struct timer_list timer_two = {
-    .cb = timer_fired,
-    .data = (void*)2,
-};
-
-static struct timer_list timer_three = {
-    .cb = timer_fired,
-    .data = (void*)3,
-};
-
-static void timer_fired(unsigned long data)
-{
-    printf("Fired timer: %lu\n", data);
-
-    if (data == 1) {
-        bsc_schedule_timer(&timer_one, 3, 0);
-        bsc_del_timer(&timer_two);
-    } else if (data == 2) {
-        printf("Should not be fired... bug in del_timer\n");
-    } else if (data == 3) {
-        printf("Timer fired not registering again\n");
-    } else  {
-        printf("wtf... wrong data\n");
-    }
-}
-
-int main(int argc, char** argv)
-{
-    printf("Starting... timer\n");
-
-    bsc_schedule_timer(&timer_one, 3, 0);
-    bsc_schedule_timer(&timer_two, 5, 0);
-    bsc_schedule_timer(&timer_three, 4, 0);
-
-    while (1) {
-        bsc_select_main(0);
-    }
-}