Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 1 | #include <osmocom/core/msgb.h> |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 2 | #include <osmocom/core/utils.h> |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 3 | |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 4 | #include <unistd.h> |
| 5 | #include <string.h> |
| 6 | |
| 7 | #include "hnbap.h" |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 8 | #include "hnbgw.h" |
| 9 | #include "hnbap_const.h" |
| 10 | |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 11 | |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 12 | static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu) |
| 13 | { |
| 14 | /* FIXME */ |
| 15 | } |
| 16 | |
| 17 | static int hnbgw_tx_hnb_register_acc() |
| 18 | { |
| 19 | /* FIXME */ |
| 20 | /* Single required response IE: RNC-ID */ |
| 21 | } |
| 22 | |
| 23 | static int hnbgw_tx_ue_register_acc() |
| 24 | { |
| 25 | /* FIXME */ |
| 26 | /* Single required response IE: RNC-ID */ |
| 27 | } |
| 28 | |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 29 | #define FIND_IE(cont, id) find_ie((const struct ProtocolIE_Container_1 *)cont, id) |
| 30 | |
| 31 | static void *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 32 | { |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 33 | int i; |
| 34 | |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 35 | for (i = 0; i < cont->count; i++) { |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 36 | ProtocolIE_Field_1 *field = &cont->tab[i]; |
| 37 | if (field->id == id) { |
| 38 | OSMO_ASSERT(field->value.type); |
| 39 | /* FIXME: we shoudl check if it is the correct type, not just any type */ |
| 40 | return field->value.u.data; |
| 41 | } |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 42 | } |
| 43 | return NULL; |
| 44 | } |
| 45 | |
Harald Welte | a2e6a7a | 2015-08-29 21:47:39 +0200 | [diff] [blame] | 46 | static inline uint16_t asn1str_to_u16(ASN1String *as) |
| 47 | { |
| 48 | if (as->len < 2) |
| 49 | return 0; |
| 50 | else |
| 51 | return *(uint16_t *)as->buf; |
| 52 | } |
| 53 | |
| 54 | static inline uint8_t asn1str_to_u8(ASN1String *as) |
| 55 | { |
| 56 | if (as->len < 1) |
| 57 | return 0; |
| 58 | else |
| 59 | return *(uint8_t *)as->buf; |
| 60 | } |
| 61 | |
| 62 | static inline uint8_t asn1bitstr_to_u32(ASN1BitString *as) |
| 63 | { |
| 64 | if (as->len < 25) |
| 65 | return 0; |
| 66 | else |
| 67 | return *(uint32_t *)as->buf; |
| 68 | } |
| 69 | |
| 70 | static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, struct HNBRegisterRequest *req) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 71 | { |
| 72 | HNB_Identity *identity = |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 73 | FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Identity); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 74 | HNB_Location_Information *loc = |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 75 | FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Location_Information); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 76 | PLMNidentity *plmn_id = |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 77 | FIND_IE(&req->protocolIEs, HNBAP_IEI_PLMNidentity); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 78 | CellIdentity *cell_id = |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 79 | FIND_IE(&req->protocolIEs, HNBAP_IEI_CellIdentity); |
| 80 | LAC *lac = FIND_IE(&req->protocolIEs, HNBAP_IEI_LAC); |
| 81 | RAC *rac = FIND_IE(&req->protocolIEs, HNBAP_IEI_RAC); |
| 82 | SAC *sac = FIND_IE(&req->protocolIEs, HNBAP_IEI_SAC); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 83 | /* Optional: CSG-ID */ |
| 84 | |
| 85 | if(!identity || !loc || !plmn_id || !cell_id || !lac || !rac || !sac) |
| 86 | return -1; |
| 87 | |
Harald Welte | a2e6a7a | 2015-08-29 21:47:39 +0200 | [diff] [blame] | 88 | /* copy all identity parameters from the message to ctx */ |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 89 | strncpy(ctx->identity_info, (const char *) identity->hNB_Identity_Info.buf, |
| 90 | sizeof(ctx->identity_info)); |
Harald Welte | a2e6a7a | 2015-08-29 21:47:39 +0200 | [diff] [blame] | 91 | ctx->id.lac = asn1str_to_u16(lac); |
| 92 | ctx->id.sac = asn1str_to_u16(sac); |
| 93 | ctx->id.rac = asn1str_to_u8(rac); |
| 94 | ctx->id.cid = asn1bitstr_to_u32(cell_id); |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 95 | //ctx->id.mcc FIXME |
| 96 | //ctx->id.mnc FIXME |
Harald Welte | a2e6a7a | 2015-08-29 21:47:39 +0200 | [diff] [blame] | 97 | |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 98 | /* FIXME: Send HNBRegisterAccept */ |
| 99 | } |
| 100 | |
Harald Welte | a2e6a7a | 2015-08-29 21:47:39 +0200 | [diff] [blame] | 101 | static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, struct UERegisterRequest *req) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 102 | { |
| 103 | UE_Identity *id = |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 104 | FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Identity); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 105 | Registration_Cause *reg_cause = |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 106 | FIND_IE(&req->protocolIEs, HNBAP_IEI_RegistrationCause); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 107 | UE_Capabilities *ue_cap = |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 108 | FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Capabilities); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 109 | |
| 110 | if (!id || !reg_cause || !ue_cap) |
| 111 | return -1; |
| 112 | |
| 113 | /* FIXME: Send UERegisterAccept */ |
| 114 | } |
| 115 | |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 116 | static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, struct InitiatingMessage *imsg) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 117 | { |
| 118 | int rc; |
| 119 | |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 120 | switch (imsg->procedureCode) { |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 121 | case HNBAP_PC_HNBRegister: /* 8.2 */ |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 122 | if (imsg->value.type != asn1_type_HNBRegisterRequest) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 123 | return -1; |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 124 | rc = hnbgw_rx_hnb_register_req(hnb, imsg->value.u.data); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 125 | break; |
| 126 | case HNBAP_PC_HNBDe_Register: /* 8.3 */ |
| 127 | break; |
| 128 | case HNBAP_PC_UERegister: /* 8.4 */ |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 129 | if (imsg->value.type != asn1_type_UERegisterRequest) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 130 | return -1; |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 131 | rc = hnbgw_rx_ue_register_req(hnb, imsg->value.u.data); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 132 | break; |
| 133 | case HNBAP_PC_UEDe_Register: /* 8.5 */ |
| 134 | break; |
| 135 | case HNBAP_PC_ErrorIndication: /* 8.6 */ |
| 136 | case HNBAP_PC_TNLUpdate: /* 8.9 */ |
| 137 | case HNBAP_PC_HNBConfigTransfer: /* 8.10 */ |
| 138 | case HNBAP_PC_RelocationComplete: /* 8.11 */ |
| 139 | case HNBAP_PC_U_RNTIQuery: /* 8.12 */ |
| 140 | case HNBAP_PC_privateMessage: |
| 141 | break; |
| 142 | default: |
| 143 | break; |
| 144 | } |
| 145 | } |
| 146 | |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 147 | static int hnbgw_rx_successful_outcome_msg(struct hnb_context *hnb, struct SuccessfulOutcome *msg) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 148 | { |
| 149 | |
| 150 | } |
| 151 | |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 152 | static int hnbgw_rx_unsuccessful_outcome_msg(struct hnb_context *hnb, struct UnsuccessfulOutcome *msg) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 153 | { |
| 154 | |
| 155 | } |
| 156 | |
| 157 | |
Harald Welte | a2e6a7a | 2015-08-29 21:47:39 +0200 | [diff] [blame] | 158 | static int _hnbgw_hnbap_rx(struct hnb_context *hnb, struct HNBAP_PDU *pdu) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 159 | { |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 160 | int rc; |
| 161 | |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 162 | /* it's a bit odd that we can't dispatch on procedure code, but |
| 163 | * that's not possible */ |
| 164 | switch (pdu->choice) { |
| 165 | case HNBAP_PDU_initiatingMessage: |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 166 | rc = hnbgw_rx_initiating_msg(hnb, &pdu->u.initiatingMessage); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 167 | break; |
| 168 | case HNBAP_PDU_successfulOutcome: |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 169 | rc = hnbgw_rx_successful_outcome_msg(hnb, &pdu->u.successfulOutcome); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 170 | break; |
| 171 | case HNBAP_PDU_unsuccessfulOutcome: |
Harald Welte | b3dae30 | 2015-08-30 12:20:09 +0200 | [diff] [blame^] | 172 | rc = hnbgw_rx_unsuccessful_outcome_msg(hnb, &pdu->u.unsuccessfulOutcome); |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 173 | break; |
| 174 | default: |
| 175 | return -1; |
| 176 | } |
| 177 | } |
| 178 | |
Harald Welte | a2e6a7a | 2015-08-29 21:47:39 +0200 | [diff] [blame] | 179 | int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg) |
Harald Welte | ba43de4 | 2015-08-29 20:33:16 +0200 | [diff] [blame] | 180 | { |
| 181 | /* FIXME: decode and handle to _hnbgw_hnbap_rx() */ |
| 182 | } |
| 183 | |
| 184 | |
| 185 | int hnbgw_hnbap_init(void) |
| 186 | { |
| 187 | |
| 188 | } |