aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/msc/gsm_data.h2
-rw-r--r--include/osmocom/msc/transaction.h2
-rw-r--r--src/libmsc/gsm_09_11.c62
-rw-r--r--src/libmsc/msc_vty.c15
-rw-r--r--src/libmsc/osmo_msc.c1
-rw-r--r--tests/test_nodes.vty8
6 files changed, 90 insertions, 0 deletions
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index dab082d82..7d3a1e71b 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -192,6 +192,8 @@ struct gsm_network {
/* Global MNCC guard timer value */
int mncc_guard_timeout;
+ /* Global guard timer value for NCSS sessions */
+ int ncss_guard_timeout;
struct {
struct mgcp_client_conf conf;
diff --git a/include/osmocom/msc/transaction.h b/include/osmocom/msc/transaction.h
index 39b09aeaa..830328bca 100644
--- a/include/osmocom/msc/transaction.h
+++ b/include/osmocom/msc/transaction.h
@@ -87,6 +87,8 @@ struct gsm_trans {
* a subscriber after successful Paging Response
*/
struct msgb *msg;
+ /* Inactivity timer, triggers transaction release */
+ struct osmo_timer_list timer_guard;
} ss;
};
diff --git a/src/libmsc/gsm_09_11.c b/src/libmsc/gsm_09_11.c
index d2ad0b7a6..c133656dd 100644
--- a/src/libmsc/gsm_09_11.c
+++ b/src/libmsc/gsm_09_11.c
@@ -51,6 +51,39 @@
/* FIXME: choose a proper range */
static uint32_t new_callref = 0x20000001;
+static void ncss_session_timeout_handler(void *_trans)
+{
+ struct gsm_trans *trans = (struct gsm_trans *) _trans;
+ struct osmo_gsup_message gsup_msg = { 0 };
+
+ /* The timeout might be disabled from the VTY */
+ if (trans->net->ncss_guard_timeout == 0)
+ return;
+
+ LOGP(DMM, LOGL_NOTICE, "SS/USSD session timeout, releasing "
+ "transaction (trans=%p, callref=%x)\n", trans, trans->callref);
+
+ /* Indicate connection release to subscriber (if active) */
+ if (trans->conn != NULL) {
+ /* This pair of cause location and value is used by commercial networks */
+ msc_send_ussd_release_complete_cause(trans->conn, trans->transaction_id,
+ GSM48_CAUSE_LOC_PUN_S_LU, GSM48_CC_CAUSE_NORMAL_UNSPEC);
+ }
+
+ /* Terminate GSUP session with EUSE */
+ gsup_msg.message_type = OSMO_GSUP_MSGT_PROC_SS_ERROR;
+ OSMO_STRLCPY_ARRAY(gsup_msg.imsi, trans->vsub->imsi);
+
+ gsup_msg.session_state = OSMO_GSUP_SESSION_STATE_END;
+ gsup_msg.session_id = trans->callref;
+ gsup_msg.cause = GMM_CAUSE_NET_FAIL;
+
+ osmo_gsup_client_enc_send(trans->net->vlr->gsup_client, &gsup_msg);
+
+ /* Finally, release this transaction */
+ trans_free(trans);
+}
+
/* Entry point for call independent MO SS messages */
int gsm0911_rcv_nc_ss(struct ran_conn *conn, struct msgb *msg)
{
@@ -108,6 +141,10 @@ int gsm0911_rcv_nc_ss(struct ran_conn *conn, struct msgb *msg)
return -ENOMEM;
}
+ /* Init inactivity timer */
+ osmo_timer_setup(&trans->ss.timer_guard,
+ ncss_session_timeout_handler, trans);
+
/* Count active NC SS/USSD sessions */
osmo_counter_inc(conn->network->active_nc_ss);
@@ -116,6 +153,12 @@ int gsm0911_rcv_nc_ss(struct ran_conn *conn, struct msgb *msg)
cm_service_request_concludes(conn, msg);
}
+ /* (Re)schedule the inactivity timer */
+ if (conn->network->ncss_guard_timeout > 0) {
+ osmo_timer_schedule(&trans->ss.timer_guard,
+ conn->network->ncss_guard_timeout, 0);
+ }
+
/* Attempt to extract Facility IE */
rc = gsm0480_extract_ie_by_tag(gh, msgb_l3len(msg),
&facility_ie, &facility_ie_len, GSM0480_IE_FACILITY);
@@ -233,6 +276,12 @@ static int handle_paging_event(unsigned int hooknum, unsigned int event,
transt->conn = ran_conn_get(conn, RAN_CONN_USE_TRANS_NC_SS);
transt->paging_request = NULL;
+ /* (Re)schedule the inactivity timer */
+ if (conn->network->ncss_guard_timeout > 0) {
+ osmo_timer_schedule(&transt->ss.timer_guard,
+ conn->network->ncss_guard_timeout, 0);
+ }
+
/* Send stored message */
ss_msg = transt->ss.msg;
gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
@@ -317,6 +366,10 @@ static struct gsm_trans *establish_nc_ss_trans(struct gsm_network *net,
}
trans->transaction_id = tid;
+ /* Init inactivity timer */
+ osmo_timer_setup(&trans->ss.timer_guard,
+ ncss_session_timeout_handler, trans);
+
/* Attempt to find connection */
conn = connection_for_subscr(vsub);
if (conn) {
@@ -371,6 +424,9 @@ void _gsm911_nc_ss_trans_free(struct gsm_trans *trans)
if (trans->ss.msg != NULL)
msgb_free(trans->ss.msg);
+ /* Stop inactivity timer */
+ osmo_timer_del(&trans->ss.timer_guard);
+
/* One session less */
osmo_counter_dec(trans->net->active_nc_ss);
}
@@ -420,6 +476,12 @@ int gsm0911_gsup_handler(struct vlr_subscr *vsub,
return 0;
}
+ /* (Re)schedule the inactivity timer */
+ if (net->ncss_guard_timeout > 0) {
+ osmo_timer_schedule(&trans->ss.timer_guard,
+ net->ncss_guard_timeout, 0);
+ }
+
/* Allocate and prepare a new MT message */
ss_msg = gsm48_msgb_alloc_name("GSM 04.08 SS/USSD");
gh = (struct gsm48_hdr *) msgb_push(ss_msg, sizeof(*gh));
diff --git a/src/libmsc/msc_vty.c b/src/libmsc/msc_vty.c
index 078b83aea..5aa533b1f 100644
--- a/src/libmsc/msc_vty.c
+++ b/src/libmsc/msc_vty.c
@@ -375,6 +375,18 @@ ALIAS_DEPRECATED(cfg_msc_mncc_guard_timeout,
"mncc-guard-timeout <0-255>",
MNCC_GUARD_TIMEOUT_STR MNCC_GUARD_TIMEOUT_VALUE_STR);
+#define NCSS_STR "Configure call independent Supplementary Services\n"
+
+DEFUN(cfg_msc_ncss_guard_timeout,
+ cfg_msc_ncss_guard_timeout_cmd,
+ "ncss guard-timeout <0-255>",
+ NCSS_STR "Set guard timer for session activity\n"
+ "guard timer value (sec.), or 0 to disable\n")
+{
+ gsmnet->ncss_guard_timeout = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_msc_assign_tmsi, cfg_msc_assign_tmsi_cmd,
"assign-tmsi",
"Assign TMSI during Location Updating.\n")
@@ -496,6 +508,8 @@ static int config_write_msc(struct vty *vty)
vty_out(vty, " mncc external %s%s", gsmnet->mncc_sock_path, VTY_NEWLINE);
vty_out(vty, " mncc guard-timeout %i%s",
gsmnet->mncc_guard_timeout, VTY_NEWLINE);
+ vty_out(vty, " ncss guard-timeout %i%s",
+ gsmnet->ncss_guard_timeout, VTY_NEWLINE);
vty_out(vty, " %sassign-tmsi%s",
gsmnet->vlr->cfg.assign_tmsi? "" : "no ", VTY_NEWLINE);
@@ -1588,6 +1602,7 @@ void msc_vty_init(struct gsm_network *msc_network)
install_element(MSC_NODE, &cfg_msc_mncc_external_cmd);
install_element(MSC_NODE, &cfg_msc_mncc_guard_timeout_cmd);
install_element(MSC_NODE, &cfg_msc_deprecated_mncc_guard_timeout_cmd);
+ install_element(MSC_NODE, &cfg_msc_ncss_guard_timeout_cmd);
install_element(MSC_NODE, &cfg_msc_no_assign_tmsi_cmd);
install_element(MSC_NODE, &cfg_msc_auth_tuple_max_reuse_count_cmd);
install_element(MSC_NODE, &cfg_msc_auth_tuple_reuse_on_error_cmd);
diff --git a/src/libmsc/osmo_msc.c b/src/libmsc/osmo_msc.c
index 9828da164..5c6f0aa2e 100644
--- a/src/libmsc/osmo_msc.c
+++ b/src/libmsc/osmo_msc.c
@@ -54,6 +54,7 @@ struct gsm_network *gsm_network_init(void *ctx, mncc_recv_cb_t mncc_recv)
net->t3212 = 5;
net->mncc_guard_timeout = 180;
+ net->ncss_guard_timeout = 30;
net->paging_response_timer = MSC_PAGING_RESPONSE_TIMER_DEFAULT;
diff --git a/tests/test_nodes.vty b/tests/test_nodes.vty
index f2312d144..fb9e5f051 100644
--- a/tests/test_nodes.vty
+++ b/tests/test_nodes.vty
@@ -34,6 +34,7 @@ OsmoMSC(config-msc)# list
mncc internal
mncc external MNCC_SOCKET_PATH
mncc guard-timeout <0-255>
+ ncss guard-timeout <0-255>
no assign-tmsi
auth-tuple-max-reuse-count <-1-2147483647>
auth-tuple-reuse-on-error (0|1)
@@ -50,6 +51,12 @@ OsmoMSC(config-msc)# list
mgw remote-port <0-65535>
...
+OsmoMSC(config-msc)# ncss?
+ ncss Configure call independent Supplementary Services
+
+OsmoMSC(config-msc)# ncss ?
+ guard-timeout Set guard timer for session activity
+
OsmoMSC(config-msc)# mncc?
mncc Configure Mobile Network Call Control
@@ -123,6 +130,7 @@ network
periodic location update 30
msc
mncc guard-timeout 180
+ ncss guard-timeout 30
assign-tmsi
cs7-instance-a 0
...