blob: 90e3d7a11a0782a7b6567be69ca1c534a51f18ce [file] [log] [blame]
Harald Welteb8b85a12016-06-17 00:06:42 +02001#pragma once
2
3#include <stdint.h>
4#include <osmocom/core/linuxlist.h>
5#include <osmocom/core/fsm.h>
6#include <osmocom/core/logging.h>
7#include <osmocom/gsm/protocol/gsm_23_003.h>
8#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
9#include <osmocom/gsm/gsm23003.h>
10#include <openbsc/gsm_data.h>
11// for GSM_NAME_LENGTH
12#include <openbsc/gsm_subscriber.h>
13
14/* from 3s to 10s */
15#define GSM_29002_TIMER_S 10
16/* from 15s to 30s */
17#define GSM_29002_TIMER_M 30
18/* from 1min to 10min */
19#define GSM_29002_TIMER_ML (10*60)
20/* from 28h to 38h */
21#define GSM_29002_TIMER_L (32*60*60)
22
23
24/* VLR subscriber authentication state */
25enum vlr_subscr_auth_state {
26 /* subscriber needs to be autenticated */
27 VLR_SUB_AS_NEEDS_AUTH,
28 /* waiting for AuthInfo from HLR/AUC */
29 VLR_SUB_AS_NEEDS_AUTH_WAIT_AI,
30 /* waiting for response from subscriber */
31 VLR_SUB_AS_WAIT_RESP,
32 /* successfully authenticated */
33 VLR_SUB_AS_AUTHENTICATED,
34 /* subscriber needs re-sync */
35 VLR_SUB_AS_NEEDS_RESYNC,
36 /* waiting for AuthInfo with ReSync */
37 VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC,
38 /* waiting for response from subscr, resync case */
39 VLR_SUB_AS_WAIT_RESP_RESYNC,
40 /* waiting for IMSI from subscriber */
41 VLR_SUB_AS_WAIT_ID_IMSI,
42 /* authentication has failed */
43 VLR_SUB_AS_AUTH_FAILED,
44};
45
46enum vlr_lu_event {
47 VLR_ULA_E_UPDATE_LA, /* Initial trigger (LU from MS) */
48 VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */
49 VLR_ULA_E_SEND_ID_NACK, /* Result of Send-ID from PVLR */
50 VLR_ULA_E_AUTH_RES, /* Result of auth procedure */
51 VLR_ULA_E_CIPH_RES, /* Result of Ciphering Mode Command */
52 VLR_ULA_E_ID_IMSI, /* IMSI recieved from MS */
53 VLR_ULA_E_ID_IMEI, /* IMEI received from MS */
54 VLR_ULA_E_ID_IMEISV, /* IMEISV received from MS */
55 VLR_ULA_E_HLR_LU_RES, /* HLR UpdateLocation result */
56 VLR_ULA_E_UPD_HLR_COMPL,/* UpdatE_HLR_VLR result */
57 VLR_ULA_E_LU_COMPL_SUCCESS,/* Location_Update_Completion_VLR result */
58 VLR_ULA_E_LU_COMPL_FAILURE,/* Location_Update_Completion_VLR result */
59 VLR_ULA_E_NEW_TMSI_ACK, /* TMSI Reallocation Complete */
60};
61
62enum vlr_ciph_result_cause {
63 VLR_CIPH_REJECT, /* ? */
64 VLR_CIPH_COMPL,
65};
66
67struct vlr_ciph_result {
68 enum vlr_ciph_result_cause cause;
69 const char *imeisv;
70};
71
72enum vlr_subscr_security_context {
73 VLR_SEC_CTX_NONE,
74 VLR_SEC_CTX_GSM,
75 VLR_SEC_CTX_UMTS,
76};
77
78enum vlr_lu_type {
79 VLR_LU_TYPE_PERIODIC,
80 VLR_LU_TYPE_IMSI_ATTACH,
81 VLR_LU_TYPE_REGULAR,
82};
83
84#define OSMO_LBUF_DECL(name, xlen) \
85 struct { \
86 uint8_t buf[xlen]; \
87 size_t len; \
88 } name
89
90struct sgsn_mm_ctx;
91struct vlr_instance;
92
93/* The VLR subscriber is the part of the GSM subscriber state in VLR (CS) or
94 * SGSN (PS), particularly while interacting with the HLR via GSUP */
95struct vlr_subscr {
96 struct llist_head list;
97 struct vlr_instance *vlr;
98
99 /* TODO either populate from HLR or drop this completely? */
100 long long unsigned int id;
101
102 /* Data from HLR */ /* 3GPP TS 23.008 */
103 /* Always use vlr_subscr_set_imsi() to write to imsi[] */
104 char imsi[GSM23003_IMSI_MAX_DIGITS+1]; /* 2.1.1.1 */
105 char msisdn[GSM_EXTENSION_LENGTH+1]; /* 2.1.2 */
106 char name[GSM_NAME_LENGTH+1]; /* proprietary */
107 OSMO_LBUF_DECL(hlr, 16); /* 2.4.7 */
108 uint32_t periodic_lu_timer; /* 2.4.24 */
109 uint32_t age_indicator; /* 2.17.1 */
110
111 /* Authentication Data */
112 struct gsm_auth_tuple auth_tuples[5]; /* 2.3.1-2.3.4 */
113 struct gsm_auth_tuple *last_tuple;
114 enum vlr_subscr_security_context sec_ctx;
115
116 /* Data local to VLR is below */
117 uint32_t tmsi; /* 2.1.4 */
118 /* Newly allocated TMSI that was not yet acked by MS */
119 uint32_t tmsi_new;
120
121 /* some redundancy in information below? */
122 struct osmo_cell_global_id cgi; /* 2.4.16 */
123 uint16_t lac; /* 2.4.2 */
124
125 char imeisv[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.2.3 */
126 char imei[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.1.9 */
127 bool imsi_detached_flag; /* 2.7.1 */
128 bool conf_by_radio_contact_ind; /* 2.7.4.1 */
129 bool sub_dataconf_by_hlr_ind; /* 2.7.4.2 */
130 bool loc_conf_in_hlr_ind; /* 2.7.4.3 */
131 bool dormant_ind; /* 2.7.8 */
132 bool cancel_loc_rx; /* 2.7.8A */
133 bool ms_not_reachable_flag; /* 2.10.2 (MNRF) */
134 bool la_allowed;
135
136 int use_count;
137 time_t expire_lu; /* FIXME: overlap with periodic_lu_timer/age_indicator */
138
139 struct osmo_fsm_inst *lu_fsm;
140 struct osmo_fsm_inst *auth_fsm;
141 struct osmo_fsm_inst *proc_arq_fsm;
142
143 bool lu_complete;
144
145 void *msc_conn_ref;
146
147 /* PS (SGSN) specific parts */
148 struct {
149 struct llist_head pdp_list;
150 uint8_t rac;
151 uint8_t sac;
152 struct gprs_mm_ctx *mmctx;
153 } ps;
154 /* CS (NITB/CSCN) specific parts */
155 struct {
156 /* pending requests */
157 bool is_paging;
158 struct llist_head requests;
159 } cs;
160};
161
162enum vlr_proc_arq_result;
163
164enum vlr_ciph {
165 VLR_CIPH_NONE, /*< A5/0, no encryption */
166 VLR_CIPH_A5_1, /*< A5/1, encryption */
167 VLR_CIPH_A5_2, /*< A5/2, deprecated export-grade encryption */
168 VLR_CIPH_A5_3, /*< A5/3, 'new secure' encryption */
169};
170
171struct vlr_ops {
172 /* encode + transmit an AUTH REQ towards the MS.
173 * \param[in] at auth tuple providing rand, key_seq and autn.
174 * \param[in] send_autn True to send AUTN, for r99 UMTS auth.
175 */
176 int (*tx_auth_req)(void *msc_conn_ref, struct gsm_auth_tuple *at,
177 bool send_autn);
178 /* encode + transmit an AUTH REJECT towards the MS */
179 int (*tx_auth_rej)(void *msc_conn_ref);
180
181 /* encode + transmit an IDENTITY REQUEST towards the MS */
182 int (*tx_id_req)(void *msc_conn_ref, uint8_t mi_type);
183
184 int (*tx_lu_acc)(void *msc_conn_ref, uint32_t send_tmsi);
185 int (*tx_lu_rej)(void *msc_conn_ref, uint8_t cause);
186 int (*tx_cm_serv_acc)(void *msc_conn_ref);
187 int (*tx_cm_serv_rej)(void *msc_conn_ref, enum vlr_proc_arq_result result);
188
189 int (*set_ciph_mode)(void *msc_conn_ref, enum vlr_ciph ciph_mode,
190 bool retrieve_imeisv);
191
192 /* notify MSC/SGSN that the subscriber data in VLR has been updated */
193 void (*subscr_update)(struct vlr_subscr *vsub);
194 /* notify MSC/SGSN that the given subscriber has been associated
195 * with this msc_conn_ref */
196 void (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscr *vsub);
197};
198
199enum vlr_timer {
200 VLR_T_3250,
201 VLR_T_3260,
202 VLR_T_3270,
203 _NUM_VLR_TIMERS
204};
205
206/* An instance of the VLR codebase */
207struct vlr_instance {
208 struct llist_head subscribers;
209 struct llist_head operations;
210 struct gsup_client *gsup_client;
211 struct vlr_ops ops;
212 struct {
213 bool retrieve_imeisv;
214 bool assign_tmsi;
215 bool check_imei_rqd;
216 int auth_tuple_max_use_count;
217 bool auth_reuse_old_sets_on_error;
218 bool parq_retrieve_imsi;
219 bool is_ps;
220 uint32_t timer[_NUM_VLR_TIMERS];
221 } cfg;
222 /* A free-form pointer for use by the caller */
223 void *user_ctx;
224};
225
226extern const struct value_string vlr_ciph_names[];
227static inline const char *vlr_ciph_name(enum vlr_ciph val)
228{
229 return get_value_string(vlr_ciph_names, val);
230}
231
232/* Location Updating request */
233struct osmo_fsm_inst *
234vlr_loc_update(struct osmo_fsm_inst *parent,
235 uint32_t parent_event_success,
236 uint32_t parent_event_failure,
237 void *parent_event_data,
238 struct vlr_instance *vlr, void *msc_conn_ref,
239 enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
240 const struct osmo_location_area_id *old_lai,
241 const struct osmo_location_area_id *new_lai,
242 bool authentication_required,
243 enum vlr_ciph ciphering_required,
244 bool is_r99, bool is_utran,
245 bool assign_tmsi);
246
247void vlr_loc_update_conn_timeout(struct osmo_fsm_inst *fi);
248
249/* tell the VLR that the subscriber connection is gone */
250int vlr_subscr_disconnected(struct vlr_subscr *vsub);
251
252int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const uint8_t *mi, size_t mi_len);
253int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, bool is_utran,
254 const uint8_t *res, uint8_t res_len);
255int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts);
256int vlr_subscr_tx_auth_fail_rep(struct vlr_subscr *vsub);
257void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, struct vlr_ciph_result *res);
258int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub);
259int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub);
260void vlr_subscr_conn_timeout(struct vlr_subscr *vsub);
261
262struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops);
263int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr,
264 const char *gsup_server_addr_str, uint16_t gsup_server_port);
265
266/* internal use only */
267
268struct osmo_fsm_inst *sub_pres_vlr_fsm_start(struct osmo_fsm_inst *parent,
269 struct vlr_subscr *vsub,
270 uint32_t term_event);
271struct osmo_fsm_inst *
272upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent,
273 struct vlr_subscr *vsub,
274 uint32_t parent_event);
275
276struct osmo_fsm_inst *
277lu_compl_vlr_proc_start(struct osmo_fsm_inst *parent,
278 struct vlr_subscr *vsub,
279 void *msc_conn_ref,
280 uint32_t parent_event_success,
281 uint32_t parent_event_failure);
282
283
284const char *vlr_subscr_name(struct vlr_subscr *vsub);
285const char *vlr_subscr_msisdn_or_name(struct vlr_subscr *vsub);
286
287#define vlr_subscr_find_by_imsi(vlr, imsi) \
288 _vlr_subscr_find_by_imsi(vlr, imsi, __BASE_FILE__, __LINE__)
289#define vlr_subscr_find_or_create_by_imsi(vlr, imsi, created) \
290 _vlr_subscr_find_or_create_by_imsi(vlr, imsi, created, \
291 __BASE_FILE__, __LINE__)
292
293#define vlr_subscr_find_by_tmsi(vlr, tmsi) \
294 _vlr_subscr_find_by_tmsi(vlr, tmsi, __BASE_FILE__, __LINE__)
295#define vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created) \
296 _vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, created, \
297 __BASE_FILE__, __LINE__)
298
299#define vlr_subscr_find_by_msisdn(vlr, msisdn) \
300 _vlr_subscr_find_by_msisdn(vlr, msisdn, __BASE_FILE__, __LINE__)
301
302struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
303 const char *imsi,
304 const char *file, int line);
305struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
306 const char *imsi,
307 bool *created,
308 const char *file,
309 int line);
310
311struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
312 uint32_t tmsi,
313 const char *file, int line);
314struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
315 uint32_t tmsi,
316 bool *created,
317 const char *file,
318 int line);
319
320struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
321 const char *msisdn,
322 const char *file, int line);
323
324#define vlr_subscr_get(sub) _vlr_subscr_get(sub, __BASE_FILE__, __LINE__)
325#define vlr_subscr_put(sub) _vlr_subscr_put(sub, __BASE_FILE__, __LINE__)
326struct vlr_subscr *_vlr_subscr_get(struct vlr_subscr *sub, const char *file, int line);
327struct vlr_subscr *_vlr_subscr_put(struct vlr_subscr *sub, const char *file, int line);
328
329struct vlr_subscr *vlr_subscr_alloc(struct vlr_instance *vlr);
330void vlr_subscr_free(struct vlr_subscr *vsub);
331int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub);
332
333void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi);
334void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei);
335void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv);
336void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn);
337
338bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi);
339bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi);
340bool vlr_subscr_matches_msisdn(struct vlr_subscr *vsub, const char *msisdn);
341bool vlr_subscr_matches_imei(struct vlr_subscr *vsub, const char *imei);
342
343uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer);
344
345int vlr_subscr_changed(struct vlr_subscr *vsub);
346int vlr_subscr_purge(struct vlr_subscr *vsub);
347void vlr_subscr_cancel(struct vlr_subscr *vsub, enum gsm48_gmm_cause cause);
348
349
350/* Process Acccess Request FSM */
351
352enum vlr_proc_arq_result {
353 VLR_PR_ARQ_RES_NONE,
354 VLR_PR_ARQ_RES_SYSTEM_FAILURE,
355 VLR_PR_ARQ_RES_ILLEGAL_SUBSCR,
356 VLR_PR_ARQ_RES_UNIDENT_SUBSCR,
357 VLR_PR_ARQ_RES_ROAMING_NOTALLOWED,
358 VLR_PR_ARQ_RES_ILLEGAL_EQUIP,
359 VLR_PR_ARQ_RES_UNKNOWN_ERROR,
360 VLR_PR_ARQ_RES_TIMEOUT,
361 VLR_PR_ARQ_RES_PASSED,
362};
363
364extern const struct value_string vlr_proc_arq_result_names[];
365static inline const char *vlr_proc_arq_result_name(enum vlr_proc_arq_result res)
366{
367 return get_value_string(vlr_proc_arq_result_names, res);
368}
369
370enum proc_arq_vlr_event {
371 PR_ARQ_E_START,
372 PR_ARQ_E_ID_IMSI,
373 PR_ARQ_E_AUTH_RES,
374 PR_ARQ_E_CIPH_RES,
375 PR_ARQ_E_UPD_LOC_RES,
376 PR_ARQ_E_TRACE_RES,
377 PR_ARQ_E_IMEI_RES,
378 PR_ARQ_E_PRES_RES,
379 PR_ARQ_E_TMSI_ACK,
380};
381
382enum vlr_parq_type {
383 VLR_PR_ARQ_T_INVALID = 0, /* to guard against unset vars */
384 VLR_PR_ARQ_T_CM_SERV_REQ,
385 VLR_PR_ARQ_T_PAGING_RESP,
386 /* FIXME: differentiate between services of 24.008 10.5.3.3 */
387};
388
389/* Process Access Request (CM SERV REQ / PAGING RESP) */
390void
391vlr_proc_acc_req(struct osmo_fsm_inst *parent,
392 uint32_t parent_event_success,
393 uint32_t parent_event_failure,
394 void *parent_event_data,
395 struct vlr_instance *vlr, void *msc_conn_ref,
396 enum vlr_parq_type type, const uint8_t *mi_lv,
397 const struct osmo_location_area_id *lai,
398 bool authentication_required,
399 enum vlr_ciph ciphering_required,
400 bool is_r99, bool is_utran);
401
402void vlr_parq_conn_timeout(struct osmo_fsm_inst *fi);
403
404void vlr_parq_fsm_init(void);
405
406int vlr_set_ciph_mode(struct vlr_instance *vlr,
407 struct osmo_fsm_inst *fi,
408 void *msc_conn_ref,
409 enum vlr_ciph ciph_mode,
410 bool retrieve_imeisv);
411
412void log_set_filter_vlr_subscr(struct log_target *target,
413 struct vlr_subscr *vlr_subscr);