#include #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 inline uint16_t asn1str_to_u16(ASN1String *as) { if (as->len < 2) return 0; else return *(uint16_t *)as->buf; } static inline uint8_t asn1str_to_u8(ASN1String *as) { if (as->len < 1) return 0; else return *(uint8_t *)as->buf; } static inline uint8_t asn1bitstr_to_u32(ASN1BitString *as) { if (as->len < 25) return 0; else return *(uint32_t *)as->buf; } static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, 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; /* copy all identity parameters from the message to ctx */ strncpy(ctx->identity_info, sizeof(ctx->identity_info, identity_info->buf); 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); ctx->id.mcc FIXME ctx->id.mnc FIXME /* FIXME: Send HNBRegisterAccept */ } static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, 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 hnb_context *hnb, 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(hnb, FIXME); 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(hnb, FIXME); 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 hnb_context *hnb, 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 hnb_context *hnb, struct msgb *msg) { /* FIXME: decode and handle to _hnbgw_hnbap_rx() */ } int hnbgw_hnbap_init(void) { }