aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
}