diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2020-07-11 01:44:08 +0200 |
---|---|---|
committer | laforge <laforge@osmocom.org> | 2020-07-16 12:03:19 +0000 |
commit | 3405c7728236f3a588a0649bc3c8a327f7a317d6 (patch) | |
tree | ec2d5d390ad55b23bfd21e67ca508840ee61fe98 | |
parent | b523f54de4f9b733ce74ffe245e27418d4c8ed35 (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.h | 1 | ||||
-rw-r--r-- | src/osmo-bsc/bsc_subscr_conn_fsm.c | 2 | ||||
-rw-r--r-- | src/osmo-bsc/gsm_data.c | 26 | ||||
-rw-r--r-- | src/osmo-bsc/lchan_fsm.c | 5 |
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; } |