aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2017-07-18 15:39:27 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2017-07-25 15:24:42 +0200
commit2ab3af5263e6d8bc33d37c50bb69c7a2dc5cd8c4 (patch)
treede1f6d3ca57c94741f3a4df86cae713f4da2ac55
parent8571981205364c439ec9922035c974f78cc32a6e (diff)
vlr: LU FSM: enable Retrieve_IMEISV_If_Required
-rw-r--r--include/openbsc/vlr.h3
-rw-r--r--src/libvlr/vlr_access_req_fsm.c2
-rw-r--r--src/libvlr/vlr_lu_fsm.c90
3 files changed, 53 insertions, 42 deletions
diff --git a/include/openbsc/vlr.h b/include/openbsc/vlr.h
index 90c55c736..619971a52 100644
--- a/include/openbsc/vlr.h
+++ b/include/openbsc/vlr.h
@@ -218,7 +218,8 @@ struct vlr_instance {
struct gsup_client *gsup_client;
struct vlr_ops ops;
struct {
- bool retrieve_imeisv;
+ bool retrieve_imeisv_early;
+ bool retrieve_imeisv_ciphered;
bool assign_tmsi;
bool check_imei_rqd;
int auth_tuple_max_use_count;
diff --git a/src/libvlr/vlr_access_req_fsm.c b/src/libvlr/vlr_access_req_fsm.c
index aea93b512..f9ed0b57d 100644
--- a/src/libvlr/vlr_access_req_fsm.c
+++ b/src/libvlr/vlr_access_req_fsm.c
@@ -294,7 +294,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 12b8bc8a2..94bea560f 100644
--- a/src/libvlr/vlr_lu_fsm.c
+++ b/src/libvlr/vlr_lu_fsm.c
@@ -822,7 +822,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);
@@ -904,28 +904,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 */
@@ -937,51 +920,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)
@@ -991,8 +992,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 {
@@ -1007,7 +1014,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:
@@ -1265,6 +1273,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,