lynxis lazus has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-sgsn/+/39561?usp=email )
Change subject: libvlr: squash libvlr reworks ......................................................................
libvlr: squash libvlr reworks
* logging/debug.h: add own debug * add PVLR support * add vlr_ra_update() * internally use RAI instead of LAI
Change-Id: I7ef8e10e9553181913c66546c97a71b21fa9ef64 --- A include/osmocom/vlr/debug.h M include/osmocom/vlr/vlr.h M src/libvlr/vlr.c M src/libvlr/vlr_lu_fsm.c 4 files changed, 99 insertions(+), 29 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/61/39561/1
diff --git a/include/osmocom/vlr/debug.h b/include/osmocom/vlr/debug.h new file mode 100644 index 0000000..c1be654 --- /dev/null +++ b/include/osmocom/vlr/debug.h @@ -0,0 +1,20 @@ +#pragma once + +#include <osmocom/core/logging.h> +#include <osmocom/sgsn/debug.h> + +enum osmo_vlr_cat { + OSMO_VLR_LOGC_VLR, + OSMO_VLR_LOGC_SGS, + _OSMO_VLR_LOGC_MAX, +}; + +void osmo_vlr_set_log_cat(enum osmo_vlr_cat logc, int logc_num); + + +// FIXME: private following + +extern int g_vlr_log_cat[_OSMO_VLR_LOGC_MAX]; + +#define LOGVLR(lvl, fmt, args...) LOGP(g_vlr_log_cat[OSMO_VLR_LOGC_VLR], lvl, fmt, ## args) +#define LOGSGS(lvl, fmt, args...) LOGP(g_vlr_log_cat[OSMO_VLR_LOGC_SGS], lvl, fmt, ## args) diff --git a/include/osmocom/vlr/vlr.h b/include/osmocom/vlr/vlr.h index 03b76f3..7bb2ed3 100644 --- a/include/osmocom/vlr/vlr.h +++ b/include/osmocom/vlr/vlr.h @@ -244,6 +244,8 @@
int (*tx_mm_info)(void *msc_conn_ref);
+ int (*tx_pvlr_request)(void *msc_conn_ref, const struct osmo_routing_area_id *old_rai); + /* notify MSC/SGSN that the subscriber data in VLR has been updated */ void (*subscr_update)(struct vlr_subscr *vsub); /* notify MSC/SGSN that the given subscriber has been associated @@ -254,6 +256,9 @@ */ void (*subscr_inval)(void *msc_conn_ref, struct vlr_subscr *vsub, enum gsm48_reject_value cause, bool cancel_by_update); + + /* decide if the location/routing area id is within the VLR or not */ + bool (*location_served)(struct vlr_subscr *vsub, const struct osmo_routing_area_id *rai); };
/* An instance of the VLR codebase */ @@ -304,6 +309,22 @@ bool is_r99, bool is_utran, bool assign_tmsi);
+struct osmo_fsm_inst * +vlr_ra_update(struct osmo_fsm_inst *parent, + uint32_t parent_event_success, + uint32_t parent_event_failure, + void *parent_event_data, + struct vlr_instance *vlr, void *msc_conn_ref, + enum vlr_lu_type type, uint32_t tmsi, const char *imsi, + const struct osmo_routing_area_id *old_lai, + const struct osmo_routing_area_id *new_lai, + bool authentication_required, + bool is_ciphering_to_be_attempted, + bool is_ciphering_required, + uint8_t key_seq, + bool is_r99, bool is_utran, + bool assign_tmsi); + void vlr_loc_update_cancel(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause fsm_cause, uint8_t gsm48_cause); @@ -319,6 +340,9 @@ void vlr_subscr_rx_ciph_res(struct vlr_subscr *vsub, enum vlr_ciph_result_cause result); int vlr_subscr_rx_tmsi_reall_compl(struct vlr_subscr *vsub); int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub); +int vlr_subscr_rx_rau_complete(struct vlr_subscr *vsub); +void vlr_subscr_rx_pvlr_id_ack(struct vlr_subscr *vsub); +void vlr_subscr_rx_pvlr_id_nack(struct vlr_subscr *vsub);
struct vlr_instance *vlr_alloc(void *ctx, const struct vlr_ops *ops, bool is_ps); int vlr_start(struct vlr_instance *vlr, struct gsup_client_mux *gcm); diff --git a/src/libvlr/vlr.c b/src/libvlr/vlr.c index 2b56a8b..54d95de 100644 --- a/src/libvlr/vlr.c +++ b/src/libvlr/vlr.c @@ -574,6 +574,7 @@ const char *file, int line) { + /* FIXME: we need to add a type to the tmsi (local, foreign) so overlaps doesn't matter */ struct vlr_subscr *vsub; vsub = _vlr_subscr_find_by_tmsi(vlr, tmsi, use, file, line); if (vsub) { @@ -598,10 +599,13 @@ struct vlr_instance *vlr = exists->vlr; int i; int j; - LOGVSUBP(LOGL_NOTICE, vsub, - "There is an existing subscriber for IMSI %s used by %s, replacing with this VLR subscr, used by %s\n", - exists->imsi, osmo_use_count_to_str_c(OTC_SELECT, &exists->use_count), - osmo_use_count_to_str_c(OTC_SELECT, &vsub->use_count)); + void *tmp = talloc_zero_size(vsub, 4); + LOGVLR(LOGL_NOTICE, + "There is an existing subscriber for IMSI %s used by %s, replacing with new VLR subscr: %s used by %s\n", + exists->imsi, osmo_use_count_to_str_c(tmp, &exists->use_count), + vlr_subscr_name(vsub), + osmo_use_count_to_str_c(tmp, &vsub->use_count)); + talloc_free(tmp);
if (!vsub->msisdn[0]) OSMO_STRLCPY_ARRAY(vsub->msisdn, exists->msisdn); @@ -1533,6 +1537,23 @@ return rc; }
+void vlr_subscr_rx_pvlr_id_ack(struct vlr_subscr *vsub) +{ + if (!vsub->lu_fsm) + return; + + osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_SEND_ID_ACK, NULL); +} + +void vlr_subscr_rx_pvlr_id_nack(struct vlr_subscr *vsub) +{ + if (!vsub->lu_fsm) + return; + + osmo_fsm_inst_dispatch(vsub->lu_fsm, VLR_ULA_E_SEND_ID_NACK, NULL); +} + + /* Tear down any running FSMs due to MSC connection timeout. * Visit all vsub->*_fsm pointers and give them a queue to send a final reject * message before the entire connection is torn down. @@ -1561,6 +1582,7 @@ OSMO_ASSERT(ops->tx_common_id); OSMO_ASSERT(ops->subscr_update); OSMO_ASSERT(ops->subscr_assoc); + OSMO_ASSERT(ops->location_served);
INIT_LLIST_HEAD(&vlr->subscribers); INIT_LLIST_HEAD(&vlr->operations); diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c index 4bbbbbe..176246e 100644 --- a/src/libvlr/vlr_lu_fsm.c +++ b/src/libvlr/vlr_lu_fsm.c @@ -752,8 +752,6 @@ bool lu_by_tmsi; char imsi[16]; uint32_t tmsi; - struct osmo_location_area_id old_lai; - struct osmo_location_area_id new_lai; struct osmo_routing_area_id old_rai; struct osmo_routing_area_id new_rai; bool authentication_required; @@ -767,20 +765,12 @@ bool is_r99; bool is_utran; bool assign_tmsi; + bool hlr_update_req;
/*! count times timer T timed out */ int N; };
- -/* Determine if given location area is served by this VLR */ -static bool lai_in_this_vlr(struct vlr_instance *vlr, - const struct osmo_location_area_id *lai) -{ - /* TODO: VLR needs to keep a locally configured list of LAIs */ - return true; -} - /* Return true when authentication should be attempted. */ static bool try_auth(struct lu_fsm_priv *lfp) { @@ -882,7 +872,7 @@ return; }
- if (lfp->lu_type == VLR_LU_TYPE_IMSI_ATTACH) { + if (lfp->lu_type == VLR_LU_TYPE_IMSI_ATTACH || lfp->hlr_update_req) { /* Update_HLR_VLR */ osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_HLR_UPD, LU_TIMEOUT_LONG, 0); @@ -931,7 +921,7 @@
vsub->conf_by_radio_contact_ind = true; /* Update LAI */ - vsub->cgi.lai = lfp->new_lai; + vsub->cgi.lai = lfp->new_rai.lac; vsub->dormant_ind = false; vsub->cancel_loc_rx = false; if (hlr_update_needed(vsub)) { @@ -1084,7 +1074,7 @@ vsub->lu_fsm = fi; vsub->msc_conn_ref = lfp->msc_conn_ref; /* FIXME: send new LAC to HLR? */ - vsub->cgi.lai.lac = lfp->new_lai.lac; + vsub->cgi.lai = lfp->new_rai.lac; lfp->vsub = vsub; /* Tell MSC to associate this subscriber with the given * connection */ @@ -1152,17 +1142,11 @@
/* TODO: PUESBINE related handling */
- /* Is previous LAI in this VLR? */ - if (!lai_in_this_vlr(vlr, &lfp->old_lai)) { -#if 0 - /* FIXME: check previous VLR, (3) */ + /* Is previous LAI/RAI in this VLR? */ + if (!vlr->ops.location_served(lfp->vsub, &lfp->old_rai)) { osmo_fsm_inst_state_chg(fi, VLR_ULA_S_WAIT_PVLR, LU_TIMEOUT_LONG, 0); return; -#endif - LOGPFSML(fi, LOGL_NOTICE, "LAI change from %s," - " but checking previous VLR not implemented\n", - osmo_lai_name(&lfp->old_lai)); }
/* If this is a TMSI based LU, we may not have the IMSI. Make sure that @@ -1217,16 +1201,35 @@ } }
+static void lu_fsm_wait_pvlr_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi); + struct vlr_instance *vlr = lfp->vlr; + + lfp->hlr_update_req = true; + vlr->ops.tx_pvlr_request(lfp->msc_conn_ref, &lfp->old_rai); +} + /* Wait for response from Send_Identification to PVLR */ static void lu_fsm_wait_pvlr(struct osmo_fsm_inst *fi, uint32_t event, void *data) { + struct lu_fsm_priv *lfp = lu_fsm_fi_priv(fi); + switch (event) { case VLR_ULA_E_SEND_ID_ACK: vlr_loc_upd_node1_pre(fi); break; case VLR_ULA_E_SEND_ID_NACK: - vlr_loc_upd_want_imsi(fi); + if (vlr_is_cs(lfp->vlr)) { + vlr_loc_upd_want_imsi(fi); + break; + } + /* PS */ + if (lfp->lu_type == VLR_LU_TYPE_IMSI_ATTACH) + vlr_loc_upd_want_imsi(fi); + else + lu_fsm_failure(fi, GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE); break; default: OSMO_ASSERT(0); @@ -1484,6 +1487,7 @@ S(VLR_ULA_S_WAIT_HLR_CHECK_IMEI_EARLY) | S(VLR_ULA_S_DONE), .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_PVLR), + .onenter = lu_fsm_wait_pvlr_onenter, .action = lu_fsm_wait_pvlr, }, [VLR_ULA_S_WAIT_AUTH] = { @@ -1674,8 +1678,8 @@ lfp->msc_conn_ref = msc_conn_ref; lfp->tmsi = tmsi; lfp->lu_type = type; - lfp->old_lai = *old_lai; - lfp->new_lai = *new_lai; + lfp->old_rai.lac = *old_lai; + lfp->new_rai.lac = *new_lai; lfp->lu_by_tmsi = true; lfp->parent_event_success = parent_event_success; lfp->parent_event_failure = parent_event_failure;