migration of code from ffasn1c to asn1c + asn1tostruct.py
diff --git a/src/hnbgw_hnbap.c b/src/hnbgw_hnbap.c
index 9db670e..5100bf5 100644
--- a/src/hnbgw_hnbap.c
+++ b/src/hnbgw_hnbap.c
@@ -7,211 +7,164 @@
 
 #include "asn1helpers.h"
 
-#include "hnbap.h"
 #include "hnbgw.h"
-#include "hnbap_const.h"
+#include "hnbap_common.h"
+#include "hnbap_ies_defs.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)
+static int hnbgw_hnbap_tx(struct hnb_context *ctx, struct msgb *msg)
 {
-	struct iu_common_msg *msg = _msg;
-	ProtocolIE_Field_1 *field;
+	/* FIXME */
+}
 
-	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++];
+static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx)
+{
+	HNBRegisterAccept_t accept_out;
+	struct msgb *msg;
+	int rc;
+
+	/* Single required response IE: RNC-ID */
+	HNBRegisterAcceptIEs_t accept = {
+		.rnc_id = ctx->gw->config.rnc_id
+	};
+
+	/* encode the Information Elements */
+	rc = hnbap_encode_hnbregisteraccepties(&accept_out,  &accept);
+	if (rc < 0) {
+		return rc;
 	}
 
-	field->id = iei;
-	//field->criticality = FIXME;
-	field->value.type = type;
-	field->value.u.data = ie;
+	/* generate a successfull outcome PDU */
+	msg = hnbap_generate_successful_outcome(ProcedureCode_id_HNBRegister,
+					       Criticality_reject,
+					       &asn_DEF_HNBRegisterAccept,
+					       &accept_out);
 
-	return 0;
+	return hnbgw_hnbap_tx(ctx, msg);
 }
 
 
-
-static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu)
+static int hnbgw_tx_ue_register_acc(struct ue_context *ue)
 {
-	/* FIXME */
-}
+	UERegisterAccept_t accept_out;
+	UERegisterAcceptIEs_t accept;
+	struct msgb *msg;
+	int rc;
 
-static int hnbgw_tx_hnb_register_acc()
-{
-	/* FIXME */
-	/* Single required response IE: RNC-ID */
-}
+	/* FIXME accept.uE_Identity; */
+	asn1_u32_to_bitstring(&accept.context_ID, &ue->context_id);
 
-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) {
-			OSMO_ASSERT(field->value.type);
-			/* FIXME: we shoudl check if it is the correct type, not just any type */
-			return field->value.u.data;
-		}
+	rc = hnbap_encode_ueregisteraccepties(&accept_out, &accept);
+	if (rc < 0) {
+		return rc;
 	}
-	return NULL;
+
+	msg = hnbap_generate_successful_outcome(ProcedureCode_id_UERegister,
+						Criticality_reject,
+						&asn_DEF_UERegisterAccept,
+						&accept_out);
+	return hnbgw_hnbap_tx(ue->hnb, msg);
 }
 
-static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, struct HNBRegisterRequest *req)
+static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, ANY_t *in)
 {
-	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 */
+	HNBRegisterRequestIEs_t ies;
+	int rc;
 
-	if(!identity || !loc || !plmn_id || !cell_id || !lac || !rac || !sac)
-		return -1;
+	rc = hnbap_decode_hnbregisterrequesties(&ies, in);
+	if (rc < 0)
+		return rc;
 
 	/* copy all identity parameters from the message to ctx */
-	asn1_strncpy(ctx->identity_info, &identity->hNB_Identity_Info,
-		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);
+	asn1_strncpy(ctx->identity_info, &ies.hnB_Identity.hNB_Identity_Info,
+			sizeof(ctx->identity_info));
+	ctx->id.lac = asn1str_to_u16(&ies.lac);
+	ctx->id.sac = asn1str_to_u16(&ies.sac);
+	ctx->id.rac = asn1str_to_u8(&ies.rac);
+	ctx->id.cid = asn1bitstr_to_u32(&ies.cellIdentity);
 	//ctx->id.mcc FIXME
 	//ctx->id.mnc FIXME
 
 	DEBUGP(DMAIN, "HNB-REGISTER-REQ from %s\n", ctx->identity_info);
 
-	/* FIXME: Send HNBRegisterAccept */
+	/* Send HNBRegisterAccept */
+	return hnbgw_tx_hnb_register_acc(ctx);
 }
 
-static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, struct UERegisterRequest *req)
+static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, ANY_t *in)
 {
-	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);
+	UERegisterRequestIEs_t ies;
+	struct ue_context *ue;
+	int rc;
 
-	if (!id || !reg_cause || !ue_cap)
-		return -1;
+	rc = hnbap_decode_ueregisterrequesties(&ies, in);
+	if (rc < 0)
+		return rc;
 
-	/* FIXME: Send UERegisterAccept */
+	DEBUGP(DMAIN, "UE-REGSITER-REQ ID_type=%d cause=%ld\n",
+		ies.uE_Identity.present, ies.registration_Cause);
+
+	/* FIXME: convert UE identity into a more palatable format */
+
+	/* Send UERegisterAccept */
+	return hnbgw_tx_ue_register_acc(ue);
 }
 
-static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, struct InitiatingMessage *imsg)
+static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, InitiatingMessage_t *imsg)
 {
 	int rc;
 
 	switch (imsg->procedureCode) {
-	case HNBAP_PC_HNBRegister:	/* 8.2 */
-		if (imsg->value.type != asn1_type_HNBRegisterRequest)
-			return -1;
-		rc = hnbgw_rx_hnb_register_req(hnb, imsg->value.u.data);
+	case ProcedureCode_id_HNBRegister:	/* 8.2 */
+		rc = hnbgw_rx_hnb_register_req(hnb, &imsg->value);
 		break;
-	case HNBAP_PC_HNBDe_Register:	/* 8.3 */
+	case ProcedureCode_id_HNBDe_Register:	/* 8.3 */
 		break;
-	case HNBAP_PC_UERegister: 	/* 8.4 */
-		if (imsg->value.type != asn1_type_UERegisterRequest)
-			return -1;
-		rc = hnbgw_rx_ue_register_req(hnb, imsg->value.u.data);
+	case ProcedureCode_id_UERegister: 	/* 8.4 */
+		rc = hnbgw_rx_ue_register_req(hnb, &imsg->value);
 		break;
-	case HNBAP_PC_UEDe_Register:	/* 8.5 */
+	case ProcedureCode_id_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:
+	case ProcedureCode_id_ErrorIndication:	/* 8.6 */
+	case ProcedureCode_id_TNLUpdate:	/* 8.9 */
+	case ProcedureCode_id_HNBConfigTransfer:	/* 8.10 */
+	case ProcedureCode_id_RelocationComplete:	/* 8.11 */
+	case ProcedureCode_id_U_RNTIQuery:	/* 8.12 */
+	case ProcedureCode_id_privateMessage:
 		break;
 	default:
 		break;
 	}
 }
 
-static int hnbgw_rx_successful_outcome_msg(struct hnb_context *hnb, struct SuccessfulOutcome *msg)
+static int hnbgw_rx_successful_outcome_msg(struct hnb_context *hnb, SuccessfulOutcome_t *msg)
 {
 
 }
 
-static int hnbgw_rx_unsuccessful_outcome_msg(struct hnb_context *hnb, struct UnsuccessfulOutcome *msg)
+static int hnbgw_rx_unsuccessful_outcome_msg(struct hnb_context *hnb, UnsuccessfulOutcome_t *msg)
 {
 
 }
 
 
-static int _hnbgw_hnbap_rx(struct hnb_context *hnb, struct HNBAP_PDU *pdu)
+static int _hnbgw_hnbap_rx(struct hnb_context *hnb, HNBAP_PDU_t *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(hnb, &pdu->u.initiatingMessage);
+	switch (pdu->present) {
+	case HNBAP_PDU_PR_initiatingMessage:
+		rc = hnbgw_rx_initiating_msg(hnb, &pdu->choice.initiatingMessage);
 		break;
-	case HNBAP_PDU_successfulOutcome:
-		rc = hnbgw_rx_successful_outcome_msg(hnb, &pdu->u.successfulOutcome);
+	case HNBAP_PDU_PR_successfulOutcome:
+		rc = hnbgw_rx_successful_outcome_msg(hnb, &pdu->choice.successfulOutcome);
 		break;
-	case HNBAP_PDU_unsuccessfulOutcome:
-		rc = hnbgw_rx_unsuccessful_outcome_msg(hnb, &pdu->u.unsuccessfulOutcome);
+	case HNBAP_PDU_PR_unsuccessfulOutcome:
+		rc = hnbgw_rx_unsuccessful_outcome_msg(hnb, &pdu->choice.unsuccessfulOutcome);
 		break;
 	default:
 		return -1;
@@ -220,20 +173,20 @@
 
 int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg)
 {
-	HNBAP_PDU *pdu;
-	ASN1Error err;
+	HNBAP_PDU_t _pdu, *pdu = &_pdu;
+	asn_dec_rval_t dec_ret;
 	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);
+	dec_ret = aper_decode(NULL, &asn_DEF_HNBAP_PDU, (void **) &pdu,
+			      msg->data, msgb_length(msg), 0, 0);
+	if (dec_ret.code != RC_OK) {
+		LOGP(DMAIN, LOGL_ERROR, "Error in ASN.1 decode\n");
 		return rc;
 	}
 
 	rc = _hnbgw_hnbap_rx(hnb, pdu);
-	asn1_free_value(asn1_type_HNBAP_PDU, pdu);
 
 	return rc;
 }