aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-11-14 14:48:00 +0100
committerHarald Welte <laforge@gnumonks.org>2016-11-14 14:48:00 +0100
commit5d90dcd28f64f6cf4970fb59a898c620b78a38ee (patch)
treecda4dca39b28d1cfefc1caa46a0c426d0889a802
parent7b1bbbea60b9b04ff20e67561c201fd08ed42ab6 (diff)
WIP: more incomplete libvlr integration work
-rw-r--r--openbsc/include/openbsc/gsm_data.h2
-rw-r--r--openbsc/include/openbsc/osmo_msc.h22
-rw-r--r--openbsc/include/openbsc/vlr.h55
-rw-r--r--openbsc/src/libbsc/bsc_api.c4
-rw-r--r--openbsc/src/libmsc/Makefile.am3
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c107
-rw-r--r--openbsc/src/libmsc/osmo_msc.c16
-rw-r--r--openbsc/src/libvlr/Makefile.am2
-rw-r--r--openbsc/src/libvlr/vlr.c3
-rw-r--r--openbsc/src/libvlr/vlr_access_req_fsm.c37
-rw-r--r--openbsc/src/libvlr/vlr_access_req_fsm.h34
-rw-r--r--openbsc/src/libvlr/vlr_lu_fsm.c8
12 files changed, 182 insertions, 111 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index c64038e05..9de7c4bdb 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -114,6 +114,8 @@ struct gsm_subscriber_connection {
struct gsm_security_operation *sec_operation;
struct gsm_anchor_operation *anch_operation;
+ struct osmo_fsm_inst *master_fsm;
+
/* Are we part of a special "silent" call */
int silent_call;
diff --git a/openbsc/include/openbsc/osmo_msc.h b/openbsc/include/openbsc/osmo_msc.h
index 8f57ce25f..768f55b42 100644
--- a/openbsc/include/openbsc/osmo_msc.h
+++ b/openbsc/include/openbsc/osmo_msc.h
@@ -3,10 +3,32 @@
#ifndef OSMO_MSC_H
#define OSMO_MSC_H
+#include <osmocom/core/fsm.h>
+
+#include <openbsc/gsm_data.h>
+
#include "bsc_api.h"
+enum subscr_conn_fsm_event {
+ /* LU FSM has terminated */
+ SUB_CON_E_LU_RES,
+ /* Process Access Request has terminated */
+ SUB_CON_E_PARQ_RES,
+ /* MS/BTS/BSC originated close request */
+ SUB_CON_E_MO_CLOSE,
+ /* MSC originated close request, primarily originates from
+ * subscr_con_put() in case reference coult reaches 0 */
+ SUB_CON_E_CN_CLOSE,
+ /* BSC erports confirmation of connection close */
+ SUB_CON_E_CLOSE_CONF,
+};
+
+
struct bsc_api *msc_bsc_api();
struct gsm_subscriber_connection *subscr_con_get(struct gsm_subscriber_connection *conn);
void subscr_con_put(struct gsm_subscriber_connection *conn);
+struct osmo_fsm_inst *
+msc_create_conn_fsm(struct gsm_subscriber_connection *conn,
+ const char *id);
#endif
diff --git a/openbsc/include/openbsc/vlr.h b/openbsc/include/openbsc/vlr.h
index 6112cc82f..4617595df 100644
--- a/openbsc/include/openbsc/vlr.h
+++ b/openbsc/include/openbsc/vlr.h
@@ -120,9 +120,9 @@ struct vlr_subscriber {
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;
+ struct osmo_fsm_inst *auth_fsm;
+ struct osmo_fsm_inst *proc_arq_fsm;
void *msc_conn_ref;
@@ -186,16 +186,18 @@ struct vlr_instance {
} cfg;
};
-struct vlr_subscriber *
-vlr_loc_update(struct vlr_instance *vlr, void *msc_conn_ref,
+struct osmo_fsm_inst *
+vlr_loc_update(struct osmo_fsm_inst *parent, uint32_t parent_term,
+ 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);
+struct osmo_fsm_inst *
+vlr_process_access_req(struct osmo_fsm_inst *parent, uint32_t parent_term,
+ 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);
@@ -238,3 +240,42 @@ 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);
+
+
+
+/* Process Acccess Request FSM */
+
+enum vlr_proc_arq_result {
+ VLR_PR_ARQ_RES_SYSTEM_FAILURE,
+ VLR_PR_ARQ_RES_ILLEGAL_SUBSCR,
+ VLR_PR_ARQ_RES_UNIDENT_SUBSCR,
+ VLR_PR_ARQ_RES_ROAMING_NOTALLOWED,
+ VLR_PR_ARQ_RES_ILLEGAL_EQUIP,
+ VLR_PR_ARQ_RES_UNKNOWN_ERROR,
+ VLR_PR_ARQ_RES_PASSED,
+};
+
+enum proc_arq_vlr_event {
+ PR_ARQ_E_START,
+ PR_ARQ_E_ID_IMSI,
+ PR_ARQ_E_AUTH_RES,
+ PR_ARQ_E_UPD_LOC_RES,
+ PR_ARQ_E_TRACE_RES,
+ PR_ARQ_E_IMEI_RES,
+ PR_ARQ_E_PRES_RES,
+ PR_ARQ_E_TMSI_ACK,
+};
+
+enum vlr_parq_type {
+ VLR_PR_ARQ_T_CM_SERV_REQ,
+ VLR_PR_ARQ_T_PAGING_RESP,
+ /* FIXME: differentiate between services of 24.008 10.5.3.3 */
+};
+
+struct osmo_fsm_inst *
+vlr_proc_acc_req(struct osmo_fsm_inst *parent, uint32_t parent_term,
+ struct vlr_instance *vlr, void *msc_conn_ref,
+ enum vlr_parq_type type, const uint8_t *mi_lv,
+ const struct osmo_location_area_id *lai);
+
+void vlr_parq_fsm_init(void);
diff --git a/openbsc/src/libbsc/bsc_api.c b/openbsc/src/libbsc/bsc_api.c
index b8b596782..b150258c4 100644
--- a/openbsc/src/libbsc/bsc_api.c
+++ b/openbsc/src/libbsc/bsc_api.c
@@ -246,6 +246,10 @@ struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan)
conn = talloc_zero(lchan->ts->trx->bts->network, struct gsm_subscriber_connection);
if (!conn)
return NULL;
+ if (!msc_create_conn_fsm(conn, NULL)) {
+ talloc_free(conn);
+ return NULL;
+ }
/* Configure the time and start it so it will be closed */
conn->lchan = lchan;
diff --git a/openbsc/src/libmsc/Makefile.am b/openbsc/src/libmsc/Makefile.am
index 51958905c..f56a07dd1 100644
--- a/openbsc/src/libmsc/Makefile.am
+++ b/openbsc/src/libmsc/Makefile.am
@@ -19,7 +19,8 @@ libmsc_a_SOURCES = auth.c \
ussd.c \
vty_interface_layer3.c \
transaction.c \
- osmo_msc.c ctrl_commands.c meas_feed.c
+ osmo_msc.c ctrl_commands.c meas_feed.c \
+ subscr_conn_fsm.c
if BUILD_SMPP
noinst_HEADERS += smpp_smsc.h
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index f00da821b..730239b77 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -426,7 +426,6 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
{
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_loc_upd_req *lu;
- struct gsm_subscriber *subscr = NULL;
struct gsm_bts *bts = conn->bts;
uint8_t mi_type;
char mi_string[GSM48_MI_SIZE];
@@ -489,16 +488,18 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
new_lai.plmn.mnc = bts->network->network_code;
new_lai.lac = bts->location_area_code;
- subscr = vlr_loc_update(g_vlr, conn, vlr_lu_type, tmsi, imsi,
- &old_lai, &new_lai);
- if (!subscr) {
- DEBUGPC(DRR, "<- Can't find any subscriber for this ID\n");
- /* FIXME: request id? close channel? */
- return -EINVAL;
+ conn->lu_fsm = vlr_loc_update(conn->master_fsm, SUB_CON_E_LU_RES,
+ g_vlr, conn, vlr_lu_type, tmsi, imsi,
+ &old_lai, &new_lai);
+ if (!conn->lu_fsm) {
+ DEBUGPC(DRR, "%s: Can't start LU FSM\n", mi_string);
+ return 0;
}
- conn->subscr = subscr;
- conn->subscr->equipment.classmark1 = lu->classmark1;
+ /* increase conn ref count for the LU FSM */
+ subscr_con_get(conn);
+
+ //FIXME conn->subscr->equipment.classmark1 = lu->classmark1;
return 0;
}
@@ -757,7 +758,6 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
char mi_string[GSM48_MI_SIZE];
struct gsm_bts *bts = conn->bts;
- struct gsm_subscriber *subscr;
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_service_request *req =
(struct gsm48_service_request *)gh->data;
@@ -766,6 +766,11 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
uint8_t *classmark2 = gh->data+2;
uint8_t mi_len = *(classmark2 + classmark2_len);
uint8_t *mi = (classmark2 + classmark2_len + 1);
+ struct osmo_location_area_id lai;
+
+ lai.plmn.mcc = bts->network->country_code;
+ lai.plmn.mnc = bts->network->network_code;
+ lai.lac = bts->location_area_code;
DEBUGP(DMM, "<- CM SERVICE REQUEST ");
if (msg->data_len < sizeof(struct gsm48_service_request*)) {
@@ -787,39 +792,31 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n",
req->cm_service_type, gsm48_mi_type_name(mi_type),
mi_string);
- subscr = subscr_get_by_imsi(bts->network->subscr_group,
- mi_string);
} else if (mi_type == GSM_MI_TYPE_TMSI) {
DEBUGPC(DMM, "serv_type=0x%02x MI(%s)=%s\n",
req->cm_service_type, gsm48_mi_type_name(mi_type),
mi_string);
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
- tmsi_from_string(mi_string));
} else {
DEBUGPC(DMM, "mi_type is not expected: %d\n", mi_type);
return gsm48_tx_mm_serv_rej(conn,
GSM48_REJECT_INCORRECT_MESSAGE);
}
- osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len));
+ proc_arq_fsm = vlr_proc_acc_req(conn->master_fsm,
+ SUB_CON_E_PARQ_RES, g_vlr,
+ conn, VLR_PR_ARQ_T_CM_SERV_REQ,
+ mi-1, &lai);
+ if (!proc_arq_fsm)
+ return gsm48_tx_mm_serv_rej(conn,
+ GSM48_REJECT_IMSI_UNKNOWN_IN_VLR);
+ /* increase use count for new PARQ FSM */
+ subscr_con_get(conn);
if (is_siemens_bts(bts))
send_siemens_mrpci(msg->lchan, classmark2-1);
-
- /* FIXME: if we don't know the TMSI, inquire abit IMSI and allocate new TMSI */
- if (!subscr)
- return gsm48_tx_mm_serv_rej(conn,
- GSM48_REJECT_IMSI_UNKNOWN_IN_VLR);
-
- if (!conn->subscr)
- conn->subscr = subscr;
- else if (conn->subscr == subscr)
- subscr_put(subscr); /* lchan already has a ref, don't need another one */
- else {
- DEBUGP(DMM, "<- CM Channel already owned by someone else?\n");
- subscr_put(subscr);
- }
+#if 0
+ osmo_signal_dispatch(SS_SUBSCR, S_SUBSCR_IDENTITY, (classmark2 + classmark2_len));
subscr->equipment.classmark2_len = classmark2_len;
memcpy(subscr->equipment.classmark2, classmark2, classmark2_len);
@@ -827,6 +824,7 @@ static int gsm48_rx_mm_serv_req(struct gsm_subscriber_connection *conn, struct m
/* we will send a MM message soon */
conn->expire_timer_stopped = 1;
+#endif
return gsm48_secure_channel(conn, req->cipher_key_seq,
_gsm48_rx_mm_serv_req_sec_cb, NULL);
@@ -958,6 +956,19 @@ static int gsm0408_rcv_mm(struct gsm_subscriber_connection *conn, struct msgb *m
return rc;
}
+static uint8_t *gsm48_cm2_get_mi(uint8_t *classmark2_lv, unsigned int tot_len)
+{
+ /* Check the size for the classmark */
+ if (tot_len < 1 + *classmark2_lv)
+ return NULL;
+
+ uint8_t *mi_lv = classmark2_lv + *classmark2_lv + 1;
+ if (tot_len < 2 + *classmark2_lv + mi_lv[0])
+ return NULL;
+
+ return mi_lv;
+}
+
/* Receive a PAGING RESPONSE message from the MS */
static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
@@ -965,10 +976,15 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
struct gsm48_hdr *gh = msgb_l3(msg);
struct gsm48_pag_resp *resp;
uint8_t *classmark2_lv = gh->data + 1;
+ uint8_t *mi_lv;
uint8_t mi_type;
char mi_string[GSM48_MI_SIZE];
- struct gsm_subscriber *subscr = NULL;
int rc = 0;
+ struct osmo_location_area_id lai;
+
+ lai.plmn.mcc = bts->network->country_code;
+ lai.plmn.mnc = bts->network->network_code;
+ lai.lac = bts->location_area_code;
resp = (struct gsm48_pag_resp *) &gh->data[0];
gsm48_paging_extract_mi(resp, msgb_l3len(msg) - sizeof(*gh),
@@ -976,25 +992,25 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
DEBUGP(DRR, "PAGING RESPONSE: MI(%s)=%s\n",
gsm48_mi_type_name(mi_type), mi_string);
- switch (mi_type) {
- case GSM_MI_TYPE_TMSI:
- subscr = subscr_get_by_tmsi(bts->network->subscr_group,
- tmsi_from_string(mi_string));
- break;
- case GSM_MI_TYPE_IMSI:
- subscr = subscr_get_by_imsi(bts->network->subscr_group,
- mi_string);
- break;
+ mi_lv = gsm48_cm2_get_mi(classmark2_lv, msgb_l3len(msg) - sizeof(*gh));
+ if (!mi_lv) {
+ /* FIXME */
+ return -1;
}
- if (!subscr) {
- DEBUGP(DRR, "<- Can't find any subscriber for this ID\n");
- /* FIXME: request id? close channel? */
- return -EINVAL;
+ proc_arq_fsm = vlr_proc_acc_req(conn->master_fsm,
+ SUB_CON_E_PARQ_RES, g_vlr,
+ conn, VLR_PR_ARQ_T_PAGING_RESP,
+ mi_lv, &lai);
+ if (!proc_arq_fsm) {
+ /* FIXME */
+ return -1;
}
+ subscr_con_get(conn);
+
+#if 0
+ /* FIXME */
log_set_context(BSC_CTX_SUBSCR, subscr);
- DEBUGP(DRR, "<- Channel was requested by %s\n",
- subscr->name && strlen(subscr->name) ? subscr->name : subscr->imsi);
subscr->equipment.classmark2_len = *classmark2_lv;
memcpy(subscr->equipment.classmark2, classmark2_lv+1, *classmark2_lv);
@@ -1004,6 +1020,7 @@ static int gsm48_rx_rr_pag_resp(struct gsm_subscriber_connection *conn, struct m
conn->expire_timer_stopped = 1;
rc = gsm48_handle_paging_resp(conn, msg, subscr);
+#endif
return rc;
}
diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c
index 96b1c2bcf..6b27cc66d 100644
--- a/openbsc/src/libmsc/osmo_msc.c
+++ b/openbsc/src/libmsc/osmo_msc.c
@@ -25,6 +25,8 @@
#include <openbsc/debug.h>
#include <openbsc/transaction.h>
#include <openbsc/db.h>
+#include <openbsc/vlr.h>
+#include <openbsc/osmo_msc.h>
#include <openbsc/gsm_04_11.h>
@@ -58,7 +60,7 @@ static int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg
*/
if (conn->silent_call)
return BSC_API_CONN_POL_ACCEPT;
- if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
+ if (conn->sec_operation || conn->anch_operation)
return BSC_API_CONN_POL_ACCEPT;
if (trans_has_conn(conn))
return BSC_API_CONN_POL_ACCEPT;
@@ -152,7 +154,7 @@ struct bsc_api *msc_bsc_api() {
}
/* lchan release handling */
-static void msc_release_connection(struct gsm_subscriber_connection *conn)
+void msc_release_connection(struct gsm_subscriber_connection *conn)
{
/* skip when we are in release, e.g. due an error */
if (conn->in_release)
@@ -162,7 +164,7 @@ static void msc_release_connection(struct gsm_subscriber_connection *conn)
LOGP(DMSC, LOGL_ERROR, "release_connection() but silent_call active?!?\n");
/* check if there is a pending operation */
- if (conn->loc_operation || conn->sec_operation || conn->anch_operation)
+ if (conn->sec_operation || conn->anch_operation)
LOGP(DMSC, LOGL_ERROR, "relase_connection() but {loc,sec,anch}_operation alive?!?\n");
if (trans_has_conn(conn))
@@ -185,7 +187,8 @@ static void msc_release_connection(struct gsm_subscriber_connection *conn)
vlr_sub_disconnected(conn->subscr);
gsm0808_clear(conn);
- subscr_con_free(conn);
+ /* TODO: is there anything to wait for? */
+ osmo_fsm_inst_dispatch(conn->master_fsm, SUB_CON_E_CLOSE_CONF, NULL);
}
/* increment the ref-count. Needs to be called by every user */
@@ -215,7 +218,6 @@ void subscr_con_put(struct gsm_subscriber_connection *conn)
conn->use_count--;
DEBUGP(DMSC, "decreased subscr_con use_count to %u\n", conn->use_count);
- if (conn->use_count == 0) {
- msc_release_connection(conn);
- }
+ if (conn->use_count == 0)
+ osmo_fsm_inst_dispatch(conn->master_fsm, SUB_CON_E_MO_CLOSE, NULL);
}
diff --git a/openbsc/src/libvlr/Makefile.am b/openbsc/src/libvlr/Makefile.am
index 462f17148..9285cbebd 100644
--- a/openbsc/src/libvlr/Makefile.am
+++ b/openbsc/src/libvlr/Makefile.am
@@ -2,7 +2,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) \
$(COVERAGE_CFLAGS) $(LIBCRYPTO_CFLAGS)
-noinst_HEADERS = vlr_auth_fsm.h vlr_core.h vlr_lu_fsm.h vlr_access_req_fsm.h
+noinst_HEADERS = vlr_auth_fsm.h vlr_core.h vlr_lu_fsm.h
noinst_LIBRARIES = libvlr.a
diff --git a/openbsc/src/libvlr/vlr.c b/openbsc/src/libvlr/vlr.c
index 9edfc0acd..0ed9fb538 100644
--- a/openbsc/src/libvlr/vlr.c
+++ b/openbsc/src/libvlr/vlr.c
@@ -38,7 +38,6 @@
#include "vlr_core.h"
#include "vlr_auth_fsm.h"
-#include "vlr_access_req_fsm.h"
#include "vlr_lu_fsm.h"
#define SGSN_SUBSCR_MAX_RETRIES 3
@@ -751,6 +750,8 @@ struct vlr_instance *vlr_init(void *ctx, const struct vlr_ops *ops,
osmo_fsm_register(&vlr_auth_fsm);
/* osmo_lu_fsm.c */
vlr_lu_fsm_init();
+ /* vlr_access_request_fsm.c */
+ vlr_parq_fsm_init();
return vlr;
}
diff --git a/openbsc/src/libvlr/vlr_access_req_fsm.c b/openbsc/src/libvlr/vlr_access_req_fsm.c
index 1d8094623..1cb4bb273 100644
--- a/openbsc/src/libvlr/vlr_access_req_fsm.c
+++ b/openbsc/src/libvlr/vlr_access_req_fsm.c
@@ -27,7 +27,6 @@
#include "vlr_core.h"
#include "vlr_auth_fsm.h"
#include "vlr_lu_fsm.h"
-#include "vlr_access_req_fsm.h"
#define S(x) (1 << (x))
@@ -82,7 +81,6 @@ static void assoc_par_with_subscr(struct osmo_fsm_inst *fi, struct vlr_subscribe
struct vlr_instance *vlr = par->vlr;
OSMO_ASSERT(vsub->proc_arq_fsm == NULL);
- vsub->proc_arq_fsm = fi;
vsub->msc_conn_ref = par->msc_conn_ref;
par->vsub = vsub;
/* Tell MSC to associate this subscriber with the given
@@ -472,30 +470,47 @@ static struct osmo_fsm proc_arq_vlr_fsm = {
};
struct osmo_fsm_inst *
-vlr_proc_acc_req(struct vlr_instance *vlr, void *msc_conn_ref,
- enum vlr_parq_type type, uint32_t tmsi, const char *imsi,
- const struct osmo_location_area_id *lai)
+vlr_proc_acc_req(struct osmo_fsm_inst *parent, uint32_t parent_term,
+ struct vlr_instance *vlr, void *msc_conn_ref,
+ enum vlr_parq_type type, const uint8_t *mi_lv,
+ const struct osmo_location_area_id *lai)
{
struct osmo_fsm_inst *fi;
struct proc_arq_priv *par;
+ char mi_string[GSM48_MI_SIZE];
+ uint8_t mi_type;
- fi = osmo_fsm_inst_alloc_child(&proc_arq_vlr_fsm, parent, term_event);
+ fi = osmo_fsm_inst_alloc_child(&proc_arq_vlr_fsm, parent,
+ parent_term);;
if (!fi)
return NULL;
par = talloc_zero(fi, struct proc_arq_priv);
+ fi->priv = par;
par->vlr = vlr;
par->msc_conn_ref = msc_conn_ref;
- par->tmsi = tmsi;
par->type = type;
par->lai = *lai;
- if (imsi) {
- strncpy(par->imsi, imsi, sizeof(par->imsi)-1);
+
+ gsm48_mi_to_string(mi_string, sizeof(mi_string), mi_lv+1, mi_lv[0]);
+ mi_type = mi_lv[1] & GSM_MI_TYPE_MASK;
+ switch (mi_type) {
+ case GSM_MI_TYPE_IMSI:
+ strncpy(par->imsi, mi_string, sizeof(par->imsi)-1);
par->imsi[sizeof(par->imsi)-1] = '\0';
par->by_tmsi = false;
- } else
+ break;
+ case GSM_MI_TYPE_TMSI:
par->by_tmsi = true;
- fi->priv = par;
+ par->tmsi = osmo_load32be(mi_lv+2);
+ break;
+ case GSM_MI_TYPE_IMEI:
+ /* TODO: IMEI (emergency call) */
+ default:
+ /* FIXME: directly send reject? */
+ osmo_fsm_inst_term(fi, OSMO_FSM_TERM_ERROR, NULL);
+ return NULL;
+ }
osmo_fsm_inst_dispatch(fi, PR_ARQ_E_START, NULL);
diff --git a/openbsc/src/libvlr/vlr_access_req_fsm.h b/openbsc/src/libvlr/vlr_access_req_fsm.h
index 25acdfbfc..3f59c932d 100644
--- a/openbsc/src/libvlr/vlr_access_req_fsm.h
+++ b/openbsc/src/libvlr/vlr_access_req_fsm.h
@@ -1,36 +1,2 @@
#pragma once
-enum vlr_proc_arq_result {
- VLR_PR_ARQ_RES_SYSTEM_FAILURE,
- VLR_PR_ARQ_RES_ILLEGAL_SUBSCR,
- VLR_PR_ARQ_RES_UNIDENT_SUBSCR,
- VLR_PR_ARQ_RES_ROAMING_NOTALLOWED,
- VLR_PR_ARQ_RES_ILLEGAL_EQUIP,
- VLR_PR_ARQ_RES_UNKNOWN_ERROR,
- VLR_PR_ARQ_RES_PASSED,
-};
-
-enum proc_arq_vlr_event {
- PR_ARQ_E_START,
- PR_ARQ_E_ID_IMSI,
- PR_ARQ_E_AUTH_RES,
- PR_ARQ_E_UPD_LOC_RES,
- PR_ARQ_E_TRACE_RES,
- PR_ARQ_E_IMEI_RES,
- PR_ARQ_E_PRES_RES,
- PR_ARQ_E_TMSI_ACK,
-};
-
-enum vlr_parq_type {
- VLR_PR_ARQ_T_CM_SERV_REQ,
- VLR_PR_ARQ_T_PAGING_RESP,
- /* FIXME: differentiate between services of 24.008 10.5.3.3 */
-};
-
-
-struct osmo_fsm_inst *
-vlr_proc_acc_req(struct vlr_instance *vlr, void *msc_conn_ref,
- enum vlr_parq_type type, uint32_t tmsi, const char *imsi,
- const struct osmo_location_area_id *lai);
-
-void vlr_parq_fsm_init(void);
diff --git a/openbsc/src/libvlr/vlr_lu_fsm.c b/openbsc/src/libvlr/vlr_lu_fsm.c
index 3f8a65a0b..ad177a30d 100644
--- a/openbsc/src/libvlr/vlr_lu_fsm.c
+++ b/openbsc/src/libvlr/vlr_lu_fsm.c
@@ -1034,8 +1034,9 @@ static struct osmo_fsm vlr_lu_fsm = {
.event_names = fsm_lu_event_names,
};
-struct vlr_subscriber *
-vlr_loc_update(struct vlr_instance *vlr, void *msc_conn_ref,
+struct osmo_fsm_inst *
+vlr_loc_update(struct osmo_fsm_inst *parent, uint32_t parent_term,
+ 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)
@@ -1052,8 +1053,7 @@ vlr_loc_update(struct vlr_instance *vlr, void *msc_conn_ref,
id_str = buf;
}
- fi = osmo_fsm_inst_alloc(&vlr_lu_fsm, vlr, NULL, LOGL_DEBUG,
- id_str);
+ fi = osmo_fsm_inst_alloc_child(&vlr_lu_fsm, parent, parent_term);
if (!fi)
return NULL;