blob: fd3a32877949537a976e79e02fd6f39e7eeb5025 [file] [log] [blame]
Harald Welteba43de42015-08-29 20:33:16 +02001#include <osmocom/core/msgb.h>
Harald Welteb3dae302015-08-30 12:20:09 +02002#include <osmocom/core/utils.h>
Harald Welteba43de42015-08-29 20:33:16 +02003
Harald Welteb3dae302015-08-30 12:20:09 +02004#include <unistd.h>
5#include <string.h>
6
7#include "hnbap.h"
Harald Welteba43de42015-08-29 20:33:16 +02008#include "hnbgw.h"
9#include "hnbap_const.h"
10
Harald Welteb3dae302015-08-30 12:20:09 +020011
Harald Welteba43de42015-08-29 20:33:16 +020012static int hnbgw_hnbap_tx(struct HNBAP_PDU *pdu)
13{
14 /* FIXME */
15}
16
17static int hnbgw_tx_hnb_register_acc()
18{
19 /* FIXME */
20 /* Single required response IE: RNC-ID */
21}
22
23static int hnbgw_tx_ue_register_acc()
24{
25 /* FIXME */
26 /* Single required response IE: RNC-ID */
27}
28
Harald Welteb3dae302015-08-30 12:20:09 +020029#define FIND_IE(cont, id) find_ie((const struct ProtocolIE_Container_1 *)cont, id)
30
31static void *find_ie(const struct ProtocolIE_Container_1 *cont, ProtocolIE_ID id)
Harald Welteba43de42015-08-29 20:33:16 +020032{
Harald Welteb3dae302015-08-30 12:20:09 +020033 int i;
34
Harald Welteba43de42015-08-29 20:33:16 +020035 for (i = 0; i < cont->count; i++) {
Harald Welteb3dae302015-08-30 12:20:09 +020036 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 Welteba43de42015-08-29 20:33:16 +020042 }
43 return NULL;
44}
45
Harald Weltea2e6a7a2015-08-29 21:47:39 +020046static 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
54static 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
62static 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
70static int hnbgw_rx_hnb_register_req(struct hnb_context *ctx, struct HNBRegisterRequest *req)
Harald Welteba43de42015-08-29 20:33:16 +020071{
72 HNB_Identity *identity =
Harald Welteb3dae302015-08-30 12:20:09 +020073 FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Identity);
Harald Welteba43de42015-08-29 20:33:16 +020074 HNB_Location_Information *loc =
Harald Welteb3dae302015-08-30 12:20:09 +020075 FIND_IE(&req->protocolIEs, HNBAP_IEI_HNB_Location_Information);
Harald Welteba43de42015-08-29 20:33:16 +020076 PLMNidentity *plmn_id =
Harald Welteb3dae302015-08-30 12:20:09 +020077 FIND_IE(&req->protocolIEs, HNBAP_IEI_PLMNidentity);
Harald Welteba43de42015-08-29 20:33:16 +020078 CellIdentity *cell_id =
Harald Welteb3dae302015-08-30 12:20:09 +020079 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 Welteba43de42015-08-29 20:33:16 +020083 /* Optional: CSG-ID */
84
85 if(!identity || !loc || !plmn_id || !cell_id || !lac || !rac || !sac)
86 return -1;
87
Harald Weltea2e6a7a2015-08-29 21:47:39 +020088 /* copy all identity parameters from the message to ctx */
Harald Welteb3dae302015-08-30 12:20:09 +020089 strncpy(ctx->identity_info, (const char *) identity->hNB_Identity_Info.buf,
90 sizeof(ctx->identity_info));
Harald Weltea2e6a7a2015-08-29 21:47:39 +020091 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 Welteb3dae302015-08-30 12:20:09 +020095 //ctx->id.mcc FIXME
96 //ctx->id.mnc FIXME
Harald Weltea2e6a7a2015-08-29 21:47:39 +020097
Harald Welteba43de42015-08-29 20:33:16 +020098 /* FIXME: Send HNBRegisterAccept */
99}
100
Harald Weltea2e6a7a2015-08-29 21:47:39 +0200101static int hnbgw_rx_ue_register_req(struct hnb_context *ctx, struct UERegisterRequest *req)
Harald Welteba43de42015-08-29 20:33:16 +0200102{
103 UE_Identity *id =
Harald Welteb3dae302015-08-30 12:20:09 +0200104 FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Identity);
Harald Welteba43de42015-08-29 20:33:16 +0200105 Registration_Cause *reg_cause =
Harald Welteb3dae302015-08-30 12:20:09 +0200106 FIND_IE(&req->protocolIEs, HNBAP_IEI_RegistrationCause);
Harald Welteba43de42015-08-29 20:33:16 +0200107 UE_Capabilities *ue_cap =
Harald Welteb3dae302015-08-30 12:20:09 +0200108 FIND_IE(&req->protocolIEs, HNBAP_IEI_UE_Capabilities);
Harald Welteba43de42015-08-29 20:33:16 +0200109
110 if (!id || !reg_cause || !ue_cap)
111 return -1;
112
113 /* FIXME: Send UERegisterAccept */
114}
115
Harald Welteb3dae302015-08-30 12:20:09 +0200116static int hnbgw_rx_initiating_msg(struct hnb_context *hnb, struct InitiatingMessage *imsg)
Harald Welteba43de42015-08-29 20:33:16 +0200117{
118 int rc;
119
Harald Welteb3dae302015-08-30 12:20:09 +0200120 switch (imsg->procedureCode) {
Harald Welteba43de42015-08-29 20:33:16 +0200121 case HNBAP_PC_HNBRegister: /* 8.2 */
Harald Welteb3dae302015-08-30 12:20:09 +0200122 if (imsg->value.type != asn1_type_HNBRegisterRequest)
Harald Welteba43de42015-08-29 20:33:16 +0200123 return -1;
Harald Welteb3dae302015-08-30 12:20:09 +0200124 rc = hnbgw_rx_hnb_register_req(hnb, imsg->value.u.data);
Harald Welteba43de42015-08-29 20:33:16 +0200125 break;
126 case HNBAP_PC_HNBDe_Register: /* 8.3 */
127 break;
128 case HNBAP_PC_UERegister: /* 8.4 */
Harald Welteb3dae302015-08-30 12:20:09 +0200129 if (imsg->value.type != asn1_type_UERegisterRequest)
Harald Welteba43de42015-08-29 20:33:16 +0200130 return -1;
Harald Welteb3dae302015-08-30 12:20:09 +0200131 rc = hnbgw_rx_ue_register_req(hnb, imsg->value.u.data);
Harald Welteba43de42015-08-29 20:33:16 +0200132 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 Welteb3dae302015-08-30 12:20:09 +0200147static int hnbgw_rx_successful_outcome_msg(struct hnb_context *hnb, struct SuccessfulOutcome *msg)
Harald Welteba43de42015-08-29 20:33:16 +0200148{
149
150}
151
Harald Welteb3dae302015-08-30 12:20:09 +0200152static int hnbgw_rx_unsuccessful_outcome_msg(struct hnb_context *hnb, struct UnsuccessfulOutcome *msg)
Harald Welteba43de42015-08-29 20:33:16 +0200153{
154
155}
156
157
Harald Weltea2e6a7a2015-08-29 21:47:39 +0200158static int _hnbgw_hnbap_rx(struct hnb_context *hnb, struct HNBAP_PDU *pdu)
Harald Welteba43de42015-08-29 20:33:16 +0200159{
Harald Welteb3dae302015-08-30 12:20:09 +0200160 int rc;
161
Harald Welteba43de42015-08-29 20:33:16 +0200162 /* 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 Welteb3dae302015-08-30 12:20:09 +0200166 rc = hnbgw_rx_initiating_msg(hnb, &pdu->u.initiatingMessage);
Harald Welteba43de42015-08-29 20:33:16 +0200167 break;
168 case HNBAP_PDU_successfulOutcome:
Harald Welteb3dae302015-08-30 12:20:09 +0200169 rc = hnbgw_rx_successful_outcome_msg(hnb, &pdu->u.successfulOutcome);
Harald Welteba43de42015-08-29 20:33:16 +0200170 break;
171 case HNBAP_PDU_unsuccessfulOutcome:
Harald Welteb3dae302015-08-30 12:20:09 +0200172 rc = hnbgw_rx_unsuccessful_outcome_msg(hnb, &pdu->u.unsuccessfulOutcome);
Harald Welteba43de42015-08-29 20:33:16 +0200173 break;
174 default:
175 return -1;
176 }
177}
178
Harald Weltea2e6a7a2015-08-29 21:47:39 +0200179int hnbgw_hnbap_rx(struct hnb_context *hnb, struct msgb *msg)
Harald Welteba43de42015-08-29 20:33:16 +0200180{
181 /* FIXME: decode and handle to _hnbgw_hnbap_rx() */
182}
183
184
185int hnbgw_hnbap_init(void)
186{
187
188}