hnbgw: Actually link in + call ffasn1c runtime library
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index 8d9e1c8..9db670e 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -2,6 +2,7 @@
 #include <osmocom/core/utils.h>
 
 #include <unistd.h>
+#include <errno.h>
 #include <string.h>
 
 #include "asn1helpers.h"
@@ -10,6 +11,49 @@
 #include "hnbgw.h"
 #include "hnbap_const.h"
 
+#define IU_MSG_NUM_IES		32
+#define IU_MSG_NUM_EXT_IES	32
+
+/* common structure of a HNBAP / RUA / RANAP message, must have identical
+ * memory footprint as the other messages, such as HNBRegisterRequest */
+struct iu_common_msg {
+	ProtocolIE_Container_1 protocolIEs;
+	BOOL protocolExtensions_option;
+	ProtocolIE_Container_1 protocolExtensions;
+};
+
+/* Add an IE to a Iu message
+ * \param _msg Message to which we want to add
+ * \param[in] ie Information Element to be added (ffasn1c generated struct)
+ * \param[in] iei Information Element Identifier
+ * \param[in] type asn1_type of the IE
+ * \param[in] ext should this be an extension field?
+ */
+int iu_msg_add_ie(void *_msg, void *ie, int iei, ASN1CType *type, int ext)
+{
+	struct iu_common_msg *msg = _msg;
+	ProtocolIE_Field_1 *field;
+
+	if (ext) {
+		msg->protocolExtensions_option = TRUE;
+		if (msg->protocolExtensions.count >= IU_MSG_NUM_EXT_IES)
+			return -ERANGE;
+		field = &msg->protocolExtensions.tab[msg->protocolExtensions.count++];
+	} else {
+		if (msg->protocolIEs.count >= IU_MSG_NUM_IES)
+			return -ERANGE;
+		field = &msg->protocolIEs.tab[msg->protocolIEs.count++];
+	}
+
+	field->id = iei;
+	//field->criticality = FIXME;
+	field->value.type = type;
+	field->value.u.data = ie;
+
+	return 0;
+}
+
+
 
 static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu)
 {
@@ -24,16 +68,34 @@
 
 static int hnbgw_tx_ue_register_acc()
 {
+#if 0
+	HNBAP_PDU pdu;
+	HNBRegisterAccept hnb_reg_acc;
+
+	hnb_reg_acc.protocol_IEs
+
+	pdu.choice = HNBAP_PDU_successfulOutcome;
+	pdu.u.successfulOutcome.procedureCode = HNBAP_PC_HNBRegister;
+	pdu.u.successfulOutcome.criticality = ;
+	pdu.u.successfulOutcome.value.type = asn1_type_HNBRegisterAccept;
+	pdu.u.successfulOutcome.value.u.data = &hnb_reg_acc;
+#endif
 	/* FIXME */
 	/* Single required response IE: RNC-ID */
 }
 
+/* we type-cast to ProtocolIE_Container_1, as all the containers structs have
+ * the same definiition.  This is of course ugly, but I see no cleaner way.
+ * Similarly, from the IEI it is clear what the type should be, but in a
+ * statically typed language we can only return 'void *' and hope the caller
+ * doesn the right typecast. */
 #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;
 
+	/* iterate over the array of IEs in the IE container and look for the first
+	 * occurrence of the right IEI */
 	for (i = 0; i < cont->count; i++) {
 		ProtocolIE_Field_1 *field = &cont->tab[i];
 		if (field->id == id) {
@@ -73,6 +135,8 @@
 	//ctx->id.mcc FIXME
 	//ctx->id.mnc FIXME
 
+	DEBUGP(DMAIN, "HNB-REGISTER-REQ from %s\n", ctx->identity_info);
+
 	/* FIXME: Send HNBRegisterAccept */
 }
 
@@ -156,7 +220,22 @@
 
 int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg)
 {
-	/* FIXME: decode and handle to _hnbgw_hnbap_rx() */
+	HNBAP_PDU *pdu;
+	ASN1Error err;
+	int rc;
+
+	/* decode and handle to _hnbgw_hnbap_rx() */
+
+	rc = asn1_aper_decode(&pdu, asn1_type_HNBAP_PDU, msg->data, msgb_length(msg), &err);
+	if (rc < 0) {
+		LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode (bit=%d): %s\n", err.bit_pos, err.msg);
+		return rc;
+	}
+
+	rc = _hnbgw_hnbap_rx(hnb, pdu);
+	asn1_free_value(asn1_type_HNBAP_PDU, pdu);
+
+	return rc;
 }