aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/timeslot_fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bsc/timeslot_fsm.c')
-rw-r--r--src/osmo-bsc/timeslot_fsm.c72
1 files changed, 64 insertions, 8 deletions
diff --git a/src/osmo-bsc/timeslot_fsm.c b/src/osmo-bsc/timeslot_fsm.c
index 84ffb7f54..4816dafb5 100644
--- a/src/osmo-bsc/timeslot_fsm.c
+++ b/src/osmo-bsc/timeslot_fsm.c
@@ -654,6 +654,39 @@ static void ts_fsm_in_use(struct osmo_fsm_inst *fi, uint32_t event, void *data)
}
}
+static void ts_fsm_borken_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts_trx_ts *ts = ts_fi_ts(fi);
+ enum bts_counter_id ctr;
+ switch (prev_state) {
+ case TS_ST_NOT_INITIALIZED:
+ ctr = BTS_CTR_TS_BORKEN_FROM_NOT_INITIALIZED;
+ break;
+ case TS_ST_UNUSED:
+ ctr = BTS_CTR_TS_BORKEN_FROM_UNUSED;
+ break;
+ case TS_ST_WAIT_PDCH_ACT:
+ ctr = BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_ACT;
+ break;
+ case TS_ST_PDCH:
+ ctr = BTS_CTR_TS_BORKEN_FROM_PDCH;
+ break;
+ case TS_ST_WAIT_PDCH_DEACT:
+ ctr = BTS_CTR_TS_BORKEN_FROM_WAIT_PDCH_DEACT;
+ break;
+ case TS_ST_IN_USE:
+ ctr = BTS_CTR_TS_BORKEN_FROM_IN_USE;
+ break;
+ case TS_ST_BORKEN:
+ ctr = BTS_CTR_TS_BORKEN_FROM_BORKEN;
+ break;
+ default:
+ ctr = BTS_CTR_TS_BORKEN_FROM_UNKNOWN;
+ }
+ rate_ctr_inc(&ts->trx->bts->bts_ctrs->ctr[ctr]);
+ osmo_stat_item_inc(ts->trx->bts->bts_statg->items[BTS_STAT_TS_BORKEN], 1);
+}
+
static void ts_fsm_borken(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
@@ -670,17 +703,29 @@ static void ts_fsm_borken(struct osmo_fsm_inst *fi, uint32_t event, void *data)
case TS_EV_PDCH_ACT_ACK:
case TS_EV_PDCH_ACT_NACK:
- /* Late PDCH activation ACK/NACK is not a crime.
- * Just process them as normal. */
- ts_fsm_wait_pdch_act(fi, event, data);
- return;
+ {
+ struct gsm_bts_trx_ts *ts = ts_fi_ts(fi);
+ struct gsm_bts *bts = ts->trx->bts;
+ /* Late PDCH activation ACK/NACK is not a crime.
+ * Just process them as normal. */
+ rate_ctr_inc(&bts->bts_ctrs->ctr[BTS_CTR_TS_BORKEN_EV_PDCH_ACT_ACK_NACK]);
+ osmo_stat_item_dec(bts->bts_statg->items[BTS_STAT_TS_BORKEN], 1);
+ ts_fsm_wait_pdch_act(fi, event, data);
+ return;
+ }
case TS_EV_PDCH_DEACT_ACK:
case TS_EV_PDCH_DEACT_NACK:
- /* Late PDCH deactivation ACK/NACK is also not a crime.
- * Just process them as normal. */
- ts_fsm_wait_pdch_deact(fi, event, data);
- return;
+ {
+ struct gsm_bts_trx_ts *ts = ts_fi_ts(fi);
+ struct gsm_bts *bts = ts->trx->bts;
+ /* Late PDCH deactivation ACK/NACK is also not a crime.
+ * Just process them as normal. */
+ rate_ctr_inc(&bts->bts_ctrs->ctr[BTS_CTR_TS_BORKEN_EV_PDCH_DEACT_ACK_NACK]);
+ osmo_stat_item_dec(bts->bts_statg->items[BTS_STAT_TS_BORKEN], 1);
+ ts_fsm_wait_pdch_deact(fi, event, data);
+ return;
+ }
default:
OSMO_ASSERT(false);
@@ -733,6 +778,15 @@ static void ts_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data
}
}
+static void ts_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
+{
+ struct gsm_bts_trx_ts *ts = ts_fi_ts(fi);
+ if (ts->fi->state == TS_ST_BORKEN) {
+ rate_ctr_inc(&ts->trx->bts->bts_ctrs->ctr[BTS_CTR_TS_BORKEN_EV_TEARDOWN]);
+ osmo_stat_item_dec(ts->trx->bts->bts_statg->items[BTS_STAT_TS_BORKEN], 1);
+ }
+}
+
#define S(x) (1 << (x))
static const struct osmo_fsm_state ts_fsm_states[] = {
@@ -830,6 +884,7 @@ static const struct osmo_fsm_state ts_fsm_states[] = {
},
[TS_ST_BORKEN] = {
.name = "BORKEN",
+ .onenter = ts_fsm_borken_onenter,
.action = ts_fsm_borken,
.in_event_mask = 0
| S(TS_EV_LCHAN_REQUESTED)
@@ -875,6 +930,7 @@ static struct osmo_fsm ts_fsm = {
| S(TS_EV_RSL_DOWN)
,
.allstate_action = ts_fsm_allstate,
+ .cleanup = ts_fsm_cleanup,
};
/* Return true if any lchans are waiting for this timeslot to become a specific PCHAN. If target_pchan is