aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-05-05 19:56:06 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-05-05 20:35:58 +0200
commitc0b7193baeafe7baf646334869495cb15e16c0a6 (patch)
treec6be9709892a3c53681fb38a8b1b53cb1c385981
parent94b093bffdc1fdf6f682897b263252e101871fcc (diff)
dyn TS: clear TCH state upon reconnecting as PDCH
For ip.access style TCH/F_PDCH, this fixes switch-back to PDCH in case the TCH use employed encryption. For Osmocom style TCH/F_TCH/H_PDCH, do the same, purely out of sanity. Roughly the same should already be happening during PDCH Chan Activ, but make sure to clear all these fields, so they are cleared even if IEs are missing. From both dyn TS code paths, call new clear_lchan_for_pdch_activ(), which clears the same fields that are normally overwritten by an RSL Chan Activ. Related: OS#3238 Change-Id: I8451039683b54bee910c97c5a3e6873e0ff1b160
-rw-r--r--src/common/rsl.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 1dc200d0..52eb5f48 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -871,6 +871,26 @@ static int encr_info2lchan(struct gsm_lchan *lchan,
return 0;
}
+/* Make sure no state from TCH use remains. */
+static void clear_lchan_for_pdch_activ(struct gsm_lchan *lchan)
+{
+ /* These values don't apply to PDCH, just clear them. Particularly the encryption must be
+ * cleared, or we would enable encryption on PDCH with parameters remaining from the TCH. */
+ lchan->ms_power = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, 0);
+ lchan->ms_power_ctrl.current = lchan->ms_power;
+ lchan->ms_power_ctrl.fixed = 0;
+ lchan->rsl_cmode = 0;
+ lchan->tch_mode = 0;
+ memset(&lchan->encr, 0, sizeof(lchan->encr));
+ memset(&lchan->ho, 0, sizeof(lchan->ho));
+ lchan->bs_power = 0;
+ lchan->ms_power = 0;
+ memset(&lchan->ms_power_ctrl, 0, sizeof(lchan->ms_power_ctrl));
+ lchan->rqd_ta = 0;
+ copy_sacch_si_to_lchan(lchan);
+ memset(&lchan->tch, 0, sizeof(lchan->tch));
+}
+
/*!
* Store the CHAN_ACTIV msg, connect the L1 timeslot in the proper type and
* then invoke rsl_rx_chan_activ() with msg.
@@ -882,7 +902,10 @@ static int dyn_ts_l1_reconnect(struct gsm_bts_trx_ts *ts, struct msgb *msg)
switch (ts->dyn.pchan_want) {
case GSM_PCHAN_TCH_F:
case GSM_PCHAN_TCH_H:
+ break;
case GSM_PCHAN_PDCH:
+ /* Only the first lchan matters for PDCH */
+ clear_lchan_for_pdch_activ(ts->lchan);
break;
default:
LOGP(DRSL, LOGL_ERROR,
@@ -2096,6 +2119,9 @@ static void rsl_rx_dyn_pdch(struct msgb *msg, bool pdch_act)
}
if (pdch_act) {
+ /* Clear TCH state. Only first lchan matters for PDCH */
+ clear_lchan_for_pdch_activ(ts->lchan);
+
/* First, disconnect the TCH channel, to connect PDTCH later */
rc = bts_model_ts_disconnect(ts);
} else {