diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-07-22 17:42:29 +0200 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-07-22 21:24:58 +0200 |
commit | 9613d7860fb4b28e0ac1d1a592df25f8351e5b64 (patch) | |
tree | 6d8cf58f1ca17f82e210447ceb18898ad7577aa6 /openbsc/src/libmsc | |
parent | 3fc122d360c46e0fe374c2fee34d9e8ceaf44ce9 (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.c | 36 | ||||
-rw-r--r-- | openbsc/src/libmsc/subscr_conn.c | 18 |
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); } |