hsl: add support for BTS-mode

This patch adds support for BTS-mode for the hsl input driver.
diff --git a/include/osmocom/abis/ipa.h b/include/osmocom/abis/ipa.h
index 83e4472..7b5b1e8 100644
--- a/include/osmocom/abis/ipa.h
+++ b/include/osmocom/abis/ipa.h
@@ -1,6 +1,7 @@
 #ifndef _OSMO_IPA_H_
 #define _OSMO_IPA_H_
 
+#include <stdint.h>
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/timer.h>
 
@@ -18,10 +19,11 @@
 	struct osmo_timer_list	timer;
 	enum ipa_link_state	state;
 	const char		*addr;
+	uint16_t		port;
 	int (*process)(struct ipa_link *link, struct msgb *msg);
 };
 
-struct ipa_link *ipa_client_link_create(void *ctx, const char *addr);
+struct ipa_link *ipa_client_link_create(void *ctx, const char *addr, uint16_t port);
 void ipa_client_link_destroy(struct ipa_link *link);
 
 int ipa_client_link_open(struct ipa_link *link);
diff --git a/src/input/hsl.c b/src/input/hsl.c
index 3854b06..e6388c8 100644
--- a/src/input/hsl.c
+++ b/src/input/hsl.c
@@ -52,6 +52,7 @@
 #include <osmocom/abis/ipaccess.h>
 #include <osmocom/core/socket.h>
 #include <osmocom/abis/logging.h>
+#include <osmocom/abis/ipa.h>
 #include <talloc.h>
 
 #define HSL_TCP_PORT	2500
@@ -308,8 +309,10 @@
 
 	switch(role) {
 	case E1INP_LINE_R_BSC:
+		LOGP(DINP, LOGL_NOTICE, "enabling hsl BSC mode\n");
+
 		ret = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
-					 "0.0.0.0", HSL_TCP_PORT, 1);
+				     addr, HSL_TCP_PORT, OSMO_SOCK_F_BIND);
 		if (ret < 0)
 			return ret;
 
@@ -323,9 +326,27 @@
 			return ret;
 		}
 		break;
-	case E1INP_LINE_R_BTS:
-		/* XXX: not implemented yet. */
+	case E1INP_LINE_R_BTS: {
+		struct ipa_link *link;
+
+		LOGP(DINP, LOGL_NOTICE, "enabling hsl BTS mode\n");
+
+		link = ipa_client_link_create(tall_hsl_ctx, addr, HSL_TCP_PORT);
+		if (link == NULL) {
+			LOGP(DINP, LOGL_ERROR, "cannot create BTS link: %s\n",
+				strerror(errno));
+			return -ENOMEM;
+		}
+		if (ipa_client_link_open(link) < 0) {
+			LOGP(DINP, LOGL_ERROR, "cannot open BTS link: %s\n",
+				strerror(errno));
+			ipa_client_link_close(link);
+			ipa_client_link_destroy(link);
+			return -EIO;
+		}
+		ret = 0;
 		break;
+	}
 	default:
 		break;
 	}
diff --git a/src/input/ipa.c b/src/input/ipa.c
index 3f37d47..7318e07 100644
--- a/src/input/ipa.c
+++ b/src/input/ipa.c
@@ -176,7 +176,8 @@
 
 static void ipa_link_timer_cb(void *data);
 
-struct ipa_link *ipa_client_link_create(void *ctx, const char *addr)
+struct ipa_link *
+ipa_client_link_create(void *ctx, const char *addr, uint16_t port)
 {
 	struct ipa_link *ipa_link;
 
@@ -191,6 +192,7 @@
 	ipa_link->timer.cb = ipa_link_timer_cb;
 	ipa_link->timer.data = ipa_link;
 	ipa_link->addr = talloc_strdup(ipa_link, addr);
+	ipa_link->port = port;
 
 	return ipa_link;
 }
@@ -205,7 +207,7 @@
 	int ret;
 
 	ret = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
-			     link->addr, IPA_TCP_PORT_OML,
+			     link->addr, link->port,
 			     OSMO_SOCK_F_CONNECT|OSMO_SOCK_F_NONBLOCK);
 	if (ret < 0) {
 		if (errno != EINPROGRESS)
diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c
index 18e30dc..38e942f 100644
--- a/src/input/ipaccess.c
+++ b/src/input/ipaccess.c
@@ -524,7 +524,8 @@
 
 		LOGP(DINP, LOGL_NOTICE, "enabling ipaccess BTS mode\n");
 
-		link = ipa_client_link_create(tall_ipa_ctx, addr);
+		link = ipa_client_link_create(tall_ipa_ctx,
+						addr, IPA_TCP_PORT_OML);
 		if (link == NULL) {
 			perror("ipa_client_link_create: ");
 			return -ENOMEM;