diff options
author | Harald Welte <laforge@gnumonks.org> | 2016-06-17 00:06:42 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2016-06-19 19:32:27 +0200 |
commit | 7b1bbbea60b9b04ff20e67561c201fd08ed42ab6 (patch) | |
tree | a1828390407df0d09c7c74212d325f5f00cccda3 /openbsc/include/openbsc | |
parent | adc168dcef4b7819f9cac392a92c7cd041baf664 (diff) |
WIP: Introduce libvlr
Change-Id: I3f75de5f0cc2ff77f276fd39832dd3621309c4b9
Diffstat (limited to 'openbsc/include/openbsc')
-rw-r--r-- | openbsc/include/openbsc/Makefile.am | 2 | ||||
-rw-r--r-- | openbsc/include/openbsc/debug.h | 1 | ||||
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 15 | ||||
-rw-r--r-- | openbsc/include/openbsc/vlr.h | 240 |
4 files changed, 242 insertions, 16 deletions
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index ea5c93b5f..7b2a6ee63 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -18,7 +18,7 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \ gprs_gb_parse.h smpp.h meas_feed.h \ gprs_gsup_client.h bsc_msg_filter.h \ oap.h \ - gtphub.h + gtphub.h vlr.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h index 43ebb19a0..7972bc823 100644 --- a/openbsc/include/openbsc/debug.h +++ b/openbsc/include/openbsc/debug.h @@ -36,6 +36,7 @@ enum { DGTPHUB, DRANAP, DSUA, + DVLR, Debug_LastEntry, }; diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index 0ae818a4d..c64038e05 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -61,20 +61,6 @@ struct gsm_auth_tuple { #define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */ /* - * LOCATION UPDATING REQUEST state - * - * Our current operation is: - * - Get imei/tmsi - * - Accept/Reject according to global policy - */ -struct gsm_loc_updating_operation { - struct osmo_timer_list updating_timer; - unsigned int waiting_for_imsi : 1; - unsigned int waiting_for_imei : 1; - unsigned int key_seq : 4; -}; - -/* * AUTHENTICATION/CIPHERING state */ struct gsm_security_operation { @@ -125,7 +111,6 @@ struct gsm_subscriber_connection { /* * Operations that have a state and might be pending */ - struct gsm_loc_updating_operation *loc_operation; struct gsm_security_operation *sec_operation; struct gsm_anchor_operation *anch_operation; diff --git a/openbsc/include/openbsc/vlr.h b/openbsc/include/openbsc/vlr.h new file mode 100644 index 000000000..6112cc82f --- /dev/null +++ b/openbsc/include/openbsc/vlr.h @@ -0,0 +1,240 @@ +#pragma once + +#include <stdint.h> +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/fsm.h> +#include <osmocom/gsm/protocol/gsm_23_003.h> +#include <osmocom/gsm/gsm23003.h> +#include <openbsc/gsm_data.h> +// for GSM_NAME_LENGTH +#include <openbsc/gsm_subscriber.h> + +/* from 3s to 10s */ +#define GSM_29002_TIMER_S 10 +/* from 15s to 30s */ +#define GSM_29002_TIMER_M 30 +/* from 1min to 10min */ +#define GSM_29002_TIMER_ML (10*60) +/* from 28h to 38h */ +#define GSM_29002_TIMER_L (32*60*60) + + +/* VLR subscriber authentication state */ +enum vlr_sub_auth_state { + /* subscriber needs to be autenticated */ + VLR_SUB_AS_NEEDS_AUTH, + /* waiting for AuthInfo from HLR/AUC */ + VLR_SUB_AS_NEEDS_AUTH_WAIT_AI, + /* waiting for response from subscriber */ + VLR_SUB_AS_WAIT_RESP, + /* successfully authenticated */ + VLR_SUB_AS_AUTHENTICATED, + /* subscriber needs re-sync */ + VLR_SUB_AS_NEEDS_RESYNC, + /* waiting for AuthInfo with ReSync */ + VLR_SUB_AS_NEEDS_AUTH_WAIT_SAI_RESYNC, + /* waiting for response from subscr, resync case */ + VLR_SUB_AS_WAIT_RESP_RESYNC, + /* waiting for IMSI from subscriber */ + VLR_SUB_AS_WAIT_ID_IMSI, + /* authentication has failed */ + VLR_SUB_AS_AUTH_FAILED, +}; + +enum vlr_lu_event { + VLR_ULA_E_UPDATE_LA, /* Initial trigger (LU from MS) */ + VLR_ULA_E_SEND_ID_ACK, /* Result of Send-ID from PVLR */ + VLR_ULA_E_SEND_ID_NACK,/* Result of Send-ID from PVLR */ + VLR_ULA_E_AUTH_RES, /* Result of auth procedure */ + VLR_ULA_E_ID_IMSI, /* IMSI recieved from MS */ + VLR_ULA_E_ID_IMEI, /* IMEI received from MS */ + VLR_ULA_E_ID_IMEISV, /* IMEISV received from MS */ + VLR_ULA_E_HLR_LU_RES, /* HLR UpdateLocation result */ + VLR_ULA_E_UPD_HLR_COMPL,/* UpdatE_HLR_VLR result */ + VLR_ULA_E_LU_COMPL_TERM,/* Location_Update_Completion_VLR result */ + VLR_ULA_E_NEW_TMSI_ACK, /* TMSI Reallocation Complete */ +}; + +enum vlr_sub_security_context { + VLR_SEC_CTX_NONE, + VLR_SEC_CTX_GSM, + VLR_SEC_CTX_UMTS, +}; + +enum vlr_lu_type { + VLR_LU_TYPE_PERIODIC, + VLR_LU_TYPE_IMSI_ATTACH, + VLR_LU_TYPE_REGULAR, +}; + +#define OSMO_LBUF_DECL(name, xlen) \ + struct { \ + uint8_t buf[xlen]; \ + size_t len; \ + } name + +struct sgsn_mm_ctx; +struct vlr_instance; + +/* The VLR subscriber is the part of the GSM subscriber state in VLR (CS) or + * SGSN (PS), particularly while interacting with the HLR via GSUP */ +struct vlr_subscriber { + struct llist_head list; + struct vlr_instance *vlr; + + /* Data from HLR */ + char imsi[GSM23003_IMSI_MAX_DIGITS+1]; /* 2.1.1.1 */ + char msisdn[15+1]; /* 2.1.2 */ + OSMO_LBUF_DECL(hlr, 16); /* 2.4.7 */ + uint32_t periodic_lu_timer; /* 2.4.24 */ + uint32_t age_indicator; /* 2.17.1 */ + char name[GSM_NAME_LENGTH]; /* proprietary */ + + /* Authentication Data */ + struct gsm_auth_tuple auth_tuples[5]; /* 2.3.1-2.3.4 */ + struct gsm_auth_tuple *last_tuple; + enum vlr_sub_security_context sec_ctx; + + /* Data local to VLR is below */ + uint32_t tmsi; /* 2.1.4 */ + + /* some redundancy in information below? */ + struct osmo_cell_global_id cgi; /* 2.4.16 */ + uint16_t lac; /* 2.4.2 */ + + char imeisv[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.2.3 */ + char imei[GSM23003_IMEISV_NUM_DIGITS+1]; /* 2.1.9 */ + bool imsi_detached_flag; /* 2.7.1 */ + bool conf_by_radio_contact_ind; /* 2.7.4.1 */ + bool sub_dataconf_by_hlr_ind; /* 2.7.4.2 */ + bool loc_conf_in_hlr_ind; /* 2.7.4.3 */ + bool dormant_ind; /* 2.7.8 */ + bool cancel_loc_rx; /* 2.7.8A */ + bool ms_not_reachable_flag; /* 2.10.2 (MNRF) */ + bool la_allowed; + + uint32_t flags; + int auth_error_cause; + int auth_tuples_updated; + int authorized; + int use_count; + time_t expire_lu; /* FIXME: overlap with periodic_lu_timer/age_indicator */ + + struct osmo_fsm_inst *auth_fsm; + struct osmo_fsm_inst *lu_fsm; + struct omso_fsm_inst *proc_arq_fsm; + + void *msc_conn_ref; + + /* PS (SGSN) specific parts */ + struct { + struct llist_head pdp_list; + uint8_t rac; + uint8_t sac; + struct gprs_mm_ctx *mmctx; + } ps; + /* VLR specific parts */ + struct { + /* pending requests */ + int is_paging; + struct llist_head requests; + } cs; +}; + +struct vlr_ops { + /* encode + transmit an AUTH REQ towards the MS */ + int (*tx_auth_req)(void *msc_conn_ref, + struct gsm_auth_tuple *at); + /* encode + transmit an AUTH REJECT towards the MS */ + int (*tx_auth_rej)(void *msc_conn_ref); + + /* encode + transmit an IDENTITY REQUEST towards the MS */ + int (*tx_id_req)(void *msc_conn_ref, uint8_t mi_type); + int (*tx_lu_ack)(void *msc_conn_ref); + int (*tx_lu_rej)(void *msc_conn_ref, uint8_t cause); + + int (*set_ciph_mode)(void *msc_conn_ref); + + /* notify MSC/SGSN that the subscriber data in VLR has been updated */ + void (*subscr_update)(struct vlr_subscriber *vsub); + /* notify MSC/SGSN that the given subscriber has bene associated + * with this msc_conn_ref */ + void (*subscr_assoc)(void *msc_conn_ref, struct vlr_subscriber *vsub); +}; + +enum vlr_timer { + VLR_T_3250, + VLR_T_3260, + VLR_T_3270, + _NUM_VLR_TIMERS +}; + +/* An instance of the VLR codebase */ +struct vlr_instance { + struct llist_head subscribers; + struct llist_head operations; + struct gprs_gsup_client *gsup_client; + struct vlr_ops ops; + struct { + bool retrieve_imeisv; + bool alloc_tmsi; + bool check_imei_rqd; + bool auth_reuse_old_sets; + bool parq_retrieve_imsi; + bool is_ps; + uint32_t timer[_NUM_VLR_TIMERS]; + } cfg; +}; + +struct vlr_subscriber * +vlr_loc_update(struct vlr_instance *vlr, void *msc_conn_ref, + enum vlr_lu_type type, uint32_t tmsi, const char *imsi, + const struct osmo_location_area_id *old_lai, + const struct osmo_location_area_id *new_lai); + +/* Process_Access_Request (CM SERV REQ / PAGING RESP) */ +struct vlr_subscriber * +vlr_process_access_req(struct vlr_instance *vlr, void *msc_conn_ref, uint32_t tmsi, + const char *imsi, const struct osmo_location_area_id *lai); + +/* tell the VLR that the subscriber connection is gone */ +int vlr_sub_disconnected(struct vlr_subscriber *vsub); + +int vlr_sub_rx_id_resp(struct vlr_subscriber *vsub, const uint8_t *mi, size_t mi_len); +int vlr_sub_rx_auth_resp(struct vlr_subscriber *vsub, bool is_r99, bool is_utran, + const uint8_t *res, uint8_t res_len); +int vlr_sub_rx_auth_fail(struct vlr_subscriber *vsub, const uint8_t *auts); +int vlr_sub_tx_auth_fail_rep(struct vlr_subscriber *vsub); + +struct vlr_instance * +vlr_init(void *ctx, const struct vlr_ops *ops, const char *addr_str, uint16_t port); + + +/* internal use only */ + +struct osmo_fsm_inst *sub_pres_vlr_fsm_start(struct osmo_fsm_inst *parent, + struct vlr_subscriber *vsub, + uint32_t term_event); +struct osmo_fsm_inst * +upd_hlr_vlr_proc_start(struct osmo_fsm_inst *parent, + struct vlr_subscriber *vsub, + uint32_t parent_event); + +struct osmo_fsm_inst * +lu_compl_vlr_proc_start(struct osmo_fsm_inst *parent, + struct vlr_subscriber *vsub, + void *msc_conn_ref, + uint32_t term_event); + + +const char *vlr_sub_name(struct vlr_subscriber *vsub); +struct vlr_subscriber * +vlr_subscr_find_by_imsi(struct vlr_instance *vlr, const char *imsi); +struct vlr_subscriber * +vlr_subscr_find_by_tmsi(struct vlr_instance *vlr, uint32_t tmsi); +struct vlr_subscriber *vlr_sub_alloc(struct vlr_instance *vlr); +void vlr_sub_cleanup(struct vlr_subscriber *vsub); +void vlr_sub_cancel(struct vlr_subscriber *vsub); +int vlr_sub_alloc_tmsi(struct vlr_subscriber *vsub); + +uint32_t vlr_timer(struct vlr_instance *vlr, uint32_t timer); |