aboutsummaryrefslogtreecommitdiffstats
path: root/src/common/rsl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/rsl.c')
-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 {