aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2019-09-04 20:40:50 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2019-09-04 21:07:36 +0200
commit3517edff26703b4515ddfffe6239e918816a74c4 (patch)
treed8de68e0318c81af7af3e5bc50d005b6ec754917
parent47ba5f72ed0b13ce1d45d3c7684d45c2de312224 (diff)
bsc_subscr_conn_fsm: Cleanly clear BSSAP conn if associated channel closed during WAIT_CCpespin/master
TTCN3 BSC_Tests.TC_ms_rel_ind_does_not_cause_bssmap_reset seems to sometimes run into a race condition on the order of messages received by osmo-bsc comming from MSC and BTS. Usual (expected) scenario): BTS->BSC EST IND BSC->MSC CL3 Info BSC<-MSC CC BTS->BSC REL IND BTS<-BSC DEACT SACCH BSC->MSC ClearRequest BSC<-MSC ClearCommand BSC->MSC ClearComplete BTS<-BSC RF Chan Release BTS->BSC RF Chan Release ACK Sometimes CC message and REL IND message are received swapped (because they are sent by different components asynchronously in TTCN3). As a result, osmo-bsc was failing to go into CLEARING state and was unable to send the ClearRequest because CC was still not received. So the idea is to stay in WAIT_CC until CC is received, then check if the lchan was dropped and in that case go into clearing state. Change-Id: Id1abf5ee44c60925b478123409f26bd29006202b
-rw-r--r--src/osmo-bsc/bsc_subscr_conn_fsm.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
index f8784f9ba..b5edeb816 100644
--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
@@ -99,6 +99,12 @@ struct osmo_tdef_state_timeout conn_fsm_timeouts[32] = {
conn->network->T_defs, \
-1)
+static bool gscon_is_active(struct gsm_subscriber_connection *conn)
+{
+ enum gscon_fsm_states st = conn->fi->state;
+ return st == ST_ACTIVE || st == ST_ASSIGNMENT || st == ST_HANDOVER;
+}
+
/* forward MT DTAP from BSSAP side to RSL side */
static inline void submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
@@ -333,10 +339,19 @@ static void gscon_fsm_wait_cc(struct osmo_fsm_inst *fi, uint32_t event, void *da
switch (event) {
case GSCON_EV_A_CONN_CFM:
/* MSC has confirmed the connection, we now change into the
- * active state and wait there for further operations */
- conn_fsm_state_chg(ST_ACTIVE);
- /* if there's user payload, forward it just like EV_MT_DTAP */
- /* FIXME: Question: if there's user payload attached to the CC, forward it like EV_MT_DTAP? */
+ * active state and wait there for further operations. */
+ if (conn->lchan) {
+ conn_fsm_state_chg(ST_ACTIVE);
+ /* if there's user payload, forward it just like EV_MT_DTAP */
+ /* FIXME: Question: if there's user payload attached to the CC, forward it like EV_MT_DTAP? */
+ } else {
+ /* If associated lchan was released while we were
+ * waiting for the confirmed connection, then instead
+ * simply drop the connection */
+ LOGPFSML(fi, LOGL_INFO, "Connection confirmed but lchan was dropped before, clearing conn\n");
+ osmo_fsm_inst_state_chg(conn->fi, ST_CLEARING, 60, 999);
+ gscon_bssmap_clear(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
+ }
break;
default:
OSMO_ASSERT(false);
@@ -589,7 +604,7 @@ static const struct osmo_fsm_state gscon_fsm_states[] = {
[ST_WAIT_CC] = {
.name = "WAIT_CC",
.in_event_mask = S(GSCON_EV_A_CONN_CFM),
- .out_state_mask = S(ST_ACTIVE),
+ .out_state_mask = S(ST_ACTIVE) | S(ST_CLEARING),
.action = gscon_fsm_wait_cc,
},
[ST_ACTIVE] = {
@@ -651,9 +666,10 @@ void gscon_lchan_releasing(struct gsm_subscriber_connection *conn, struct gsm_lc
lchan_forget_conn(conn->lchan);
conn->lchan = NULL;
}
- if (!conn->lchan) {
- if (conn->fi->state != ST_CLEARING)
- osmo_fsm_inst_state_chg(conn->fi, ST_CLEARING, 60, 999);
+ /* if conn is not active we cannot send bssap. If on WAIT_CC, then let's
+ * wait until CC is received to tear down */
+ if (!conn->lchan && gscon_is_active(conn)) {
+ osmo_fsm_inst_state_chg(conn->fi, ST_CLEARING, 60, 999);
gscon_bssmap_clear(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
}
}