src: port openBSC over libosmo-abis

This is a big patch that ports openBSC over libosmo-abis.
Sorry, the changes that are included here are all dependent
of libosmo-abis, splitting them into smaller pieces would
leave the repository in some intermediate state, which is
not desired.

The main changes are:

- The directory libabis/ has been removed as it now lives in
  libosmo-abis.

- new configuration file format for nanoBTS and HSL femto, we
  need to define the virtual e1_line and attach it to the OML
  link.

- all the existing BTS drivers (nanoBTS, hsl femto, Nokia site,
  BS11 and rbs2000) now use the new libosmo-abis framework.

- use r232 input driver available in libosmo-abis for bs11_config.

- use ipa_msg_recv instead of old ipaccess_read_msg function.

- delete definition of gsm_e1_subslot and input_signal_data.
  These structures now lives in libosmo-abis.

Most of this patch are deletions of libabis/ which has been
moved to libosmo-abis.

This patch also modifies openBSC to use all the new definitions
available in libosmocore and libosmo-abis. In order to do that,
we have replaced the following:

- DINP, DMI, DMIB and DMUX by their respective DL* correspondences.
- SS_GLOBAL by SS_L_GLOBAL
- SS_INPUT by SS_L_INPUT
- S_GLOBAL_SHUTDOWN by S_L_GLOBAL_SHUTDOWN
- SS_INPUT by SS_L_INPUT
- S_INP_* by S_L_INP_* sub-signals
- E1INP_NODE by L_E1INP_NODE vty node

This patch has been tested with:
- one nanoBTS
- the HSL femto with the examples available under libosmo-abis
- BS11 with both dahdi and misdn drivers.
diff --git a/openbsc/src/utils/Makefile.am b/openbsc/src/utils/Makefile.am
index c2d2085..a7882ed 100644
--- a/openbsc/src/utils/Makefile.am
+++ b/openbsc/src/utils/Makefile.am
@@ -1,12 +1,12 @@
 INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
-AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
-AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(COVERAGE_LDFLAGS)
+AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS)
+AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOABIS_LIBS) $(COVERAGE_LDFLAGS)
 
 bin_PROGRAMS = bs11_config isdnsync
 
-bs11_config_SOURCES = bs11_config.c rs232.c
+bs11_config_SOURCES = bs11_config.c
 bs11_config_LDADD = $(top_builddir)/src/libcommon/libcommon.a \
-		    $(top_builddir)/src/libabis/libabis.a \
-		    $(top_builddir)/src/libbsc/libbsc.a
+		    $(top_builddir)/src/libbsc/libbsc.a \
+		    $(top_builddir)/src/libtrau/libtrau.a
 
 isdnsync_SOURCES = isdnsync.c
diff --git a/openbsc/src/utils/bs11_config.c b/openbsc/src/utils/bs11_config.c
index ef01072..e8acb46 100644
--- a/openbsc/src/utils/bs11_config.c
+++ b/openbsc/src/utils/bs11_config.c
@@ -41,6 +41,12 @@
 #include <osmocom/core/select.h>
 #include <openbsc/rs232.h>
 #include <osmocom/core/application.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/abis/abis.h>
+#include <osmocom/abis/e1_input.h>
+
+static void *tall_bs11cfg_ctx;
+static struct e1inp_sign_link *oml_link;
 
 /* state of our bs11_config application */
 enum bs11cfg_state {
@@ -638,8 +644,9 @@
 }
 
 /* handle a fully-received message/packet from the RS232 port */
-int handle_serial_msg(struct msgb *rx_msg)
+static int abis_nm_bs11cfg_rcvmsg(struct msgb *rx_msg)
 {
+	struct e1inp_sign_link *link = rx_msg->dst;
 	struct abis_om_hdr *oh;
 	struct abis_om_fom_hdr *foh;
 	struct tlv_parsed tp;
@@ -719,6 +726,8 @@
 		perror("ERROR in main loop");
 		//break;
 	}
+	/* flush the queue of pending messages to be sent. */
+	abis_nm_queue_send_next(link->trx->bts);
 	if (rc == 1)
 		return rc;
 
@@ -864,11 +873,21 @@
 	}
 }
 
+static int bs11cfg_sign_link(struct msgb *msg)
+{
+	msg->dst = oml_link;
+	return abis_nm_bs11cfg_rcvmsg(msg);
+}
+
+struct e1inp_line_ops bs11cfg_e1inp_line_ops = {
+	.sign_link	= bs11cfg_sign_link,
+};
+
 extern int bts_model_bs11_init(void);
 int main(int argc, char **argv)
 {
 	struct gsm_network *gsmnet;
-	int rc;
+	struct e1inp_line *line;
 
 	osmo_init_logging(&log_info);
 	handle_options(argc, argv);
@@ -882,11 +901,35 @@
 	g_bts = gsm_bts_alloc_register(gsmnet, GSM_BTS_TYPE_BS11, HARDCODED_TSC,
 					HARDCODED_BSIC);
 
-	rc = rs232_setup(serial_port, delay_ms, g_bts);
-	if (rc < 0) {
-		fprintf(stderr, "Problem setting up serial port\n");
+	/* Override existing OML callback handler to set our own. */
+	g_bts->model->oml_rcvmsg = abis_nm_bs11cfg_rcvmsg;
+
+	libosmo_abis_init(tall_bs11cfg_ctx);
+
+	/* Initialize virtual E1 line over rs232. */
+	line = talloc_zero(tall_bs11cfg_ctx, struct e1inp_line);
+	if (!line) {
+		fprintf(stderr, "Unable to allocate memory for virtual E1 line\n");
 		exit(1);
 	}
+	/* set the serial port. */
+	bs11cfg_e1inp_line_ops.cfg.rs232.port = serial_port;
+	bs11cfg_e1inp_line_ops.cfg.rs232.delay = delay_ms;
+
+	line->driver = e1inp_driver_find("rs232");
+	if (!line->driver) {
+		fprintf(stderr, "cannot find `rs232' driver, giving up.\n");
+		exit(1);
+	}
+	e1inp_line_bind_ops(line, &bs11cfg_e1inp_line_ops);
+
+	/* configure and create signalling link for OML. */
+	e1inp_ts_config_sign(&line->ts[0], line);
+	g_bts->oml_link = oml_link =
+		e1inp_sign_link_create(&line->ts[0], E1INP_SIGN_OML,
+					g_bts->c0, TEI_OML, 0);
+
+	e1inp_line_update(line);
 
 	signal(SIGINT, &signal_handler);
 
@@ -904,8 +947,3 @@
 
 	exit(0);
 }
-
-/* dummy to be able to compile */
-void gsm_net_update_ctype(struct gsm_network *net)
-{
-}
diff --git a/openbsc/src/utils/rs232.c b/openbsc/src/utils/rs232.c
deleted file mode 100644
index 01b8c7e..0000000
--- a/openbsc/src/utils/rs232.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* OpenBSC BS-11 T-Link interface using POSIX serial port */
-
-/* (C) 2008-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 Affero General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <termios.h>
-#include <fcntl.h>
-
-#include <osmocom/core/select.h>
-#include <osmocom/core/msgb.h>
-#include <openbsc/debug.h>
-#include <openbsc/gsm_data.h>
-#include <openbsc/rs232.h>
-
-/* adaption layer from GSM 08.59 + 12.21 to RS232 */
-
-struct serial_handle {
-	struct osmo_fd fd;
-	struct llist_head tx_queue;
-
-	struct msgb *rx_msg;
-	unsigned int rxmsg_bytes_missing;
-
-	unsigned int delay_ms;
-	struct gsm_bts *bts;
-};
-
-/* FIXME: this needs to go */
-static struct serial_handle _ser_handle, *ser_handle = &_ser_handle;
-
-#define LAPD_HDR_LEN	10
-
-static int handle_ser_write(struct osmo_fd *bfd);
-
-/* callback from abis_nm */
-int _abis_nm_sendmsg(struct msgb *msg, int to_trx_oml)
-{
-	struct serial_handle *sh = ser_handle;
-	uint8_t *lapd;
-	unsigned int len;
-
-	msg->l2h = msg->data;
-
-	/* prepend LAPD header */
-	lapd = msgb_push(msg, LAPD_HDR_LEN);
-
-	len = msg->len - 2;
-
-	lapd[0] = (len >> 8) & 0xff;
-	lapd[1] = len & 0xff; /* length of bytes startign at lapd[2] */
-	lapd[2] = 0x00;
-	lapd[3] = 0x07;
-	lapd[4] = 0x01;
-	lapd[5] = 0x3e;
-	lapd[6] = 0x00;
-	lapd[7] = 0x00;
-	lapd[8] = msg->len - 10; /* length of bytes starting at lapd[10] */
-	lapd[9] = lapd[8] ^ 0x38;
-
-	msgb_enqueue(&sh->tx_queue, msg);
-	sh->fd.when |= BSC_FD_WRITE;
-
-	/* we try to immediately send */
-	handle_ser_write(&sh->fd);
-
-	return 0;
-}
-
-/* select.c callback in case we can write to the RS232 */
-static int handle_ser_write(struct osmo_fd *bfd)
-{
-	struct serial_handle *sh = bfd->data;
-	struct msgb *msg;
-	int written;
-
-	msg = msgb_dequeue(&sh->tx_queue);
-	if (!msg) {
-		bfd->when &= ~BSC_FD_WRITE;
-		return 0;
-	}
-
-	DEBUGP(DMI, "RS232 TX: %s\n", osmo_hexdump(msg->data, msg->len));
-
-	/* send over serial line */
-	written = write(bfd->fd, msg->data, msg->len);
-	if (written < msg->len) {
-		perror("short write:");
-		msgb_free(msg);
-		return -1;
-	}
-
-	msgb_free(msg);
-	usleep(sh->delay_ms*1000);
-
-	return 0;
-}
-
-#define SERIAL_ALLOC_SIZE	300
-
-/* select.c callback in case we can read from the RS232 */
-static int handle_ser_read(struct osmo_fd *bfd)
-{
-	struct serial_handle *sh = bfd->data;
-	struct msgb *msg;
-	int rc = 0;
-
-	if (!sh->rx_msg) {
-		sh->rx_msg = msgb_alloc(SERIAL_ALLOC_SIZE, "RS232 Rx");
-		sh->rx_msg->l2h = NULL;
-		sh->rx_msg->dst = sh->bts->c0->rsl_link;
-	}
-	msg = sh->rx_msg;
-
-	/* first read two byes to obtain length */
-	if (msg->len < 2) {
-		rc = read(sh->fd.fd, msg->tail, 2 - msg->len);
-		if (rc < 0) {
-			perror("ERROR reading from serial port");
-			msgb_free(msg);
-			return rc;
-		}
-		msgb_put(msg, rc);
-
-		if (msg->len >= 2) {
-			/* parse LAPD payload length */
-			if (msg->data[0] != 0)
-				fprintf(stderr, "Suspicious header byte 0: 0x%02x\n",
-					msg->data[0]);
-
-			sh->rxmsg_bytes_missing = msg->data[0] << 8;
-			sh->rxmsg_bytes_missing += msg->data[1];
-
-			if (sh->rxmsg_bytes_missing < LAPD_HDR_LEN -2)
-				fprintf(stderr, "Invalid length in hdr: %u\n",
-					sh->rxmsg_bytes_missing);
-		}
-	} else {
-		/* try to read as many of the missing bytes as are available */
-		rc = read(sh->fd.fd, msg->tail, sh->rxmsg_bytes_missing);
-		if (rc < 0) {
-			perror("ERROR reading from serial port");
-			msgb_free(msg);
-			return rc;
-		}
-		msgb_put(msg, rc);
-		sh->rxmsg_bytes_missing -= rc;
-
-		if (sh->rxmsg_bytes_missing == 0) {
-			/* we have one complete message now */
-			sh->rx_msg = NULL;
-
-			if (msg->len > LAPD_HDR_LEN)
-				msg->l2h = msg->data + LAPD_HDR_LEN;
-
-			DEBUGP(DMI, "RS232 RX: %s\n", osmo_hexdump(msg->data, msg->len));
-			rc = handle_serial_msg(msg);
-		}
-	}
-
-	return rc;
-}
-
-/* select.c callback */
-static int serial_fd_cb(struct osmo_fd *bfd, unsigned int what)
-{
-	int rc = 0;
-
-	if (what & BSC_FD_READ)
-		rc = handle_ser_read(bfd);
-
-	if (rc < 0)
-		return rc;
-
-	if (what & BSC_FD_WRITE)
-		rc = handle_ser_write(bfd);
-
-	return rc;
-}
-
-int rs232_setup(const char *serial_port, unsigned int delay_ms,
-		struct gsm_bts *bts)
-{
-	int rc, serial_fd;
-	struct termios tio;
-
-	serial_fd = open(serial_port, O_RDWR);
-	if (serial_fd < 0) {
-		perror("cannot open serial port:");
-		return serial_fd;
-	}
-
-	/* set baudrate */
-	rc = tcgetattr(serial_fd, &tio);
-	if (rc < 0) {
-		perror("tcgetattr()");
-		return rc;
-	}
-	cfsetispeed(&tio, B19200);
-	cfsetospeed(&tio, B19200);
-	tio.c_cflag |=  (CREAD | CLOCAL | CS8);
-	tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
-	tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
-	tio.c_iflag |=  (INPCK | ISTRIP);
-	tio.c_iflag &= ~(ISTRIP | IXON | IXOFF | IGNBRK | INLCR | ICRNL | IGNCR);
-	tio.c_oflag &= ~(OPOST);
-	rc = tcsetattr(serial_fd, TCSADRAIN, &tio);
-	if (rc < 0) {
-		perror("tcsetattr()");
-		return rc;
-	}
-
-	INIT_LLIST_HEAD(&ser_handle->tx_queue);
-	ser_handle->fd.fd = serial_fd;
-	ser_handle->fd.when = BSC_FD_READ;
-	ser_handle->fd.cb = serial_fd_cb;
-	ser_handle->fd.data = ser_handle;
-	ser_handle->delay_ms = delay_ms;
-	ser_handle->bts = bts;
-	rc = osmo_fd_register(&ser_handle->fd);
-	if (rc < 0) {
-		fprintf(stderr, "could not register FD: %s\n",
-			strerror(rc));
-		return rc;
-	}
-
-	return 0;
-}