From 27f9c4ab4b09258424eadf8e1a4a5a20a57c0869 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 30 Aug 2015 22:47:18 +0200 Subject: migration of code from ffasn1c to asn1c + asn1tostruct.py --- src/hnbgw_hnbap.c | 249 ++++++++++++++++++++++-------------------------------- 1 file changed, 101 insertions(+), 148 deletions(-) (limited to 'src/hnbgw_hnbap.c') 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; - - 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++]; - } + /* FIXME */ +} - field->id = iei; - //field->criticality = FIXME; - field->value.type = type; - field->value.u.data = ie; +static int hnbgw_tx_hnb_register_acc(struct hnb_context *ctx) +{ + HNBRegisterAccept_t accept_out; + struct msgb *msg; + int rc; - return 0; -} + /* 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; + } + /* generate a successfull outcome PDU */ + msg = hnbap_generate_successful_outcome(ProcedureCode_id_HNBRegister, + Criticality_reject, + &asn_DEF_HNBRegisterAccept, + &accept_out); -static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu) -{ - /* FIXME */ + return hnbgw_hnbap_tx(ctx, msg); } -static int hnbgw_tx_hnb_register_acc() -{ - /* FIXME */ - /* Single required response IE: RNC-ID */ -} -static int hnbgw_tx_ue_register_acc() +static int hnbgw_tx_ue_register_acc(struct ue_context *ue) { -#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 */ -} + UERegisterAccept_t accept_out; + UERegisterAcceptIEs_t accept; + struct msgb *msg; + int rc; -/* 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; - } + /* FIXME accept.uE_Identity; */ + asn1_u32_to_bitstring(&accept.context_ID, &ue->context_id); + + 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 */ - - if(!identity || !loc || !plmn_id || !cell_id || !lac || !rac || !sac) - return -1; + HNBRegisterRequestIEs_t ies; + int rc; + + 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); - - if (!id || !reg_cause || !ue_cap) - return -1; + UERegisterRequestIEs_t ies; + struct ue_context *ue; + int rc; - /* FIXME: Send UERegisterAccept */ + rc = hnbap_decode_ueregisterrequesties(&ies, in); + if (rc < 0) + return rc; + + 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 @@ static int _hnbgw_hnbap_rx(struct hnb_context *hnb, struct HNBAP_PDU *pdu) 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; } -- cgit v1.2.3