aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-07-22 17:42:29 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-07-22 21:24:58 +0200
commit9613d7860fb4b28e0ac1d1a592df25f8351e5b64 (patch)
tree6d8cf58f1ca17f82e210447ceb18898ad7577aa6 /openbsc/src/libmsc
parent3fc122d360c46e0fe374c2fee34d9e8ceaf44ce9 (diff)
fix release upon IMSI Detach
In case of an IMSI Detach, we don't have a conn_fsm, yet we still need to send release messages. Hence directly release the conn in msc_subscr_conn_close() when there is no conn_fsm present. Move the conn release actions from the conn_fsm cleanup function to new function msc_subscr_conn_release_all(). From the FSM cleanup, call msc_subscr_conn_close(), and invoke msc_subscr_conn_release_all() from there. Document msc_subscr_conn_close() behavior. Change-Id: Ied6981099605ad803f8ffed38f23ed8203a97727
Diffstat (limited to 'openbsc/src/libmsc')
-rw-r--r--openbsc/src/libmsc/osmo_msc.c36
-rw-r--r--openbsc/src/libmsc/subscr_conn.c18
2 files changed, 34 insertions, 20 deletions
diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c
index 2b91f010e..1429ca988 100644
--- a/openbsc/src/libmsc/osmo_msc.c
+++ b/openbsc/src/libmsc/osmo_msc.c
@@ -262,8 +262,35 @@ struct bsc_api *msc_bsc_api() {
return &msc_handler;
}
-/* Signal the connection's FSM to gracefully terminate the connection by a
- * SUBSCR_CONN_E_CN_CLOSE event.
+void msc_subscr_conn_release_all(struct gsm_subscriber_connection *conn, uint32_t cause)
+{
+ if (conn->in_release)
+ return;
+ conn->in_release = true;
+
+ /* If we're closing in a middle of a trans, we need to clean up */
+ trans_conn_closed(conn);
+
+ switch (conn->via_ran) {
+ case RAN_UTRAN_IU:
+ iu_tx_release(conn->iu.ue_ctx, NULL);
+ /* FIXME: keep the conn until the Iu Release Outcome is
+ * received from the UE, or a timeout expires. For now, the log
+ * says "unknown UE" for each release outcome. */
+ break;
+ case RAN_GERAN_A:
+ a_iface_tx_clear_cmd(conn);
+ break;
+ default:
+ LOGP(DMM, LOGL_ERROR, "%s: Unknown RAN type, cannot tx release/clear\n",
+ vlr_subscr_name(conn->vsub));
+ break;
+ }
+}
+
+/* If the conn->conn_fsm is still present, dispatch SUBSCR_CONN_E_CN_CLOSE
+ * event to gracefully terminate the connection. If the conn_fsm is already
+ * cleared, call msc_subscr_conn_release_all() to take release actions.
* \param cause a GSM_CAUSE_* constant, e.g. GSM_CAUSE_AUTH_FAILED.
*/
void msc_subscr_conn_close(struct gsm_subscriber_connection *conn,
@@ -279,8 +306,11 @@ void msc_subscr_conn_close(struct gsm_subscriber_connection *conn,
}
if (!conn->conn_fsm) {
DEBUGP(DMM, "msc_subscr_conn_close(vsub=%s, cause=%u): no conn fsm,"
- " ignore.\n",
+ " releasing directly without release event.\n",
vlr_subscr_name(conn->vsub), cause);
+ /* In case of an IMSI Detach, we don't have conn_fsm. Release
+ * anyway to ensure a timely Iu Release / BSSMAP Clear. */
+ msc_subscr_conn_release_all(conn, cause);
return;
}
if (conn->conn_fsm->state == SUBSCR_CONN_S_RELEASED) {
diff --git a/openbsc/src/libmsc/subscr_conn.c b/openbsc/src/libmsc/subscr_conn.c
index 5219944d9..249de7ddf 100644
--- a/openbsc/src/libmsc/subscr_conn.c
+++ b/openbsc/src/libmsc/subscr_conn.c
@@ -225,25 +225,9 @@ static void subscr_conn_fsm_cleanup(struct osmo_fsm_inst *fi,
if (!conn)
return;
-
- if (conn->in_release)
- return;
- conn->in_release = true;
conn->conn_fsm = NULL;
- /* If we're closing in a middle of a trans, we need to clean up */
- trans_conn_closed(conn);
-
- if (conn->via_ran == RAN_UTRAN_IU)
- iu_tx_release(conn->iu.ue_ctx, NULL);
- /* FIXME: keep the conn until the Iu Release Outcome is
- * received from the UE, or a timeout expires. For now, the log
- * says "unknown UE" for each release outcome. */
-
- /* Clear A-Interface connection */
- if (conn->via_ran == RAN_GERAN_A)
- a_iface_tx_clear_cmd(conn);
-
+ msc_subscr_conn_close(conn, cause);
msc_subscr_conn_put(conn);
}