Use implement HNBAP transmit using per-hnb write_queue
diff --git a/src/hnbgw.c b/src/hnbgw.c
index 5e033fa..2db0afb 100644
--- a/src/hnbgw.c
+++ b/src/hnbgw.c
@@ -16,6 +16,7 @@
 #include <osmocom/core/logging.h>
 #include <osmocom/core/socket.h>
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/write_queue.h>
 
 #include <osmocom/vty/telnet_interface.h>
 #include <osmocom/vty/logging.h>
@@ -32,12 +33,12 @@
 	},
 };
 
-static int hnb_socket_cb(struct osmo_fd *fd, unsigned int what)
+static int hnb_read_cb(struct osmo_fd *fd)
 {
 	struct hnb_context *hnb = fd->data;
 	struct sctp_sndrcvinfo sinfo;
 	struct msgb *msg = msgb_alloc(IUH_MSGB_SIZE, "Iuh rx");
-	int flags;
+	int flags = 0;
 	int rc;
 
 	if (!msg)
@@ -56,9 +57,11 @@
 
 	switch (sinfo.sinfo_ppid) {
 	case IUH_PPI_HNBAP:
+		hnb->hnbap_stream = sinfo.sinfo_stream;
 		rc = hnbgw_hnbap_rx(hnb, msg);
 		break;
 	case IUH_PPI_RUA:
+		hnb->rua_stream = sinfo.sinfo_stream;
 		//rc = hnbgw_rua_rx(hnb, msg);
 		break;
 	case IUH_PPI_SABP:
@@ -78,6 +81,22 @@
 	return rc;
 }
 
+static int hnb_write_cb(struct osmo_fd *fd, struct msgb *msg)
+{
+	struct hnb_context *ctx = fd->data;
+	struct sctp_sndrcvinfo sinfo = {
+		.sinfo_ppid = msgb_ppid(msg),
+		.sinfo_stream = ctx->hnbap_stream,
+	};
+	int rc;
+
+	rc = sctp_send(fd->fd, msgb_data(msg), msgb_length(msg),
+			&sinfo, 0);
+	msgb_free(msg);
+
+	return rc;
+}
+
 /*! call-back when the listen FD has something to read */
 static int listen_fd_cb(struct osmo_fd *fd, unsigned int what)
 {
@@ -99,11 +118,13 @@
 		return -ENOMEM;
 
 	ctx->gw = gw;
-	ctx->socket.data = ctx;
-	ctx->socket.fd = new_fd;
-	ctx->socket.when = BSC_FD_READ;
-	ctx->socket.cb = hnb_socket_cb;
-	osmo_fd_register(&ctx->socket);
+	osmo_wqueue_init(&ctx->wqueue, 16);
+	ctx->wqueue.bfd.data = ctx;
+	ctx->wqueue.bfd.fd = new_fd;
+	ctx->wqueue.bfd.when = BSC_FD_READ;
+	ctx->wqueue.read_cb = hnb_read_cb;
+	ctx->wqueue.write_cb = hnb_write_cb;
+	osmo_fd_register(&ctx->wqueue.bfd);
 
 	llist_add_tail(&ctx->list, &gw->hnb_list);
 
diff --git a/src/hnbgw.h b/src/hnbgw.h
index ab8c103..17ce562 100644
--- a/src/hnbgw.h
+++ b/src/hnbgw.h
@@ -2,10 +2,13 @@
 
 #include <osmocom/core/select.h>
 #include <osmocom/core/linuxlist.h>
+#include <osmocom/core/write_queue.h>
 
 #define DEBUG
 #include <osmocom/core/logging.h>
 
+#define msgb_ppid(msg)		(msg)->cb[0]
+
 enum {
 	DMAIN,
 };
@@ -39,12 +42,17 @@
 	struct llist_head list;
 	/*! HNB-GW we are part of */
 	struct hnb_gw *gw;
-	/*! SCTP socket for Iuh to this specific HNB */
-	struct osmo_fd socket;
+	/*! SCTP socket + write queue for Iuh to this specific HNB */
+	struct osmo_wqueue wqueue;
 	/*! copied from HNB-Identity-Info IE */
 	char identity_info[256];
 	/*! copied from Cell Identity IE */
 	struct umts_cell_id id;
+
+	/*! SCTP stream ID for HNBAP */
+	uint16_t hnbap_stream;
+	/*! SCTP stream ID for RUA */
+	uint16_t rua_stream;
 };
 
 struct ue_context {
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index 495c71d..65e5cc9 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -16,7 +16,8 @@
 
 static int hnbgw_hnbap_tx(struct hnb_context *ctx, struct msgb *msg)
 {
-	/* FIXME */
+	msgb_ppid(msg) = IUH_PPI_HNBAP;
+	return osmo_wqueue_enqueue(&ctx->wqueue, msg);
 }
 
 static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx)