aboutsummaryrefslogtreecommitdiffstats
path: root/src/hnbgw_hnbap.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2015-08-30 22:47:18 +0200
committerHarald Welte <laforge@gnumonks.org>2015-08-30 22:48:59 +0200
commit27f9c4ab4b09258424eadf8e1a4a5a20a57c0869 (patch)
treeee563720d4f22c4b99fc5952e102c7e007f3b32f /src/hnbgw_hnbap.c
parent547b76c5b4b3f0f3f1b5488e50e0ad2be00c730e (diff)
migration of code from ffasn1c to asn1c + asn1tostruct.py
Diffstat (limited to 'src/hnbgw_hnbap.c')
-rw-r--r--src/hnbgw_hnbap.c249
1 files changed, 101 insertions, 148 deletions
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;
}