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