From 6eb3640bf99d11e482444c3b8bcb0a6af7c17f1f Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 12 Mar 2018 00:39:47 +0100 Subject: 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 --- src/libbsc/abis_rsl.c | 32 ++++++++++++++++++++++++++------ 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"); -- cgit v1.2.3