diff options
Diffstat (limited to 'src/host/trxcon/sched_trx.c')
-rw-r--r-- | src/host/trxcon/sched_trx.c | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c index 120098bd..2142119f 100644 --- a/src/host/trxcon/sched_trx.c +++ b/src/host/trxcon/sched_trx.c @@ -406,6 +406,42 @@ int sched_trx_activate_lchan(struct trx_ts *ts, enum trx_lchan_type chan) return 0; } +static void sched_trx_reset_lchan(struct trx_lchan_state *lchan) +{ + /* Prevent NULL-pointer deference */ + OSMO_ASSERT(lchan != NULL); + + /* Reset internal state variables */ + lchan->rx_burst_mask = 0x00; + lchan->tx_burst_mask = 0x00; + lchan->rx_first_fn = 0; + + /* Free burst memory */ + talloc_free(lchan->rx_bursts); + talloc_free(lchan->tx_bursts); + + lchan->rx_bursts = NULL; + lchan->tx_bursts = NULL; + + /* Forget the current prim */ + sched_prim_drop(lchan); + + /* TCH specific variables */ + if (CHAN_IS_TCH(lchan->type)) { + lchan->dl_ongoing_facch = 0; + lchan->ul_ongoing_facch = 0; + + lchan->rsl_cmode = 0x00; + lchan->tch_mode = 0x00; + + /* Reset AMR state */ + memset(&lchan->amr, 0x00, sizeof(lchan->amr)); + } + + /* Reset ciphering state */ + memset(&lchan->a5, 0x00, sizeof(lchan->a5)); +} + int sched_trx_deactivate_lchan(struct trx_ts *ts, enum trx_lchan_type chan) { struct trx_lchan_state *lchan; @@ -424,16 +460,10 @@ int sched_trx_deactivate_lchan(struct trx_ts *ts, enum trx_lchan_type chan) LOGP(DSCH, LOGL_DEBUG, "Deactivating lchan=%s " "on ts=%d\n", trx_lchan_desc[chan].name, ts->index); - /* Free memory */ - talloc_free(lchan->rx_bursts); - talloc_free(lchan->tx_bursts); - - /* Reset ciphering state */ - memset(&lchan->a5, 0x00, sizeof(lchan->a5)); - - /* Forget the current prim */ - sched_prim_drop(lchan); + /* Reset internal state, free memory */ + sched_trx_reset_lchan(lchan); + /* Update activation flag */ lchan->active = 0; return 0; @@ -451,12 +481,14 @@ void sched_trx_deactivate_all_lchans(struct trx_ts *ts) for (i = 0; i < len; i++) { lchan = ts->lchans + i; - talloc_free(lchan->rx_bursts); - talloc_free(lchan->tx_bursts); + /* Omit inactive channels */ + if (!lchan->active) + continue; - /* Forget the current prim */ - sched_prim_drop(lchan); + /* Reset internal state, free memory */ + sched_trx_reset_lchan(lchan); + /* Update activation flag */ lchan->active = 0; } } |