very early intial code snippets for handling HNBAP in a HNB-GW
diff --git a/src/hnbap_const.h b/src/hnbap_const.h
new file mode 100644
index 0000000..7d3dfa3
--- /dev/null
+++ b/src/hnbap_const.h
@@ -0,0 +1,55 @@
+#pragma once
+
+/* should be auto-generated by ffasn1c, but isn't :( */
+enum hnbap_procedure_code {
+	HNBAP_PC_HNBRegister		= 1,
+	HNBAP_PC_HNBDe_Register 	= 2,
+	HNBAP_PC_UERegister		= 3,
+	HNBAP_PC_UEDe_Register		= 4,
+	HNBAP_PC_ErrorIndication	= 5,
+	HNBAP_PC_privateMessage		= 6,
+	HNBAP_PC_CSGMembershipUpdate	= 7,
+	HNBAP_PC_TNLUpdate		= 9,
+	HNBAP_PC_HNBConfigTransfer	= 10,
+	HNBAP_PC_RelocationComplete	= 11,
+	HNBAP_PC_U_RNTIQuery		= 14,
+};
+
+/* should be auto-generated by ffasn1c, but isn't :( */
+enum hnbap_iei {
+	HNBAP_IEI_Cause				= 1,
+	HNBAP_IEI_CriticalityDiagnostics	= 2,
+	HNBAP_IEI_HNB_Identity			= 3,
+	HNBAP_IEI_Context_ID			= 4,
+	HNBAP_IEI_UE_Identity			= 5,
+	HNBAP_IEI_LAC				= 6,
+	HNBAP_IEI_RAC				= 7,
+	HNBAP_IEI_HNB_Location_Information	= 8,
+	HNBAP_IEI_PLMNidentity			= 9,
+	HNBAP_IEI_SAC				= 10,
+	HNBAP_IEI_CellIdentity			= 11,
+	HNBAP_IEI_RegistrationCause		= 12,
+	HNBAP_IEI_UE_Capabilities		= 13,
+	HNBAP_IEI_RNC_ID			= 14,
+	HNBAP_IEI_CSG_ID			= 15,
+	HNBAP_IEI_BackoffTimer			= 16,
+	HNBAP_IEI_HNB_Internet_Information	= 17,
+	HNBAP_IEI_HNB_Cell_Acces_Mode		= 18,
+	HNBAP_IEI_MuxPortNumber			= 19,
+	HNBAP_IEI_Service_Area_For_Broadcast	= 20,
+	HNBAP_IEI_CSGMembershipStatus		= 21,
+	HNBAP_IEI_RABList			= 22,
+	HNBAP_IEI_HNBConfigInfo			= 23,
+	HNBAP_IEI_AccessResult			= 25,
+	HNBAP_IEI_Update_cause			= 26,
+	HNBAP_IEI_NeighborInfoList		= 27,
+	HNBAP_IEI_NeighborInfoRequestList	= 28,
+	HNBAP_IEI_Iurh_Signalling_TNL_Address	= 29,
+	HNBAP_IEI_PSC				= 30,
+	HNBAP_IEI_HNB_Cell_Identifier		= 31,
+	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.h b/src/hnbgw.h
new file mode 100644
index 0000000..87a5a2f
--- /dev/null
+++ b/src/hnbgw.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/linuxlist.h>
+
+struct hnb_context {
+	/*! Entry in HNB-global list of HNB */
+	struct llist_head list;
+	/*! SCTP socket for Iuh to this specific HNB */
+	struct osmo_fd socket;
+
+	/*! copied from HNB-Identity-Info */
+	char identity[256];
+};
+
+struct ue_context {
+	struct llist_head list;
+	uint32_t context_id;
+};
+
+struct hnb_gw {
+	struct {
+		/*! SCTP port for Iuh listening */
+		uint16_t iuh_listen_port;
+	} config;
+	/*! SCTP listen socket for incoming connections */
+	struct osmo_fd listen_fd;
+	struct llist_head hnb_list;
+};
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
new file mode 100644
index 0000000..9b674ad
--- /dev/null
+++ b/src/hnbgw_hnbap.c
@@ -0,0 +1,138 @@
+#include <osmocom/core/msgb.h>
+
+#include "hnbgw.h"
+#include "hnbap_const.h"
+
+static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu)
+{
+	/* FIXME */
+}
+
+static int hnbgw_tx_hnb_register_acc()
+{
+	/* FIXME */
+	/* Single required response IE: RNC-ID */
+}
+
+static int hnbgw_tx_ue_register_acc()
+{
+	/* FIXME */
+	/* Single required response IE: RNC-ID */
+}
+
+struct ProtocolIE_Field_1 *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id)
+{
+	for (i = 0; i < cont->count; i++) {
+		if (cont->tab[i].id == id)
+			return &cont->tab[i];
+	}
+	return NULL;
+}
+
+static int hnbgw_rx_hnb_register_req(struct HNBRegisterRequest *req)
+{
+	HNB_Identity *identity =
+		FIND_IE(req->protocolIEs, HNBAP_IEI_HNB_Identity);
+	HNB_Location_Information *loc =
+		FIND_IE(req->protocolIEs, HNBAP_IEI_HNB_Location_Information);
+	PLMNidentity *plmn_id =
+		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);
+	/* Optional: CSG-ID */
+
+	if(!identity || !loc || !plmn_id || !cell_id || !lac || !rac || !sac)
+		return -1;
+
+	/* FIXME: Send HNBRegisterAccept */
+}
+
+static int hnbgw_rx_ue_register_req(struct UERegisterRequest *req)
+{
+	UE_Identity *id =
+		FIND_IE(req->protocolIEs, HNBAP_IEI_UE_Identity);
+	Registration_Cause *reg_cause =
+		FIND_IE(req->protocolIEs, HNBAP_IEI_RegistrationCause);
+	UE_Capabilities *ue_cap =
+		FIND_IE(req->protocolIEs, HNBAP_IEI_UE_Capabilities);
+
+	if (!id || !reg_cause || !ue_cap)
+		return -1;
+
+	/* FIXME: Send UERegisterAccept */
+}
+
+static int hnbgw_rx_initiating_msg(struct InitiatingMessage *msg)
+{
+	int rc;
+
+	switch (msg->procedureCode) {
+	case HNBAP_PC_HNBRegister:	/* 8.2 */
+		if (msg->value.type != asn1_type_HNBRegisterRequest)
+			return -1;
+		rc = hnbgw_rx_hnb_register_req();
+		break;
+	case HNBAP_PC_HNBDe_Register:	/* 8.3 */
+		break;
+	case HNBAP_PC_UERegister: 	/* 8.4 */
+		if (msg->value.type != asn1_type_UERegisterRequest)
+			return -1;
+		rc = hnbgw_rx_ue_register_req();
+		break;
+	case HNBAP_PC_UEDe_Register:	/* 8.5 */
+		break;
+	case HNBAP_PC_ErrorIndication:	/* 8.6 */
+	case HNBAP_PC_TNLUpdate:	/* 8.9 */
+	case HNBAP_PC_HNBConfigTransfer:	/* 8.10 */
+	case HNBAP_PC_RelocationComplete:	/* 8.11 */
+	case HNBAP_PC_U_RNTIQuery:	/* 8.12 */
+	case HNBAP_PC_privateMessage:
+		break;
+	default:
+		break;
+	}
+}
+
+static int hnbgw_rx_successful_outcome_msg(struct SuccessfulOutcome *msg)
+{
+
+}
+
+static int hnbgw_rx_unsuccessful_outcome_msg(struct UnsuccessfulOutcome *msg)
+{
+
+}
+
+
+static int _hnbgw_hnbap_rx(struct HNBAP_PDU *pdu)
+{
+	/* 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);
+		break;
+	case HNBAP_PDU_successfulOutcome:
+		rc = hnbgw_rx_successful_outcome_msg(&pdu->u.successfulOutcome);
+		break;
+	case HNBAP_PDU_unsuccessfulOutcome:
+		rc = hnbgw_rx_unsuccessful_outcome_msg(&pdu->u.unsuccessfulOutcome);
+		break;
+	default:
+		return -1;
+	}
+}
+
+int hnbgw_hnbap_rx(struct msgb *msg)
+{
+	/* FIXME: decode and handle to _hnbgw_hnbap_rx() */
+}
+
+
+int hnbgw_hnbap_init(void)
+{
+
+}