first compiling code (untested)
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..18ec5bb
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,15 @@
+LIBFFASN1_DIR=../../../kommerz/sysmocom/git/admin/ffasn1c/libffasn1
+
+CFLAGS=-g -Wall `pkg-config --cflags libosmocore libosmovty libosmogsm` -I$(LIBFFASN1_DIR)
+LDFLAGS=`pkg-config --libs libosmocore libosmovty libosmogsm` -lsctp -L$(LIBFFASN1_DIR) -lffasn1
+
+all: hnbgw
+
+hnbgw: hnbgw.o hnbgw_hnbap.o hnbap.o
+	$(CC) $(LDFLAGS) -o $@ $^
+
+%.o: %.c
+	$(CC) $(CFLAGS) -o $@ -c $^
+
+clean:
+	@rm -f hmbgw *.o
diff --git a/src/hnbap.c b/src/hnbap.c
new file mode 120000
index 0000000..9373ccc
--- /dev/null
+++ b/src/hnbap.c
@@ -0,0 +1 @@
+../asn1/hnbap/ffasn1c/hnbap.c
\ No newline at end of file
diff --git a/src/hnbap.h b/src/hnbap.h
new file mode 120000
index 0000000..6b16029
--- /dev/null
+++ b/src/hnbap.h
@@ -0,0 +1 @@
+../asn1/hnbap/ffasn1c/hnbap.h
\ No newline at end of file
diff --git a/src/hnbap_const.h b/src/hnbap_const.h
index 7d3dfa3..36c5422 100644
--- a/src/hnbap_const.h
+++ b/src/hnbap_const.h
@@ -50,6 +50,5 @@
 	HNBAP_IEI_HNB_Tunnel_Information	= 41,
 	HNBAP_IEI_CELL_FACHMobilitySupport	= 42,
 	HNBAP_IEI_S_RNTIPrefix			= 43,
-	HNBAP_IEI_S_RNTIPrefix			= 43,
 	/* FIXME */
 };
diff --git a/src/hnbgw.c b/src/hnbgw.c
index fc26d0d..a5015ae 100644
--- a/src/hnbgw.c
+++ b/src/hnbgw.c
@@ -1,9 +1,29 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <signal.h>
 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/sctp.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/talloc.h>
 #include <osmocom/core/select.h>
+#include <osmocom/core/logging.h>
 #include <osmocom/core/socket.h>
-#include <osmocom/core/linuxlist.h>
+#include <osmocom/core/msgb.h>
+
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/logging.h>
 
 #include "hnbgw.h"
+#include "hnbgw_hnbap.h"
+
+static void *tall_hnb_ctx;
 
 struct hnb_gw g_hnb_gw = {
 	.config = {
@@ -35,7 +55,7 @@
 		rc = hnbgw_hnbap_rx(hnb, msg);
 		break;
 	case IUH_PPI_RUA:
-		rc = hnbgw_rua_rx(hnb, msg);
+		//rc = hnbgw_rua_rx(hnb, msg);
 		break;
 	case IUH_PPI_SABP:
 	case IUH_PPI_RNA:
@@ -58,8 +78,8 @@
 static int listen_fd_cb(struct osmo_fd *fd, unsigned int what)
 {
 	struct hnb_gw *gw = fd->data;
-	struct hmb_context *ctx;
-	struct sokaddr_storage sockaddr;
+	struct hnb_context *ctx;
+	struct sockaddr_storage sockaddr;
 	socklen_t len = sizeof(sockaddr);
 
 	int new_fd = accept(fd->fd, (struct sockaddr *)&sockaddr, &len);
@@ -79,19 +99,77 @@
 	ctx->socket.fd = new_fd;
 	ctx->socket.when = BSC_FD_READ;
 	ctx->socket.cb = hnb_socket_cb;
-	osmo_fd_register(&cttx->socket);
+	osmo_fd_register(&ctx->socket);
+
+	llist_add_tail(&ctx->list, &gw->hnb_list);
 
 	return 0;
 }
 
+static const struct log_info_cat log_cat[] = {
+	[DMAIN] = {
+		.name = "DMAIN", .loglevel = LOGL_DEBUG, .enabled = 1,
+		.color = "",
+		.description = "Main program",
+	},
+};
 
+static const struct log_info hnbgw_log_info = {
+	.cat = log_cat,
+	.num_cat = ARRAY_SIZE(log_cat),
+};
 
+static struct vty_app_info vty_info = {
+	.name		= "OsmoHNBGW",
+	.version	= "0",
+};
+
+static int daemonize = 0;
+
+int main(int argc, char **argv)
 {
+	int rc;
+
+	tall_hnb_ctx = talloc_named_const(NULL, 0, "hnb_context");
+
 	g_hnb_gw.listen_fd.cb = listen_fd_cb;
 	g_hnb_gw.listen_fd.when = BSC_FD_READ;
 	g_hnb_gw.listen_fd.data = &g_hnb_gw;
 
-	osmo_sock_init_ofd(&g_hnb_gw.listen_fd, AF_INET, SOCK_STREAM,
+	rc = osmo_init_logging(&hnbgw_log_info);
+	if (rc < 0)
+		exit(1);
+
+	vty_init(&vty_info);
+
+	rc = telnet_init(NULL, &g_hnb_gw, 2323);
+	if (rc < 0) {
+		perror("Error binding VTY port");
+		exit(1);
+	}
+
+	rc = osmo_sock_init_ofd(&g_hnb_gw.listen_fd, AF_INET, SOCK_STREAM,
 			   IPPROTO_SCTP, "127.0.0.1",
 			   g_hnb_gw.config.iuh_listen_port, OSMO_SOCK_F_BIND);
+	if (rc < 0) {
+		perror("Error binding Iuh port");
+		exit(1);
+	}
+
+	if (daemonize) {
+		rc = osmo_daemonize();
+		if (rc < 0) {
+			perror("Error during daemonize");
+			exit(1);
+		}
+	}
+
+	while (1) {
+		rc = osmo_select_main(0);
+		if (rc < 0)
+			exit(3);
+	}
+
+	/* not reached */
+	exit(0);
 }
diff --git a/src/hnbgw.h b/src/hnbgw.h
index 7b69a10..ab8c103 100644
--- a/src/hnbgw.h
+++ b/src/hnbgw.h
@@ -3,6 +3,14 @@
 #include <osmocom/core/select.h>
 #include <osmocom/core/linuxlist.h>
 
+#define DEBUG
+#include <osmocom/core/logging.h>
+
+enum {
+	DMAIN,
+};
+
+
 /* 25.467 Section 7.1 */
 #define IUH_DEFAULT_SCTP_PORT	29169
 #define RNA_DEFAULT_SCTP_PORT	25471
@@ -13,7 +21,7 @@
 #define IUH_PPI_RNA		42
 #define IUH_PPI_PUA		55
 
-#define IHU_MSGB_SIZE	2048
+#define IUH_MSGB_SIZE	2048
 
 struct umts_cell_id {
 	uint16_t mcc;	/*!< Mobile Country Code */
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index ce41222..fd3a328 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -1,8 +1,14 @@
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/utils.h>
 
+#include <unistd.h>
+#include <string.h>
+
+#include "hnbap.h"
 #include "hnbgw.h"
 #include "hnbap_const.h"
 
+
 static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu)
 {
 	/* FIXME */
@@ -20,11 +26,19 @@
 	/* Single required response IE: RNC-ID */
 }
 
-struct ProtocolIE_Field_1 *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id)
+#define FIND_IE(cont, id) find_ie((const struct ProtocolIE_Container_1 *)cont, id)
+
+static void *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id)
 {
+	int i;
+
 	for (i = 0; i < cont->count; i++) {
-		if (cont->tab[i].id == id)
-			return &cont->tab[i];
+		ProtocolIE_Field_1 *field = &cont->tab[i];
+		if (field->id == id) {
+			OSMO_ASSERT(field->value.type);
+			/* FIXME: we shoudl check if it is the correct type, not just any type */
+			return field->value.u.data;
+		}
 	}
 	return NULL;
 }
@@ -56,29 +70,30 @@
 static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, struct HNBRegisterRequest *req)
 {
 	HNB_Identity *identity =
-		FIND_IE(req->protocolIEs, HNBAP_IEI_HNB_Identity);
+		FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Identity);
 	HNB_Location_Information *loc =
-		FIND_IE(req->protocolIEs, HNBAP_IEI_HNB_Location_Information);
+		FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Location_Information);
 	PLMNidentity *plmn_id =
-		FIND_IE(req->protocolIEs, HNBAP_IEI_PLMNidentity);
+		FIND_IE(&req->protocolIEs, HNBAP_IEI_PLMNidentity);
 	CellIdentity *cell_id =
-		FIND_IE(req->protocolIEs, HNBAP_IEI_CellIdentity);
-	LAC *lac = FIND_IE(req->protocolIEs, HNBAP_IEI_LAC);
-	RAC *rac = FIND_IE(req->protocolIEs, HNBAP_IEI_RAC);
-	SAC *sac = FIND_IE(req->protocolIEs, HNBAP_IEI_SAC);
+		FIND_IE(&req->protocolIEs, HNBAP_IEI_CellIdentity);
+	LAC *lac = FIND_IE(&req->protocolIEs, HNBAP_IEI_LAC);
+	RAC *rac = FIND_IE(&req->protocolIEs, HNBAP_IEI_RAC);
+	SAC *sac = FIND_IE(&req->protocolIEs, HNBAP_IEI_SAC);
 	/* Optional: CSG-ID */
 
 	if(!identity || !loc || !plmn_id || !cell_id || !lac || !rac || !sac)
 		return -1;
 
 	/* copy all identity parameters from the message to ctx */
-	strncpy(ctx->identity_info, sizeof(ctx->identity_info, identity_info->buf);
+	strncpy(ctx->identity_info, (const char *) identity->hNB_Identity_Info.buf,
+		sizeof(ctx->identity_info));
 	ctx->id.lac = asn1str_to_u16(lac);
 	ctx->id.sac = asn1str_to_u16(sac);
 	ctx->id.rac = asn1str_to_u8(rac);
 	ctx->id.cid = asn1bitstr_to_u32(cell_id);
-	ctx->id.mcc FIXME
-	ctx->id.mnc FIXME
+	//ctx->id.mcc FIXME
+	//ctx->id.mnc FIXME
 
 	/* FIXME: Send HNBRegisterAccept */
 }
@@ -86,11 +101,11 @@
 static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, struct UERegisterRequest *req)
 {
 	UE_Identity *id =
-		FIND_IE(req->protocolIEs, HNBAP_IEI_UE_Identity);
+		FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Identity);
 	Registration_Cause *reg_cause =
-		FIND_IE(req->protocolIEs, HNBAP_IEI_RegistrationCause);
+		FIND_IE(&req->protocolIEs, HNBAP_IEI_RegistrationCause);
 	UE_Capabilities *ue_cap =
-		FIND_IE(req->protocolIEs, HNBAP_IEI_UE_Capabilities);
+		FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Capabilities);
 
 	if (!id || !reg_cause || !ue_cap)
 		return -1;
@@ -98,22 +113,22 @@
 	/* FIXME: Send UERegisterAccept */
 }
 
-static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, struct InitiatingMessage *msg)
+static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, struct InitiatingMessage *imsg)
 {
 	int rc;
 
-	switch (msg->procedureCode) {
+	switch (imsg->procedureCode) {
 	case HNBAP_PC_HNBRegister:	/* 8.2 */
-		if (msg->value.type != asn1_type_HNBRegisterRequest)
+		if (imsg->value.type != asn1_type_HNBRegisterRequest)
 			return -1;
-		rc = hnbgw_rx_hnb_register_req(hnb, FIXME);
+		rc = hnbgw_rx_hnb_register_req(hnb, imsg->value.u.data);
 		break;
 	case HNBAP_PC_HNBDe_Register:	/* 8.3 */
 		break;
 	case HNBAP_PC_UERegister: 	/* 8.4 */
-		if (msg->value.type != asn1_type_UERegisterRequest)
+		if (imsg->value.type != asn1_type_UERegisterRequest)
 			return -1;
-		rc = hnbgw_rx_ue_register_req(hnb, FIXME);
+		rc = hnbgw_rx_ue_register_req(hnb, imsg->value.u.data);
 		break;
 	case HNBAP_PC_UEDe_Register:	/* 8.5 */
 		break;
@@ -129,12 +144,12 @@
 	}
 }
 
-static int hnbgw_rx_successful_outcome_msg(struct SuccessfulOutcome *msg)
+static int hnbgw_rx_successful_outcome_msg(struct hnb_context *hnb, struct SuccessfulOutcome *msg)
 {
 
 }
 
-static int hnbgw_rx_unsuccessful_outcome_msg(struct UnsuccessfulOutcome *msg)
+static int hnbgw_rx_unsuccessful_outcome_msg(struct hnb_context *hnb, struct UnsuccessfulOutcome *msg)
 {
 
 }
@@ -142,17 +157,19 @@
 
 static int _hnbgw_hnbap_rx(struct hnb_context *hnb, struct HNBAP_PDU *pdu)
 {
+	int rc;
+
 	/* it's a bit odd that we can't dispatch on procedure code, but
 	 * that's not possible */
 	switch (pdu->choice) {
 	case HNBAP_PDU_initiatingMessage:
-		rc = hnbgw_rx_initiating_msg(&pdu->u.initiatingMessage);
+		rc = hnbgw_rx_initiating_msg(hnb, &pdu->u.initiatingMessage);
 		break;
 	case HNBAP_PDU_successfulOutcome:
-		rc = hnbgw_rx_successful_outcome_msg(&pdu->u.successfulOutcome);
+		rc = hnbgw_rx_successful_outcome_msg(hnb, &pdu->u.successfulOutcome);
 		break;
 	case HNBAP_PDU_unsuccessfulOutcome:
-		rc = hnbgw_rx_unsuccessful_outcome_msg(&pdu->u.unsuccessfulOutcome);
+		rc = hnbgw_rx_unsuccessful_outcome_msg(hnb, &pdu->u.unsuccessfulOutcome);
 		break;
 	default:
 		return -1;
diff --git a/src/hnbgw_hnbap.h b/src/hnbgw_hnbap.h
new file mode 100644
index 0000000..955e0aa
--- /dev/null
+++ b/src/hnbgw_hnbap.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "hnbgw.h"
+
+int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg);
+int hnbgw_hnbap_init(void);