aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-03-12 00:39:47 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2018-03-12 03:52:12 +0100
commit6eb3640bf99d11e482444c3b8bcb0a6af7c17f1f (patch)
tree8c190fd3c6f4fe97bcbc4b0bf19e25ee1f68fbd6
parent4ac7763bc7c861e7f28e8eead6f2327387f6e2a9 (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.c32
-rw-r--r--src/osmo-bsc/osmo_bsc_api.c3
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");