Review at  https://gerrit.osmocom.org/6815

trxcon/scheduler: reset lchan state after deactivation

Let's assume that a logical channel, which was already in use,
is activated again for a new connection. As we don't reset the
state variables, such as burst masks or ciphering data, it may
cause an unexpected behaviour.

In order to avoid this, let's always reset the logical channel
state after deactivation.

Change-Id: I91e736a97cb05b167614cb488a00d847a9a859e0
---
M src/host/trxcon/sched_trx.c
1 file changed, 45 insertions(+), 13 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/15/6815/1

diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 120098b..2142119 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -406,6 +406,42 @@
        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 @@
        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 internal state, free memory */
+       sched_trx_reset_lchan(lchan);
 
-       /* Reset ciphering state */
-       memset(&lchan->a5, 0x00, sizeof(lchan->a5));
-
-       /* Forget the current prim */
-       sched_prim_drop(lchan);
-
+       /* Update activation flag */
        lchan->active = 0;
 
        return 0;
@@ -451,12 +481,14 @@
        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;
        }
 }

-- 
To view, visit https://gerrit.osmocom.org/6815
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I91e736a97cb05b167614cb488a00d847a9a859e0
Gerrit-PatchSet: 1
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <lafo...@gnumonks.org>

Reply via email to