diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2017-07-18 15:39:27 +0200 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-08-07 16:52:25 +0200 |
commit | 54a706cf920d1b5dcfbd5a4697538d16ea18aa98 (patch) | |
tree | 18de28a899ae366158482a44dc061a768bb6d807 /src/libvlr/vlr_lu_fsm.c | |
parent | ef9126c4dc4f4dc679449586134ea5167a4e9ea0 (diff) |
vlr: LU FSM: enable Retrieve_IMEISV_If_Required
Change-Id: I121b95ad6d5ecb7603815eece2b43008de487a8a
Diffstat (limited to 'src/libvlr/vlr_lu_fsm.c')
-rw-r--r-- | src/libvlr/vlr_lu_fsm.c | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/src/libvlr/vlr_lu_fsm.c b/src/libvlr/vlr_lu_fsm.c index f9ccbdfcd..ae671c1dc 100644 --- a/src/libvlr/vlr_lu_fsm.c +++ b/src/libvlr/vlr_lu_fsm.c @@ -814,7 +814,7 @@ static void vlr_loc_upd_post_auth(struct osmo_fsm_inst *fi) if (vlr_set_ciph_mode(vsub->vlr, fi, lfp->msc_conn_ref, lfp->ciphering_required, - vsub->vlr->cfg.retrieve_imeisv)) { + vsub->vlr->cfg.retrieve_imeisv_ciphered)) { LOGPFSML(fi, LOGL_ERROR, "Failed to send Ciphering Mode Command\n"); vlr_lu_compl_fsm_failure(fi, GSM48_REJECT_NETWORK_FAILURE); @@ -896,28 +896,11 @@ static const char *lai_name(struct osmo_location_area_id *lai) return buf; } -/* 4.1.2.1: Subscriber (via MSC/SGSN) requests location update */ -static void _start_lu_main(struct osmo_fsm_inst *fi) +static int _lu_fsm_associate_vsub(struct osmo_fsm_inst *fi) { struct lu_fsm_priv *lfp = fi->priv; struct vlr_instance *vlr = lfp->vlr; struct vlr_subscr *vsub = NULL; - bool created; - - /* 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) */ - 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", - lai_name(&lfp->old_lai)); - } if (!lfp->imsi[0]) { /* TMSI was used */ @@ -929,51 +912,69 @@ static void _start_lu_main(struct osmo_fsm_inst *fi) * someone else's TMSI. * TODO: Otherwise we can ask for the IMSI and verify that it * matches the IMSI on record. */ - vsub = vlr_subscr_find_or_create_by_tmsi(vlr, lfp->tmsi, - &created); + vsub = vlr_subscr_find_or_create_by_tmsi(vlr, lfp->tmsi, NULL); if (!vsub) { - LOGPFSML(fi, LOGL_ERROR, - "VLR subscriber allocation failed\n"); + LOGPFSML(fi, LOGL_ERROR, "VLR subscriber allocation failed\n"); lu_fsm_failure(fi, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER); - return; + return -1; } vsub->sub_dataconf_by_hlr_ind = false; if (assoc_lfp_with_sub(fi, vsub)) { vlr_subscr_put(vsub); - return; /* error */ + return -1; /* error, fsm failure invoked in assoc_lfp_with_sub() */ } - - if (created) - vlr_loc_upd_want_imsi(fi); - else - vlr_loc_upd_node1(fi); - /* We cannot have MSC area change, as the VLR - * serves only one MSC */ vlr_subscr_put(vsub); } else { /* IMSI was used */ vsub = vlr_subscr_find_or_create_by_imsi(vlr, lfp->imsi, NULL); if (!vsub) { - LOGPFSML(fi, LOGL_ERROR, - "VLR subscriber allocation failed\n"); + LOGPFSML(fi, LOGL_ERROR, "VLR subscriber allocation failed\n"); lu_fsm_failure(fi, GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER); vlr_subscr_put(vsub); - return; + return -1; } vsub->sub_dataconf_by_hlr_ind = false; if (assoc_lfp_with_sub(fi, vsub)) { vlr_subscr_put(vsub); - return; /* error */ + return -1; /* error, fsm failure invoked in assoc_lfp_with_sub() */ } - vlr_loc_upd_node1(fi); vlr_subscr_put(vsub); } + return 0; } +/* 4.1.2.1: Subscriber (via MSC/SGSN) requests location update */ +static void _start_lu_main(struct osmo_fsm_inst *fi) +{ + struct lu_fsm_priv *lfp = fi->priv; + struct vlr_instance *vlr = lfp->vlr; + + /* 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) */ + 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", + lai_name(&lfp->old_lai)); + } + + /* If this is a TMSI based LU, we may not have the IMSI. Make sure that + * we know the IMSI, either on record, or request it. */ + if (!lfp->vsub->imsi[0]) + vlr_loc_upd_want_imsi(fi); + else + vlr_loc_upd_node1(fi); +} static void lu_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -983,8 +984,14 @@ static void lu_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, OSMO_ASSERT(event == VLR_ULA_E_UPDATE_LA); - if (1) { // FIXME - //if (lfp->type == VLR_LU_TYPE_PERIODIC && lfp->vsub->imeisv[0]) + if (_lu_fsm_associate_vsub(fi)) + return; /* error. FSM already terminated. */ + + OSMO_ASSERT(lfp->vsub); + + /* See 3GPP TS 23.012, procedure Retrieve_IMEISV_If_Required */ + if ((!vlr->cfg.retrieve_imeisv_early) + || (lfp->type == VLR_LU_TYPE_PERIODIC && lfp->vsub->imeisv[0])) { /* R_IMEISV_IR1 passed */ _start_lu_main(fi); } else { @@ -999,7 +1006,8 @@ static void lu_fsm_wait_imeisv(struct osmo_fsm_inst *fi, uint32_t event, { switch (event) { case VLR_ULA_E_ID_IMEISV: - /* FIXME: copy IMEISV */ + /* IMEISV was copied in vlr_subscr_rx_id_resp(), and that's + * where we received this event from. */ _start_lu_main(fi); break; default: @@ -1257,6 +1265,8 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = { .in_event_mask = S(VLR_ULA_E_ID_IMEISV), .out_state_mask = S(VLR_ULA_S_WAIT_PVLR) | S(VLR_ULA_S_WAIT_IMSI) | + S(VLR_ULA_S_WAIT_AUTH) | + S(VLR_ULA_S_WAIT_HLR_UPD) | S(VLR_ULA_S_DONE), .name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMEISV), .action = lu_fsm_wait_imeisv, |