aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2020-07-11 01:44:08 +0200
committerlaforge <laforge@osmocom.org>2020-07-16 12:03:19 +0000
commit3405c7728236f3a588a0649bc3c8a327f7a317d6 (patch)
treeec2d5d390ad55b23bfd21e67ca508840ee61fe98
parentb523f54de4f9b733ce74ffe245e27418d4c8ed35 (diff)
propagate RSL error cause codes to RR Channel Release cause
In various places that receive an error cause from RSL and place it in lchan.release.rsl_error_cause, translate it to an RR cause and place that in the recently added lchan.release.rr_cause. Hence the RR Channel Release message now reflects more specific error causes when the reason for the error was received in an RSL message's cause value. Change-Id: I46eb12c91a8c08162b43dd22c7ba825ef3bbc6ac
-rw-r--r--include/osmocom/bsc/gsm_data.h1
-rw-r--r--src/osmo-bsc/bsc_subscr_conn_fsm.c2
-rw-r--r--src/osmo-bsc/gsm_data.c26
-rw-r--r--src/osmo-bsc/lchan_fsm.c5
4 files changed, 34 insertions, 0 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 43d7040fc..c35798192 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1898,5 +1898,6 @@ int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
bool trx_has_valid_pchan_config(const struct gsm_bts_trx *trx);
enum gsm48_rr_cause bsc_gsm48_rr_cause_from_gsm0808_cause(enum gsm0808_cause c);
+enum gsm48_rr_cause bsc_gsm48_rr_cause_from_rsl_cause(uint8_t c);
#endif /* _GSM_DATA_H */
diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
index 0ed6715be..72f24749f 100644
--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
@@ -783,6 +783,8 @@ static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d
if (conn->lchan) {
conn->lchan->release.in_error = true;
conn->lchan->release.rsl_error_cause = data ? *(uint8_t*)data : RSL_ERR_IE_ERROR;
+ conn->lchan->release.rr_cause =
+ bsc_gsm48_rr_cause_from_rsl_cause(conn->lchan->release.rsl_error_cause);
}
gscon_bssmap_clear(conn, GSM0808_CAUSE_RADIO_INTERFACE_FAILURE);
break;
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index 860e236fe..a4f6b7f36 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -1867,3 +1867,29 @@ enum gsm48_rr_cause bsc_gsm48_rr_cause_from_gsm0808_cause(enum gsm0808_cause c)
return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
}
}
+
+/* Map RSL_ERR_* cause codes to gsm48_rr_cause codes.
+ * The mappings were chosen by naive guessing without a proper specification available. */
+enum gsm48_rr_cause bsc_gsm48_rr_cause_from_rsl_cause(uint8_t c)
+{
+ switch (c) {
+ case RSL_ERR_NORMAL_UNSPEC:
+ return GSM48_RR_CAUSE_NORMAL;
+ case RSL_ERR_MAND_IE_ERROR:
+ return GSM48_RR_CAUSE_INVALID_MAND_INF;
+ case RSL_ERR_OPT_IE_ERROR:
+ return GSM48_RR_CAUSE_COND_IE_ERROR;
+ case RSL_ERR_INVALID_MESSAGE:
+ case RSL_ERR_MSG_DISCR:
+ case RSL_ERR_MSG_TYPE:
+ case RSL_ERR_MSG_SEQ:
+ case RSL_ERR_IE_ERROR:
+ case RSL_ERR_IE_NONEXIST:
+ case RSL_ERR_IE_LENGTH:
+ case RSL_ERR_IE_CONTENT:
+ case RSL_ERR_PROTO:
+ return GSM48_RR_CAUSE_PROT_ERROR_UNSPC;
+ default:
+ return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
+ }
+}
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index dfb8a053d..bcf7c4b06 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -681,6 +681,7 @@ static void lchan_fsm_wait_activ_ack(struct osmo_fsm_inst *fi, uint32_t event, v
if (data) {
uint32_t next_state;
lchan->release.rsl_error_cause = *(uint8_t*)data;
+ lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause);
lchan->release.in_error = true;
if (lchan->release.rsl_error_cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
next_state = LCHAN_ST_BORKEN;
@@ -693,6 +694,7 @@ static void lchan_fsm_wait_activ_ack(struct osmo_fsm_inst *fi, uint32_t event, v
rsl_err_name(lchan->release.rsl_error_cause), lchan->release.rsl_error_cause);
} else {
lchan->release.rsl_error_cause = RSL_ERR_IE_NONEXIST;
+ lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause);
lchan->release.in_error = true;
lchan_fail_to(LCHAN_ST_BORKEN, "Chan Activ NACK without cause IE");
}
@@ -1109,6 +1111,7 @@ static void lchan_fsm_borken(struct osmo_fsm_inst *fi, uint32_t event, void *dat
osmo_stat_item_dec(lchan->ts->trx->bts->bts_statg->items[BTS_STAT_LCHAN_BORKEN], 1);
lchan->release.in_error = true;
lchan->release.rsl_error_cause = RSL_ERR_INTERWORKING;
+ lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause);
lchan_fsm_state_chg(LCHAN_ST_WAIT_RF_RELEASE_ACK);
return;
@@ -1125,6 +1128,7 @@ static void lchan_fsm_borken(struct osmo_fsm_inst *fi, uint32_t event, void *dat
osmo_stat_item_dec(lchan->ts->trx->bts->bts_statg->items[BTS_STAT_LCHAN_BORKEN], 1);
lchan->release.in_error = true;
lchan->release.rsl_error_cause = RSL_ERR_INTERWORKING;
+ lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause);
lchan_fsm_state_chg(LCHAN_ST_WAIT_AFTER_ERROR);
/* TODO: we used to do this only for sysmobts:
int do_free = is_sysmobts_v2(ts->trx->bts);
@@ -1353,6 +1357,7 @@ int lchan_fsm_timer_cb(struct osmo_fsm_inst *fi)
default:
lchan->release.in_error = true;
lchan->release.rsl_error_cause = RSL_ERR_INTERWORKING;
+ lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause);
lchan_fail("Timeout");
return 0;
}