blob: 27b40c201f88b9d87089d9b7b82d75571a411760 [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>
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +01007#include <osmocom/core/use_count.h>
Harald Welte123261e2022-05-15 11:43:35 +02008#include <osmocom/core/stat_item.h>
9#include <osmocom/core/rate_ctr.h>
Harald Welteb8b85a12016-06-17 00:06:42 +020010#include <osmocom/gsm/protocol/gsm_23_003.h>
11#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
12#include <osmocom/gsm/gsm23003.h>
Neels Hofmeyrcf309132017-12-14 03:57:31 +010013#include <osmocom/gsm/gsm0808.h>
Vadim Yanitskiy8a0e2582018-06-14 03:54:33 +070014#include <osmocom/gsm/gsup.h>
Stefan Sperlingafa030d2018-12-06 12:06:59 +010015#include <osmocom/gsm/ipa.h>
Neels Hofmeyr7b61ffe2018-11-30 02:46:53 +010016#include <osmocom/msc/msc_common.h>
Harald Welte1ea6baf2018-07-31 19:40:52 +020017#include <osmocom/gsupclient/gsup_client.h>
Alexander Couzenseff28ab2024-09-12 00:55:25 +020018#include <osmocom/vlr/vlr_sgs.h>
Harald Welteb8b85a12016-06-17 00:06:42 +020019
Maxa263bb22017-12-27 13:23:44 +010020#define LOGGSUPP(level, gsup, fmt, args...) \
21 LOGP(DVLR, level, "GSUP(%s) " fmt, (gsup)->imsi, ## args)
22
23#define LOGVSUBP(level, vsub, fmt, args...) \
24 LOGP(DVLR, level, "SUBSCR(%s) " fmt, vlr_subscr_name(vsub), ## args)
25
Harald Welte2483f1b2016-06-19 18:06:02 +020026struct log_target;
Neels Hofmeyr46d526a2020-05-29 03:27:50 +020027struct osmo_mobile_identity;
Harald Welte2483f1b2016-06-19 18:06:02 +020028
Stefan Sperlingdefc3c82018-05-15 14:48:04 +020029#define VLR_SUBSCRIBER_NO_EXPIRATION 0
30#define VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL 60 /* in seconds */
31
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +010032#define VSUB_USE_ATTACHED "attached"
33
Harald Welteb8b85a12016-06-17 00:06:42 +020034/* from 3s to 10s */
35#define GSM_29002_TIMER_S 10
36/* from 15s to 30s */
37#define GSM_29002_TIMER_M 30
38/* from 1min to 10min */
39#define GSM_29002_TIMER_ML (10*60)
40/* from 28h to 38h */
41#define GSM_29002_TIMER_L (32*60*60)
42
Harald Welteb8b85a12016-06-17 00:06:42 +020043/* VLR subscriber authentication state */
44enum vlr_subscr_auth_state {
Martin Hauke3f07dac2019-11-14 17:49:08 +010045 /* subscriber needs to be authenticated */
Harald Welteb8b85a12016-06-17 00:06:42 +020046 VLR_SUB_AS_NEEDS_AUTH,
47 /* waiting for AuthInfo from HLR/AUC */
48 VLR_SUB_AS_NEEDS_AUTH_WAIT_AI,
49 /* waiting for response from subscriber */
50 VLR_SUB_AS_WAIT_RESP,
51 /* successfully authenticated */
52 VLR_SUB_AS_AUTHENTICATED,
53 /* subscriber needs re-sync */
54 VLR_SUB_AS_NEEDS_RESYNC,
55 /* waiting for AuthInfo with ReSync */
56 VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC,
57 /* waiting for response from subscr, resync case */
58 VLR_SUB_AS_WAIT_RESP_RESYNC,
59 /* waiting for IMSI from subscriber */
60 VLR_SUB_AS_WAIT_ID_IMSI,
61 /* authentication has failed */
62 VLR_SUB_AS_AUTH_FAILED,
63};
64
65enum vlr_lu_event {
66 VLR_ULA_E_UPDATE_LA, /* Initial trigger (LU from MS) */
67 VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */
68 VLR_ULA_E_SEND_ID_NACK, /* Result of Send-ID from PVLR */
Neels Hofmeyr3189f392022-10-26 18:11:58 +020069 VLR_ULA_E_AUTH_SUCCESS, /* Successful result of auth procedure */
Neels Hofmeyr1cb18a22022-10-11 00:18:04 +020070 VLR_ULA_E_AUTH_NO_INFO, /* HLR returned SAI NACK, possibly continue without auth */
Neels Hofmeyr923b6642022-09-28 00:15:45 +020071 VLR_ULA_E_AUTH_FAILURE, /* Auth procedure failed */
Harald Welteb8b85a12016-06-17 00:06:42 +020072 VLR_ULA_E_CIPH_RES, /* Result of Ciphering Mode Command */
Martin Hauke3f07dac2019-11-14 17:49:08 +010073 VLR_ULA_E_ID_IMSI, /* IMSI received from MS */
Harald Welteb8b85a12016-06-17 00:06:42 +020074 VLR_ULA_E_ID_IMEI, /* IMEI received from MS */
75 VLR_ULA_E_ID_IMEISV, /* IMEISV received from MS */
Oliver Smith7d053092018-12-14 17:37:38 +010076 VLR_ULA_E_HLR_IMEI_ACK, /* Check_IMEI_VLR result from HLR */
77 VLR_ULA_E_HLR_IMEI_NACK,/* Check_IMEI_VLR result from HLR */
Harald Welteb8b85a12016-06-17 00:06:42 +020078 VLR_ULA_E_HLR_LU_RES, /* HLR UpdateLocation result */
79 VLR_ULA_E_UPD_HLR_COMPL,/* UpdatE_HLR_VLR result */
80 VLR_ULA_E_LU_COMPL_SUCCESS,/* Location_Update_Completion_VLR result */
81 VLR_ULA_E_LU_COMPL_FAILURE,/* Location_Update_Completion_VLR result */
82 VLR_ULA_E_NEW_TMSI_ACK, /* TMSI Reallocation Complete */
83};
84
85enum vlr_ciph_result_cause {
86 VLR_CIPH_REJECT, /* ? */
87 VLR_CIPH_COMPL,
88};
89
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +010090struct vlr_auth_tuple {
91 int use_count;
92 int key_seq;
93 struct osmo_auth_vector vec;
94};
95#define VLR_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */
96
97
Harald Welteb8b85a12016-06-17 00:06:42 +020098enum vlr_subscr_security_context {
99 VLR_SEC_CTX_NONE,
100 VLR_SEC_CTX_GSM,
101 VLR_SEC_CTX_UMTS,
102};
103
104enum vlr_lu_type {
105 VLR_LU_TYPE_PERIODIC,
106 VLR_LU_TYPE_IMSI_ATTACH,
107 VLR_LU_TYPE_REGULAR,
108};
109
110#define OSMO_LBUF_DECL(name, xlen) \
111 struct { \
112 uint8_t buf[xlen]; \
113 size_t len; \
114 } name
115
116struct sgsn_mm_ctx;
117struct vlr_instance;
118
Neels Hofmeyr7b61ffe2018-11-30 02:46:53 +0100119#define VLR_NAME_LENGTH 160
Neels Hofmeyr7b61ffe2018-11-30 02:46:53 +0100120
Harald Welteb8b85a12016-06-17 00:06:42 +0200121/* The VLR subscriber is the part of the GSM subscriber state in VLR (CS) or
122 * SGSN (PS), particularly while interacting with the HLR via GSUP */
123struct vlr_subscr {
124 struct llist_head list;
125 struct vlr_instance *vlr;
126
127 /* TODO either populate from HLR or drop this completely? */
128 long long unsigned int id;
129
130 /* Data from HLR */ /* 3GPP TS 23.008 */
131 /* Always use vlr_subscr_set_imsi() to write to imsi[] */
132 char imsi[GSM23003_IMSI_MAX_DIGITS+1]; /* 2.1.1.1 */
Vadim Yanitskiy8b0737f2019-05-25 19:27:17 +0700133 char msisdn[GSM23003_MSISDN_MAX_DIGITS+1]; /* 2.1.2 */
Neels Hofmeyr7b61ffe2018-11-30 02:46:53 +0100134 char name[VLR_NAME_LENGTH+1]; /* proprietary */
Harald Welteb8b85a12016-06-17 00:06:42 +0200135 OSMO_LBUF_DECL(hlr, 16); /* 2.4.7 */
Harald Welteb8b85a12016-06-17 00:06:42 +0200136 uint32_t age_indicator; /* 2.17.1 */
137
138 /* Authentication Data */
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100139 struct vlr_auth_tuple auth_tuples[5]; /* 2.3.1-2.3.4 */
140 struct vlr_auth_tuple *last_tuple;
Harald Welteb8b85a12016-06-17 00:06:42 +0200141 enum vlr_subscr_security_context sec_ctx;
142
143 /* Data local to VLR is below */
144 uint32_t tmsi; /* 2.1.4 */
145 /* Newly allocated TMSI that was not yet acked by MS */
146 uint32_t tmsi_new;
147
Harald Welteb8b85a12016-06-17 00:06:42 +0200148 struct osmo_cell_global_id cgi; /* 2.4.16 */
Harald Welteb8b85a12016-06-17 00:06:42 +0200149
150 char imeisv[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.2.3 */
Oliver Smithd1037052019-05-02 13:39:26 +0200151 char imei[GSM23003_IMEI_NUM_DIGITS_NO_CHK+1]; /* 2.1.9 */
Harald Welteb8b85a12016-06-17 00:06:42 +0200152 bool imsi_detached_flag; /* 2.7.1 */
153 bool conf_by_radio_contact_ind; /* 2.7.4.1 */
154 bool sub_dataconf_by_hlr_ind; /* 2.7.4.2 */
155 bool loc_conf_in_hlr_ind; /* 2.7.4.3 */
156 bool dormant_ind; /* 2.7.8 */
157 bool cancel_loc_rx; /* 2.7.8A */
158 bool ms_not_reachable_flag; /* 2.10.2 (MNRF) */
159 bool la_allowed;
160
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100161 struct osmo_use_count use_count;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100162 struct osmo_use_count_entry use_count_buf[8];
163 int32_t max_total_use_count;
Harald Welteb8b85a12016-06-17 00:06:42 +0200164
165 struct osmo_fsm_inst *lu_fsm;
166 struct osmo_fsm_inst *auth_fsm;
167 struct osmo_fsm_inst *proc_arq_fsm;
Harald Welte0df904d2018-12-03 11:00:04 +0100168 struct osmo_fsm_inst *sgs_fsm;
Harald Welteb8b85a12016-06-17 00:06:42 +0200169
170 bool lu_complete;
Stefan Sperlingdefc3c82018-05-15 14:48:04 +0200171 time_t expire_lu;
Harald Welteb8b85a12016-06-17 00:06:42 +0200172
173 void *msc_conn_ref;
174
175 /* PS (SGSN) specific parts */
176 struct {
177 struct llist_head pdp_list;
Harald Welteb8b85a12016-06-17 00:06:42 +0200178 } ps;
179 /* CS (NITB/CSCN) specific parts */
180 struct {
181 /* pending requests */
182 bool is_paging;
Neels Hofmeyr2ff5bcd2017-12-15 03:02:27 +0100183 struct osmo_timer_list paging_response_timer;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200184 /* list of struct subscr_request */
Harald Welteb8b85a12016-06-17 00:06:42 +0200185 struct llist_head requests;
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200186 uint8_t lac;
Neels Hofmeyr7814a832018-12-26 00:40:18 +0100187 enum osmo_rat_type attached_via_ran;
Harald Welteb8b85a12016-06-17 00:06:42 +0200188 } cs;
Harald Welte0df904d2018-12-03 11:00:04 +0100189 /* SGs (MME) specific parts */
190 struct {
191 struct vlr_sgs_cfg cfg;
192 char mme_name[SGS_MME_NAME_LEN + 1];
193 struct osmo_location_area_id lai;
194 vlr_sgs_lu_response_cb_t response_cb;
195 vlr_sgs_lu_paging_cb_t paging_cb;
196 vlr_sgs_lu_mminfo_cb_t mminfo_cb;
197 enum sgsap_service_ind paging_serv_ind;
198 struct osmo_timer_list Ts5;
Pau Espin Pedrol67106702021-04-27 18:20:15 +0200199 bool last_eutran_plmn_present;
200 struct osmo_plmn_id last_eutran_plmn;
Harald Welte0df904d2018-12-03 11:00:04 +0100201 } sgs;
Neels Hofmeyr986fe7e2018-09-13 03:05:52 +0200202
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100203 struct osmo_gsm48_classmark classmark;
Harald Welteb8b85a12016-06-17 00:06:42 +0200204};
205
Harald Welteb8b85a12016-06-17 00:06:42 +0200206enum vlr_ciph {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100207 VLR_CIPH_NONE = 0, /*< A5/0, no encryption */
208 VLR_CIPH_A5_1 = 1, /*< A5/1, encryption */
209 VLR_CIPH_A5_2 = 2, /*< A5/2, deprecated export-grade encryption */
210 VLR_CIPH_A5_3 = 3, /*< A5/3, 'new secure' encryption */
Harald Welteb8b85a12016-06-17 00:06:42 +0200211};
212
Neels Hofmeyrcf309132017-12-14 03:57:31 +0100213static inline uint8_t vlr_ciph_to_gsm0808_alg_id(enum vlr_ciph ciph)
214{
215 switch (ciph) {
Neels Hofmeyrcf309132017-12-14 03:57:31 +0100216 case VLR_CIPH_NONE:
217 return GSM0808_ALG_ID_A5_0;
218 case VLR_CIPH_A5_1:
219 return GSM0808_ALG_ID_A5_1;
220 case VLR_CIPH_A5_2:
221 return GSM0808_ALG_ID_A5_2;
222 case VLR_CIPH_A5_3:
223 return GSM0808_ALG_ID_A5_3;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100224 default:
225 return GSM0808_ALG_ID_A5_7;
Neels Hofmeyrcf309132017-12-14 03:57:31 +0100226 }
227}
228
Harald Welteb8b85a12016-06-17 00:06:42 +0200229struct vlr_ops {
230 /* encode + transmit an AUTH REQ towards the MS.
231 * \param[in] at auth tuple providing rand, key_seq and autn.
232 * \param[in] send_autn True to send AUTN, for r99 UMTS auth.
233 */
Neels Hofmeyr8b6e5362018-11-30 02:57:33 +0100234 int (*tx_auth_req)(void *msc_conn_ref, struct vlr_auth_tuple *at,
Harald Welteb8b85a12016-06-17 00:06:42 +0200235 bool send_autn);
236 /* encode + transmit an AUTH REJECT towards the MS */
237 int (*tx_auth_rej)(void *msc_conn_ref);
238
239 /* encode + transmit an IDENTITY REQUEST towards the MS */
240 int (*tx_id_req)(void *msc_conn_ref, uint8_t mi_type);
241
242 int (*tx_lu_acc)(void *msc_conn_ref, uint32_t send_tmsi);
Neels Hofmeyr15809592018-04-06 02:57:51 +0200243 int (*tx_lu_rej)(void *msc_conn_ref, enum gsm48_reject_value cause);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100244 int (*tx_cm_serv_acc)(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type);
245 int (*tx_cm_serv_rej)(void *msc_conn_ref, enum osmo_cm_service_type cm_service_type,
246 enum gsm48_reject_value cause);
Harald Welteb8b85a12016-06-17 00:06:42 +0200247
Harald Welte71c51df2017-12-23 18:51:48 +0100248 int (*set_ciph_mode)(void *msc_conn_ref, bool umts_aka, bool retrieve_imeisv);
Harald Welteb8b85a12016-06-17 00:06:42 +0200249
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200250 int (*tx_common_id)(void *msc_conn_ref);
251
Stefan Sperling3a741282018-03-13 21:11:49 +0100252 int (*tx_mm_info)(void *msc_conn_ref);
Neels Hofmeyr84da6b12016-05-20 21:59:55 +0200253
Harald Welteb8b85a12016-06-17 00:06:42 +0200254 /* notify MSC/SGSN that the subscriber data in VLR has been updated */
255 void (*subscr_update)(struct vlr_subscr *vsub);
256 /* notify MSC/SGSN that the given subscriber has been associated
257 * with this msc_conn_ref */
Neels Hofmeyr1035d902018-12-28 21:22:32 +0100258 int (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscr *vsub);
Neels Hofmeyr2fd69e12024-03-26 00:50:04 +0100259 /* notify MSC that the given subscriber is no longer valid */
260 void (*subscr_inval)(void *msc_conn_ref, struct vlr_subscr *vsub);
Harald Welteb8b85a12016-06-17 00:06:42 +0200261};
262
Harald Welteb8b85a12016-06-17 00:06:42 +0200263/* An instance of the VLR codebase */
264struct vlr_instance {
265 struct llist_head subscribers;
266 struct llist_head operations;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100267 struct gsup_client_mux *gcm;
Harald Welteb8b85a12016-06-17 00:06:42 +0200268 struct vlr_ops ops;
Stefan Sperlingdefc3c82018-05-15 14:48:04 +0200269 struct osmo_timer_list lu_expire_timer;
Harald Welteb8b85a12016-06-17 00:06:42 +0200270 struct {
Neels Hofmeyr54a706c2017-07-18 15:39:27 +0200271 bool retrieve_imeisv_early;
272 bool retrieve_imeisv_ciphered;
Harald Welteb8b85a12016-06-17 00:06:42 +0200273 bool assign_tmsi;
274 bool check_imei_rqd;
Neels Hofmeyr33f53412017-10-29 02:11:18 +0100275 int auth_tuple_max_reuse_count;
Harald Welteb8b85a12016-06-17 00:06:42 +0200276 bool auth_reuse_old_sets_on_error;
277 bool parq_retrieve_imsi;
278 bool is_ps;
Neels Hofmeyr9aac5c22020-05-27 00:04:26 +0200279 uint8_t nri_bitlen;
280 struct osmo_nri_ranges *nri_ranges;
Harald Welteb8b85a12016-06-17 00:06:42 +0200281 } cfg;
Harald Welte123261e2022-05-15 11:43:35 +0200282 struct osmo_stat_item_group *statg;
283 struct rate_ctr_group *ctrg;
Harald Welteb8b85a12016-06-17 00:06:42 +0200284 /* A free-form pointer for use by the caller */
285 void *user_ctx;
286};
287
288extern const struct value_string vlr_ciph_names[];
289static inline const char *vlr_ciph_name(enum vlr_ciph val)
290{
291 return get_value_string(vlr_ciph_names, val);
292}
293
294/* Location Updating request */
295struct osmo_fsm_inst *
296vlr_loc_update(struct osmo_fsm_inst *parent,
297 uint32_t parent_event_success,
298 uint32_t parent_event_failure,
299 void *parent_event_data,
300 struct vlr_instance *vlr, void *msc_conn_ref,
301 enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
302 const struct osmo_location_area_id *old_lai,
303 const struct osmo_location_area_id *new_lai,
304 bool authentication_required,
Neels Hofmeyrd99a6072022-10-10 23:34:48 +0200305 bool is_ciphering_to_be_attempted,
Neels Hofmeyr2ea72642022-10-10 23:35:47 +0200306 bool is_ciphering_required,
Sylvain Munautda9f37e2019-03-14 11:02:36 +0100307 uint8_t key_seq,
Harald Welteb8b85a12016-06-17 00:06:42 +0200308 bool is_r99, bool is_utran,
309 bool assign_tmsi);
310
Neels Hofmeyr15809592018-04-06 02:57:51 +0200311void vlr_loc_update_cancel(struct osmo_fsm_inst *fi,
312 enum osmo_fsm_term_cause fsm_cause,
313 uint8_t gsm48_cause);
Harald Welteb8b85a12016-06-17 00:06:42 +0200314
Neels Hofmeyrc036b792018-11-29 22:37:51 +0100315/* tell the VLR that the RAN connection is gone */
Harald Welteb8b85a12016-06-17 00:06:42 +0200316int vlr_subscr_disconnected(struct vlr_subscr *vsub);
Maxdcc193d2017-12-27 19:34:15 +0100317bool vlr_subscr_expire(struct vlr_subscr *vsub);
Neels Hofmeyr46d526a2020-05-29 03:27:50 +0200318int vlr_subscr_rx_id_resp(struct vlr_subscr *vsub, const struct osmo_mobile_identity *mi);
Harald Welteb8b85a12016-06-17 00:06:42 +0200319int vlr_subscr_rx_auth_resp(struct vlr_subscr *vsub, bool is_r99, bool is_utran,
320 const uint8_t *res, uint8_t res_len);
321int vlr_subscr_rx_auth_fail(struct vlr_subscr *vsub, const uint8_t *auts);
Max770fbd22018-01-24 12:48:33 +0100322int vlr_subscr_tx_auth_fail_rep(const struct vlr_subscr *vsub) __attribute__((warn_unused_result));
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100323void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, enum vlr_ciph_result_cause result);
Harald Welteb8b85a12016-06-17 00:06:42 +0200324int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub);
325int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub);
Harald Welteb8b85a12016-06-17 00:06:42 +0200326
327struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100328int vlr_start(struct vlr_instance *vlr, struct gsup_client_mux *gcm);
329int vlr_gsup_rx(struct gsup_client_mux *gcm, void *data, const struct osmo_gsup_message *gsup_msg);
Harald Welteb8b85a12016-06-17 00:06:42 +0200330
331/* internal use only */
332
Neels Hofmeyr1a5bcd52017-11-18 22:19:55 +0100333void sub_pres_vlr_fsm_start(struct osmo_fsm_inst **fsm,
334 struct osmo_fsm_inst *parent,
335 struct vlr_subscr *vsub,
336 uint32_t term_event);
Harald Welteb8b85a12016-06-17 00:06:42 +0200337struct osmo_fsm_inst *
338upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent,
339 struct vlr_subscr *vsub,
340 uint32_t parent_event);
341
342struct osmo_fsm_inst *
343lu_compl_vlr_proc_start(struct osmo_fsm_inst *parent,
344 struct vlr_subscr *vsub,
345 void *msc_conn_ref,
346 uint32_t parent_event_success,
347 uint32_t parent_event_failure);
348
349
Oliver Smith5598aae2019-01-08 11:47:21 +0100350const char *vlr_subscr_name(const struct vlr_subscr *vsub);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100351const char *vlr_subscr_short_name(const struct vlr_subscr *vsub, unsigned int maxlen);
Oliver Smith5598aae2019-01-08 11:47:21 +0100352const char *vlr_subscr_msisdn_or_name(const struct vlr_subscr *vsub);
Harald Welteb8b85a12016-06-17 00:06:42 +0200353
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100354#define vlr_subscr_find_by_imsi(vlr, imsi, USE) \
355 _vlr_subscr_find_by_imsi(vlr, imsi, USE, __FILE__, __LINE__)
356#define vlr_subscr_find_or_create_by_imsi(vlr, imsi, USE, created) \
357 _vlr_subscr_find_or_create_by_imsi(vlr, imsi, USE, created, \
Neels Hofmeyrc36e61e2018-08-20 12:41:36 +0200358 __FILE__, __LINE__)
Harald Welteb8b85a12016-06-17 00:06:42 +0200359
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100360#define vlr_subscr_find_by_tmsi(vlr, tmsi, USE) \
361 _vlr_subscr_find_by_tmsi(vlr, tmsi, USE, __FILE__, __LINE__)
362#define vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, USE, created) \
363 _vlr_subscr_find_or_create_by_tmsi(vlr, tmsi, USE, created, \
Neels Hofmeyrc36e61e2018-08-20 12:41:36 +0200364 __FILE__, __LINE__)
Harald Welteb8b85a12016-06-17 00:06:42 +0200365
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100366#define vlr_subscr_find_by_msisdn(vlr, msisdn, USE) \
367 _vlr_subscr_find_by_msisdn(vlr, msisdn, USE, __FILE__, __LINE__)
Harald Welteb8b85a12016-06-17 00:06:42 +0200368
Neels Hofmeyr5bdba0d2021-07-27 03:46:18 +0200369#define vlr_subscr_find_by_mi(vlr, mi, USE) \
370 _vlr_subscr_find_by_mi(vlr, mi, USE, __FILE__, __LINE__)
371
Harald Welteb8b85a12016-06-17 00:06:42 +0200372struct vlr_subscr *_vlr_subscr_find_by_imsi(struct vlr_instance *vlr,
373 const char *imsi,
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100374 const char *use,
Harald Welteb8b85a12016-06-17 00:06:42 +0200375 const char *file, int line);
376struct vlr_subscr *_vlr_subscr_find_or_create_by_imsi(struct vlr_instance *vlr,
377 const char *imsi,
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100378 const char *use,
Harald Welteb8b85a12016-06-17 00:06:42 +0200379 bool *created,
380 const char *file,
381 int line);
382
383struct vlr_subscr *_vlr_subscr_find_by_tmsi(struct vlr_instance *vlr,
384 uint32_t tmsi,
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100385 const char *use,
Harald Welteb8b85a12016-06-17 00:06:42 +0200386 const char *file, int line);
387struct vlr_subscr *_vlr_subscr_find_or_create_by_tmsi(struct vlr_instance *vlr,
388 uint32_t tmsi,
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100389 const char *use,
Harald Welteb8b85a12016-06-17 00:06:42 +0200390 bool *created,
391 const char *file,
392 int line);
393
394struct vlr_subscr *_vlr_subscr_find_by_msisdn(struct vlr_instance *vlr,
395 const char *msisdn,
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100396 const char *use,
Harald Welteb8b85a12016-06-17 00:06:42 +0200397 const char *file, int line);
398
Neels Hofmeyr5bdba0d2021-07-27 03:46:18 +0200399struct vlr_subscr *_vlr_subscr_find_by_mi(struct vlr_instance *vlr,
400 const struct osmo_mobile_identity *mi,
401 const char *use,
402 const char *file, int line);
403
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100404#define vlr_subscr_get(VSUB, USE) vlr_subscr_get_src(VSUB, USE, __FILE__, __LINE__)
405#define vlr_subscr_put(VSUB, USE) vlr_subscr_put_src(VSUB, USE, __FILE__, __LINE__)
Harald Welteb8b85a12016-06-17 00:06:42 +0200406
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100407#define vlr_subscr_get_src(VSUB, USE, SRCFILE, SRCLINE) \
Neels Hofmeyr08aae212019-04-23 15:09:04 +0200408 OSMO_ASSERT((VSUB) && _osmo_use_count_get_put(&(VSUB)->use_count, USE, 1, SRCFILE, SRCLINE) == 0)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100409#define vlr_subscr_put_src(VSUB, USE, SRCFILE, SRCLINE) \
Neels Hofmeyr08aae212019-04-23 15:09:04 +0200410 OSMO_ASSERT((VSUB) && _osmo_use_count_get_put(&(VSUB)->use_count, USE, -1, SRCFILE, SRCLINE) == 0)
Neels Hofmeyr7c5346c2019-02-19 02:36:35 +0100411
Harald Welteb8b85a12016-06-17 00:06:42 +0200412void vlr_subscr_free(struct vlr_subscr *vsub);
413int vlr_subscr_alloc_tmsi(struct vlr_subscr *vsub);
414
415void vlr_subscr_set_imsi(struct vlr_subscr *vsub, const char *imsi);
416void vlr_subscr_set_imei(struct vlr_subscr *vsub, const char *imei);
417void vlr_subscr_set_imeisv(struct vlr_subscr *vsub, const char *imeisv);
418void vlr_subscr_set_msisdn(struct vlr_subscr *vsub, const char *msisdn);
Pau Espin Pedrol67106702021-04-27 18:20:15 +0200419void vlr_subscr_set_last_used_eutran_plmn_id(struct vlr_subscr *vsub,
420 const struct osmo_plmn_id *last_eutran_plmn);
Harald Welteb8b85a12016-06-17 00:06:42 +0200421
422bool vlr_subscr_matches_imsi(struct vlr_subscr *vsub, const char *imsi);
423bool vlr_subscr_matches_tmsi(struct vlr_subscr *vsub, uint32_t tmsi);
424bool vlr_subscr_matches_msisdn(struct vlr_subscr *vsub, const char *msisdn);
425bool vlr_subscr_matches_imei(struct vlr_subscr *vsub, const char *imei);
426
427uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer);
428
429int vlr_subscr_changed(struct vlr_subscr *vsub);
Max770fbd22018-01-24 12:48:33 +0100430int vlr_subscr_purge(struct vlr_subscr *vsub) __attribute__((warn_unused_result));
Neels Hofmeyr15809592018-04-06 02:57:51 +0200431void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub,
432 enum osmo_fsm_term_cause fsm_cause,
Alexander Couzenseac1b932024-09-12 16:51:12 +0200433 enum gsm48_reject_value gsm48_cause);
Harald Welteb8b85a12016-06-17 00:06:42 +0200434
Stefan Sperlingdefc3c82018-05-15 14:48:04 +0200435void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub);
Harald Welteb8b85a12016-06-17 00:06:42 +0200436
Martin Hauke3f07dac2019-11-14 17:49:08 +0100437/* Process Access Request FSM */
Harald Welteb8b85a12016-06-17 00:06:42 +0200438
Harald Welteb8b85a12016-06-17 00:06:42 +0200439enum proc_arq_vlr_event {
440 PR_ARQ_E_START,
441 PR_ARQ_E_ID_IMSI,
442 PR_ARQ_E_AUTH_RES,
Neels Hofmeyr1cb18a22022-10-11 00:18:04 +0200443 PR_ARQ_E_AUTH_NO_INFO,
Neels Hofmeyr923b6642022-09-28 00:15:45 +0200444 PR_ARQ_E_AUTH_FAILURE,
Harald Welteb8b85a12016-06-17 00:06:42 +0200445 PR_ARQ_E_CIPH_RES,
446 PR_ARQ_E_UPD_LOC_RES,
447 PR_ARQ_E_TRACE_RES,
448 PR_ARQ_E_IMEI_RES,
449 PR_ARQ_E_PRES_RES,
450 PR_ARQ_E_TMSI_ACK,
451};
452
453enum vlr_parq_type {
454 VLR_PR_ARQ_T_INVALID = 0, /* to guard against unset vars */
455 VLR_PR_ARQ_T_CM_SERV_REQ,
456 VLR_PR_ARQ_T_PAGING_RESP,
Neels Hofmeyrae98b972021-07-27 03:46:49 +0200457 VLR_PR_ARQ_T_CM_RE_ESTABLISH_REQ,
Harald Welteb8b85a12016-06-17 00:06:42 +0200458 /* FIXME: differentiate between services of 24.008 10.5.3.3 */
459};
460
461/* Process Access Request (CM SERV REQ / PAGING RESP) */
462void
463vlr_proc_acc_req(struct osmo_fsm_inst *parent,
464 uint32_t parent_event_success,
465 uint32_t parent_event_failure,
466 void *parent_event_data,
467 struct vlr_instance *vlr, void *msc_conn_ref,
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100468 enum vlr_parq_type type, enum osmo_cm_service_type cm_service_type,
Neels Hofmeyr46d526a2020-05-29 03:27:50 +0200469 const struct osmo_mobile_identity *mi,
Harald Welteb8b85a12016-06-17 00:06:42 +0200470 const struct osmo_location_area_id *lai,
471 bool authentication_required,
Neels Hofmeyrd99a6072022-10-10 23:34:48 +0200472 bool is_ciphering_to_be_attempted,
Neels Hofmeyr2ea72642022-10-10 23:35:47 +0200473 bool is_ciphering_required,
Sylvain Munautda9f37e2019-03-14 11:02:36 +0100474 uint8_t key_seq,
Harald Welteb8b85a12016-06-17 00:06:42 +0200475 bool is_r99, bool is_utran);
476
Neels Hofmeyr15809592018-04-06 02:57:51 +0200477void vlr_parq_cancel(struct osmo_fsm_inst *fi,
478 enum osmo_fsm_term_cause fsm_cause,
479 enum gsm48_reject_value gsm48_cause);
Harald Welteb8b85a12016-06-17 00:06:42 +0200480
481void vlr_parq_fsm_init(void);
482
483int vlr_set_ciph_mode(struct vlr_instance *vlr,
484 struct osmo_fsm_inst *fi,
485 void *msc_conn_ref,
Neels Hofmeyr2ef2da52017-12-18 01:23:42 +0100486 bool umts_aka,
Harald Welteb8b85a12016-06-17 00:06:42 +0200487 bool retrieve_imeisv);
488
Neels Hofmeyre3d72d72017-12-18 02:06:44 +0100489bool vlr_use_umts_aka(struct osmo_auth_vector *vec, bool is_r99);
490
Harald Welteb8b85a12016-06-17 00:06:42 +0200491void log_set_filter_vlr_subscr(struct log_target *target,
492 struct vlr_subscr *vlr_subscr);
Alexander Couzens7312b152019-08-19 15:30:12 +0200493
Alexander Couzenseac1b932024-09-12 16:51:12 +0200494enum gsm48_reject_value vlr_gmm_cause_to_reject_cause(enum gsm48_gmm_cause gmm_cause);
495enum gsm48_reject_value vlr_gmm_cause_to_reject_cause_domain(enum gsm48_gmm_cause gmm_cause, bool is_cs);
496enum gsm48_reject_value vlr_reject_causes_cs(enum gsm48_reject_value reject_cause);
497enum gsm48_reject_value vlr_reject_causes_ps(enum gsm48_reject_value reject_cause);