diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2018-03-12 00:39:47 +0100 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2018-03-12 03:52:12 +0100 |
commit | 6eb3640bf99d11e482444c3b8bcb0a6af7c17f1f (patch) | |
tree | 8c190fd3c6f4fe97bcbc4b0bf19e25ee1f68fbd6 | |
parent | 4ac7763bc7c861e7f28e8eead6f2327387f6e2a9 (diff) |
abis_rsl: properly handle RSL Release Ind from MS
If we receive a Release Ind from the MS, we so far just drop it on the floor,
assuming that some other part of the BSC code invoked something that it is
already taking care of -- which is of course not the case.
If we receive a Release Ind for an lchan that is not in state LCHAN_S_REL_REQ,
signal the MSC with a Clear Request which will lead to a graceful teardown of
the entire connection.
If there should be no conn, immediately invoke the channel release and ignore
BSSAP.
Related: ttcn3 test TC_chan_rel_rll_rel_ind(),
see I737be141b69a250eb6eb38007f8042981c1a31cf (osmo-ttcn3-hacks)
Change-Id: I0f8c9c4e6b6850b15c70250fd3f88bdf75f9accf
-rw-r--r-- | src/libbsc/abis_rsl.c | 32 | ||||
-rw-r--r-- | src/osmo-bsc/osmo_bsc_api.c | 3 |
2 files changed, 29 insertions, 6 deletions
diff --git a/src/libbsc/abis_rsl.c b/src/libbsc/abis_rsl.c index 7400f896e..9ec4f2d35 100644 --- a/src/libbsc/abis_rsl.c +++ b/src/libbsc/abis_rsl.c @@ -2125,13 +2125,33 @@ static void rsl_handle_release(struct gsm_lchan *lchan) int sapi; struct gsm_bts *bts; - /* - * Maybe only one link/SAPI was releasd or the error handling - * was activated. Just return now and let the other code handle - * it. - */ - if (lchan->state != LCHAN_S_REL_REQ) + if (lchan->state == LCHAN_S_NONE) { + LOGP(DRSL, LOGL_ERROR, "%s Release requested for an unused lchan\n", + gsm_lchan_name(lchan)); + return; + } + + if (lchan->state != LCHAN_S_REL_REQ) { + /* The MS asked us to release. */ + struct bsc_api *bsc_api = lchan->ts->trx->bts->network->bsc_api; + if (!bsc_api || !bsc_api->clear_request) { + LOGP(DRSL, LOGL_ERROR, "%s FATAL: no bsc_api to dispatch Clear Request\n", + gsm_lchan_name(lchan)); + return; + } + rsl_lchan_set_state(lchan, LCHAN_S_REL_REQ); + + if (!lchan->conn) { + /* No conn exists, release the lchan right away */ + lchan->state = LCHAN_S_REL_REQ; + rsl_rf_chan_release(lchan, 0, SACCH_NONE); + return; + } + + /* Kick off a BSSAP Clear Request followed by a full teardown via MSC. */ + bsc_api->clear_request(lchan->conn, 0); return; + } for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) { if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) diff --git a/src/osmo-bsc/osmo_bsc_api.c b/src/osmo-bsc/osmo_bsc_api.c index 75dae1293..b87711d27 100644 --- a/src/osmo-bsc/osmo_bsc_api.c +++ b/src/osmo-bsc/osmo_bsc_api.c @@ -449,6 +449,9 @@ static void bsc_assign_fail(struct gsm_subscriber_connection *conn, static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause) { struct msgb *resp; + if (!conn) + return 1; + return_when_not_connected_val(conn, 1); LOGP(DMSC, LOGL_INFO, "Tx MSC CLEAR REQUEST\n"); |