aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2021-01-27 23:45:33 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2021-02-05 20:24:43 +0100
commitb03e73f27b26449864296fdab84f6fb6e1978c45 (patch)
tree4142fa45f1ccccd8e9bb040def380fab1e758ec5
parent980a28fdcbf37b180159d02dd494e89e302b3481 (diff)
lchan activation: indicate whether TA is known
On lchan activation, we already know the Timing Advance in most situations: from the Channel Request RACH, or from a previous lchan in the same cell. Place this information in lchan->activate.info.ta. So far, the lchan->last_ta (until recently called rqd_ta) was used to store the initial TA for channel activation -- move the initial TA to lchan->activate.info.ta, for proper scoping. Only an inter-cell handover does not yet know a Timing Advance (until the Handover Detection RACH is received), so indicate activate.info.ta_known = false for that case. If ta_known is false, do not include an Access Delay IE in the Channel Activation message, ensuring that the BTS does not use an arbitrary TA that is likely inaccurate. The effect for OsmoBTS is that we will *not* start the downlink SACCH on channel activation for inter-cell handover, but will wait for a HO RACH first, and then use the correct TA when enabling downlink SACCH. Related: OS#4008 SYS#5192 Change-Id: I986bf93e8acd6aef7eaf63ac962480b680aa894f
-rw-r--r--include/osmocom/bsc/gsm_data.h2
-rw-r--r--src/osmo-bsc/abis_rsl.c18
-rw-r--r--src/osmo-bsc/assignment_fsm.c4
-rw-r--r--src/osmo-bsc/handover_fsm.c7
-rw-r--r--src/osmo-bsc/lchan_fsm.c8
5 files changed, 28 insertions, 11 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 6cb3cf0a4..edfae269e 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -571,6 +571,8 @@ struct lchan_activate_info {
/* During intra-BSC handover, we keep the MGW endpoint intact and just re-route to the new lchan. This
* activate_info is for the new lchan, the re_use_mgw_endpoint_from_lchan points at the old lchan. */
struct gsm_lchan *re_use_mgw_endpoint_from_lchan;
+ bool ta_known;
+ uint8_t ta;
};
struct gsm_lchan {
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index edffd356d..67e7d27bc 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -521,7 +521,6 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
struct msgb *msg;
int rc;
uint8_t *len;
- uint8_t ta;
struct rsl_ie_chan_mode cm;
struct gsm48_chan_desc cd;
@@ -541,12 +540,6 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
return rc;
}
- ta = lchan->last_ta;
-
- /* BS11 requires TA shifted by 2 bits */
- if (bts->type == GSM_BTS_TYPE_BS11)
- ta <<= 2;
-
memset(&cd, 0, sizeof(cd));
gsm48_lchan2chan_desc(&cd, lchan);
@@ -601,7 +594,13 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
if (bts->ms_power_ctrl.mode != GSM_PWR_CTRL_MODE_NONE)
msgb_tv_put(msg, RSL_IE_MS_POWER, lchan->ms_power);
- msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
+ if (lchan->activate.info.ta_known) {
+ uint8_t ta = lchan->activate.info.ta;
+ /* BS11 requires TA shifted by 2 bits */
+ if (bts->type == GSM_BTS_TYPE_BS11)
+ ta <<= 2;
+ msgb_tv_put(msg, RSL_IE_TIMING_ADVANCE, ta);
+ }
/* BS/MS Power Control Parameters (if supported by BTS model) */
add_power_control_params(msg, RSL_IE_BS_POWER_PARAM, lchan);
@@ -1756,13 +1755,14 @@ void abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts)
OSMO_ASSERT(lchan->rqd_ref);
*(lchan->rqd_ref) = rqd->ref;
- lchan->last_ta = rqd->ta;
LOG_LCHAN(lchan, LOGL_DEBUG, "MS: Channel Request: reason=%s ra=0x%02x ta=%d\n",
gsm_chreq_name(rqd->reason), rqd->ref.ra, rqd->ta);
info = (struct lchan_activate_info){
.activ_for = FOR_MS_CHANNEL_REQUEST,
.chan_mode = GSM48_CMODE_SIGN,
+ .ta = rqd->ta,
+ .ta_known = true,
};
lchan_activate(lchan, &info);
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index a8b6439df..39219a41e 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -487,6 +487,8 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
.requires_voice_stream = conn->assignment.requires_voice_stream,
.msc_assigned_cic = req->msc_assigned_cic,
.re_use_mgw_endpoint_from_lchan = conn->lchan,
+ .ta = conn->lchan->last_ta,
+ .ta_known = true,
};
osmo_fsm_inst_dispatch(conn->lchan->fi, LCHAN_EV_REQUEST_MODE_MODIFY, &info);
@@ -562,6 +564,8 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
.requires_voice_stream = conn->assignment.requires_voice_stream,
.msc_assigned_cic = req->msc_assigned_cic,
.re_use_mgw_endpoint_from_lchan = conn->lchan,
+ .ta = conn->lchan->last_ta,
+ .ta_known = true,
};
lchan_activate(conn->assignment.new_lchan, &info);
}
diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c
index b9caf045f..87359dc74 100644
--- a/src/osmo-bsc/handover_fsm.c
+++ b/src/osmo-bsc/handover_fsm.c
@@ -408,6 +408,13 @@ static void handover_start_intra_bsc(struct gsm_subscriber_connection *conn)
.s15_s0 = conn->lchan->activate.info.s15_s0,
};
+ /* For intra-cell handover, we know the accurate Timing Advance from the previous lchan. For inter-cell
+ * handover, no Timing Advance for the new cell is known, so leave it unset. */
+ if (ho->new_bts == bts) {
+ info.ta = conn->lchan->last_ta;
+ info.ta_known = true;
+ }
+
lchan_activate(ho->new_lchan, &info);
}
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index 7a75c0b96..9c7ecaf48 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -580,7 +580,6 @@ static void lchan_fsm_wait_ts_ready_onenter(struct osmo_fsm_inst *fi, uint32_t p
ms_power_dbm = ms_pwr_dbm(bts->band, old_lchan->ms_power);
lchan_update_ms_power_ctrl_level(lchan, ms_power_dbm >= 0 ? ms_power_dbm : bts->ms_max_power);
lchan->bs_power = old_lchan->bs_power;
- lchan->last_ta = old_lchan->last_ta;
} else {
lchan_update_ms_power_ctrl_level(lchan, bts->ms_max_power);
/* Upon last entering the UNUSED state, from lchan_reset():
@@ -702,8 +701,13 @@ static void lchan_fsm_wait_activ_ack_onenter(struct osmo_fsm_inst *fi, uint32_t
lchan->encr = lchan->activate.info.encr;
rc = rsl_tx_chan_activ(lchan, act_type, ho_ref);
- if (rc)
+ if (rc) {
lchan_fail_to(LCHAN_ST_UNUSED, "Tx Chan Activ failed: %s (%d)", strerror(-rc), rc);
+ return;
+ }
+
+ if (lchan->activate.info.ta_known)
+ lchan->last_ta = lchan->activate.info.ta;
}
static void lchan_fsm_post_activ_ack(struct osmo_fsm_inst *fi);