From 0a65cc3e7bc2e5bd608ddd01d031beea4d33ad0e Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Tue, 18 Jul 2017 15:39:27 +0200 Subject: vlr: LU FSM: enable Retrieve_IMEISV_If_Required Change-Id: I121b95ad6d5ecb7603815eece2b43008de487a8a --- src/libvlr/vlr_access_req_fsm.c | 2 +- src/libvlr/vlr_lu_fsm.c | 90 +++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c index 15f84b7e3..67fba566f 100644 --- a/src/libvlr/vlr_access_req_fsm.c +++ b/src/libvlr/vlr_access_req_fsm.c @@ -286,7 +286,7 @@ static void _proc_arq_vlr_node2(struct osmo_fsm_inst *fi) if (vlr_set_ciph_mode(vsub->vlr, fi, par->msc_conn_ref, par->ciphering_required, - vsub->vlr->cfg.retrieve_imeisv)) { + vsub->vlr->cfg.retrieve_imeisv_ciphered)) { LOGPFSML(fi, LOGL_ERROR, "Failed to send Ciphering Mode Command\n"); proc_arq_fsm_done(fi, VLR_PR_ARQ_RES_SYSTEM_FAILURE); 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, -- cgit v1.2.3