aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2021-05-22 16:29:35 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2021-05-31 05:20:02 +0000
commitc33eb8d56943b8981523754b081967e6ff5f245d (patch)
tree65c63d529525b7afd92e87c17e9544f5c4c8e4fa /src
parent5df7e771a86f3cdd1c7a6a6f71f9ad6f3465674f (diff)
allow explixit TSC Set and TSC on chan activ / modif / assignment
Activating / modifying to a VAMOS mode will require picking specific TSC Set / TSC. It is a bad idea to pick the TSC in each message encoding function, rather make this choice centrally. So far we pick the training sequence code to use based on the timeslot configuration, and this TSC is determined only upon encoding the RSL messages. Instead, pick the TSC to use upon the initial lchan activation / modification request; store this in the request structs and pass through the activation / modification code paths. For VAMOS modes, we also need to pick a TSC Set. Do so also upon activ / modif request. Note that the TSC Set is not yet applied in this patch, it will be applied in upcoming VAMOS patches. The activ / modif request may pass -1 for tsc_set and/or tsc to indicate no specific choice of TSC Set and TSC, resulting in the same behavior as before this patch. For example, lchan->activate.info.tsc* may be passed as -1. The exact choice for tsc_set and tsc is then stored in lchan->activate.tsc*, i.e. one level up (the .info sub-struct is considered as immutable input args). The lchan->activate.tsc* are the values actually encoded in RSL messages. After the ACK, the lchan->activate.tsc* is stored in lchan->tsc* to indicate the TSC actually in use. Same for modif. Note that in 3GPP TS 45.002, the TSC Set are numbered 1 to 4, while the TSC are numbered 0 to 7. On the wire, though, TSC Set is sent as 0 to 3 value. This is a weird discrepancy, odd choice made by the spec authors. For conformance with the spec wording, I decided to pass the TSC Set number as a 1-4 ranged value, and only convert it to the 0-3 on-the-wire format upon message encoding. So log messages and VTY output will indicate the first TSC Set as "1", but the first TSC as "0", as defined in 3GPP TS 45.002, even if that is somewhat weird. Related: SYS#5315 OS#4940 Change-Id: Ic665125255d7354f5499d10dda1dd866ab243d24
Diffstat (limited to 'src')
-rw-r--r--src/osmo-bsc/abis_rsl.c4
-rw-r--r--src/osmo-bsc/assignment_fsm.c13
-rw-r--r--src/osmo-bsc/bsc_vty.c7
-rw-r--r--src/osmo-bsc/gsm_04_08_rr.c6
-rw-r--r--src/osmo-bsc/lchan_fsm.c29
-rw-r--r--src/osmo-bsc/lcs_loc_req.c2
6 files changed, 48 insertions, 13 deletions
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index c2a20053b..71bf0bbeb 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -528,7 +528,7 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
}
memset(&cd, 0, sizeof(cd));
- gsm48_lchan2chan_desc(&cd, lchan, gsm_ts_tsc(lchan->ts));
+ gsm48_lchan2chan_desc(&cd, lchan, lchan->activate.tsc);
msg = rsl_msgb_alloc();
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
@@ -1801,7 +1801,7 @@ int rsl_tx_imm_assignment(struct gsm_lchan *lchan)
ia->proto_discr = GSM48_PDISC_RR;
ia->msg_type = GSM48_MT_RR_IMM_ASS;
ia->page_mode = GSM48_PM_SAME;
- gsm48_lchan2chan_desc(&ia->chan_desc, lchan, gsm_ts_tsc(lchan->ts));
+ gsm48_lchan2chan_desc(&ia->chan_desc, lchan, lchan->tsc);
/* use request reference extracted from CHAN_RQD */
memcpy(&ia->req_ref, lchan->rqd_ref, sizeof(ia->req_ref));
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index b96dbb3c3..81de9588e 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -439,7 +439,7 @@ static bool reuse_existing_lchan(struct gsm_subscriber_connection *conn)
}
static int _reassignment_request(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan,
- enum gsm_chan_t new_lchan_type)
+ enum gsm_chan_t new_lchan_type, int tsc_set, int tsc)
{
struct gsm_subscriber_connection *conn = lchan->conn;
struct assignment_request req = {
@@ -450,6 +450,8 @@ static int _reassignment_request(enum assign_for assign_for, struct gsm_lchan *l
.n_ch_mode_rate = 1,
.ch_mode_rate_list = { lchan->current_ch_mode_rate },
.target_lchan = to_lchan,
+ .tsc_set = tsc_set,
+ .tsc = tsc,
};
if (to_lchan)
@@ -469,15 +471,16 @@ static int _reassignment_request(enum assign_for assign_for, struct gsm_lchan *l
return osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_ASSIGNMENT_START, &req);
}
-int reassignment_request_to_lchan(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan)
+int reassignment_request_to_lchan(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan,
+ int tsc_set, int tsc)
{
- return _reassignment_request(assign_for, lchan, to_lchan, 0);
+ return _reassignment_request(assign_for, lchan, to_lchan, 0, tsc_set, tsc);
}
int reassignment_request_to_chan_type(enum assign_for assign_for, struct gsm_lchan *lchan,
enum gsm_chan_t new_lchan_type)
{
- return _reassignment_request(assign_for, lchan, NULL, new_lchan_type);
+ return _reassignment_request(assign_for, lchan, NULL, new_lchan_type, -1, -1);
}
void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
@@ -635,6 +638,8 @@ static void assignment_fsm_wait_lchan_active_onenter(struct osmo_fsm_inst *fi, u
.re_use_mgw_endpoint_from_lchan = conn->lchan,
.ta = conn->lchan->last_ta,
.ta_known = true,
+ .tsc_set = req->tsc_set,
+ .tsc = req->tsc,
};
lchan_activate(conn->assignment.new_lchan, &activ_info);
}
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 89f8c0ee6..ec625c426 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1876,7 +1876,7 @@ static int trigger_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_
vty_out(vty, "Error: cannot find free lchan of type %s%s",
gsm_lchant_name(from_lchan->type), VTY_NEWLINE);
}
- if (reassignment_request_to_lchan(ACTIVATE_FOR_VTY, from_lchan, to_lchan)) {
+ if (reassignment_request_to_lchan(ACTIVATE_FOR_VTY, from_lchan, to_lchan, -1, -1)) {
vty_out(vty, "Error: not allowed to start assignment for %s%s",
gsm_lchan_name(from_lchan), VTY_NEWLINE);
return CMD_WARNING;
@@ -6044,7 +6044,10 @@ DEFUN(pdch_act, pdch_act_cmd,
/* Activate / Deactivate a single lchan with a specific codec mode */
static int lchan_act_single(struct vty *vty, struct gsm_lchan *lchan, const char *codec_str, int amr_mode, int activate)
{
- struct lchan_activate_info info = { };
+ struct lchan_activate_info info = {
+ .tsc_set = -1,
+ .tsc = -1,
+ };
uint16_t amr_modes[8] =
{ GSM0808_SC_CFG_AMR_4_75, GSM0808_SC_CFG_AMR_4_75_5_90_7_40_12_20, GSM0808_SC_CFG_AMR_5_90,
GSM0808_SC_CFG_AMR_6_70, GSM0808_SC_CFG_AMR_7_40, GSM0808_SC_CFG_AMR_7_95, GSM0808_SC_CFG_AMR_10_2,
diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c
index 153f1027f..c0efafb4d 100644
--- a/src/osmo-bsc/gsm_04_08_rr.c
+++ b/src/osmo-bsc/gsm_04_08_rr.c
@@ -618,7 +618,7 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *current_lchan, struct gsm_lchan *new
* the chan_desc. But as long as multi-slot configurations
* are not used we seem to be fine.
*/
- gsm48_lchan2chan_desc(&ass->chan_desc, new_lchan, gsm_ts_tsc(new_lchan->ts));
+ gsm48_lchan2chan_desc(&ass->chan_desc, new_lchan, new_lchan->tsc);
ass->power_command = power_command;
/* Cell Channel Description (freq. hopping), TV (see 3GPP TS 44.018, 10.5.2.1b) */
@@ -681,6 +681,7 @@ int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode)
struct gsm48_chan_mode_modify *cmm =
(struct gsm48_chan_mode_modify *) msgb_put(msg, sizeof(*cmm));
struct gsm_bts *bts = lchan->ts->trx->bts;
+ uint8_t tsc;
DEBUGP(DRR, "-> CHANNEL MODE MODIFY mode=0x%02x\n", mode);
@@ -690,7 +691,8 @@ int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode)
/* fill the channel information element, this code
* should probably be shared with rsl_rx_chan_rqd() */
- gsm48_lchan2chan_desc(&cmm->chan_desc, lchan, gsm_ts_tsc(lchan->ts));
+ tsc = (lchan->modify.tsc >= 0) ? lchan->modify.tsc : gsm_ts_tsc(lchan->ts);
+ gsm48_lchan2chan_desc(&cmm->chan_desc, lchan, tsc);
cmm->mode = mode;
/* in case of multi rate we need to attach a config */
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index a3438f758..1610ac303 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -457,6 +457,8 @@ static void lchan_reset(struct gsm_lchan *lchan)
.last_error = lchan->last_error,
.release.rr_cause = GSM48_RR_CAUSE_NORMAL,
+
+ .tsc_set = 1,
};
}
@@ -713,6 +715,15 @@ static void lchan_fsm_wait_activ_ack_onenter(struct osmo_fsm_inst *fi, uint32_t
lchan->encr = lchan->activate.info.encr;
+ if (lchan->activate.info.tsc_set > 0)
+ lchan->activate.tsc_set = lchan->activate.info.tsc_set;
+ else
+ lchan->activate.tsc_set = 1;
+
+ /* Use the TSC provided in the modification request, if any. Otherwise use the timeslot's configured
+ * TSC. */
+ lchan->activate.tsc = (lchan->activate.info.tsc >= 0) ? lchan->activate.info.tsc : gsm_ts_tsc(lchan->ts);
+
rc = rsl_tx_chan_activ(lchan, act_type, ho_ref);
if (rc) {
lchan_fail_to(LCHAN_ST_UNUSED, "Tx Chan Activ failed: %s (%d)", strerror(-rc), rc);
@@ -786,6 +797,8 @@ static void lchan_fsm_post_activ_ack(struct osmo_fsm_inst *fi)
lchan->current_ch_mode_rate = lchan->activate.info.ch_mode_rate;
lchan->current_mr_conf = lchan->activate.mr_conf_filtered;
+ lchan->tsc_set = lchan->activate.tsc_set;
+ lchan->tsc = lchan->activate.tsc;
LOG_LCHAN(lchan, LOGL_INFO, "Rx Activ ACK %s\n",
gsm48_chan_mode_name(lchan->current_ch_mode_rate.chan_mode));
@@ -958,6 +971,8 @@ static void lchan_fsm_wait_rsl_chan_mode_modify_ack(struct osmo_fsm_inst *fi, ui
/* The Channel Mode Modify was ACKed, now the requested values become the accepted and used values. */
lchan->current_ch_mode_rate = lchan->modify.info.ch_mode_rate;
lchan->current_mr_conf = lchan->modify.mr_conf_filtered;
+ lchan->tsc_set = lchan->modify.tsc_set;
+ lchan->tsc = lchan->modify.tsc;
if (lchan->modify.info.requires_voice_stream
&& !lchan->fi_rtp) {
@@ -1117,15 +1132,25 @@ static void lchan_fsm_established(struct osmo_fsm_inst *fi, uint32_t event, void
}
}
+ if (lchan->modify.info.tsc_set > 0)
+ lchan->modify.tsc_set = lchan->modify.info.tsc_set;
+ else
+ lchan->modify.tsc_set = 1;
+
+ /* Use the TSC provided in the modification request, if any. Otherwise use the timeslot's configured
+ * TSC. */
+ lchan->modify.tsc = (lchan->modify.info.tsc >= 0) ? lchan->modify.info.tsc : gsm_ts_tsc(lchan->ts);
+
LOG_LCHAN(lchan, LOGL_INFO,
- "Modification requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s\n",
+ "Modification requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s tsc=%d/%u\n",
lchan_modify_for_name(lchan->modify.info.modify_for),
lchan->modify.info.requires_voice_stream ? "yes" : "no",
lchan->modify.info.requires_voice_stream ?
(use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new")
: "none",
gsm_lchant_name(lchan->type),
- gsm48_chan_mode_name(lchan->modify.info.ch_mode_rate.chan_mode));
+ gsm48_chan_mode_name(lchan->modify.info.ch_mode_rate.chan_mode),
+ lchan->modify.tsc_set, lchan->modify.tsc);
lchan_fsm_state_chg(LCHAN_ST_WAIT_RR_CHAN_MODE_MODIFY_ACK);
return;
diff --git a/src/osmo-bsc/lcs_loc_req.c b/src/osmo-bsc/lcs_loc_req.c
index ef9ee278a..ee85c91e7 100644
--- a/src/osmo-bsc/lcs_loc_req.c
+++ b/src/osmo-bsc/lcs_loc_req.c
@@ -369,7 +369,7 @@ static void lcs_loc_req_handover_performed(struct lcs_loc_req *lcs_loc_req)
.cause = BSSLAP_CAUSE_INTRA_BSS_HO,
},
};
- gsm48_lchan2chan_desc(&apdu->reset.chan_desc, lchan, gsm_ts_tsc(lchan->ts));
+ gsm48_lchan2chan_desc(&apdu->reset.chan_desc, lchan, lchan->tsc);
}
lcs_loc_req_send(lcs_loc_req, &bsslap);