This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
neels gerrit-no-reply at lists.osmocom.orgneels has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/24377 )
Change subject: add VAMOS secondary lchans to timeslot struct
......................................................................
add VAMOS secondary lchans to timeslot struct
So far there is a bunch of code setting a primary lchan in VAMOS mode.
This patch now adds the actual secondary "shadow" lchans that may be
combined with a primary lchan in VAMOS mode to form a multiplex.
VAMOS lchans are put in the same ts->lchan[] array that keeps the
primary lchans. They are at most two additional usable lchans (for a
TCH/H shadow) added to either TCH/F or TCH/H.
Keeping these in the same array allows looping over all lchans easily.
The ts->max_primary_lchans indicates the index of the first VAMOS shadow
lchan.
Related: SYS#5315 OS#4940
Change-Id: I928af99498bba488d317693f3144d4fccbbe9af3
---
M include/osmocom/bsc/gsm_data.h
M src/osmo-bsc/abis_rsl.c
M src/osmo-bsc/assignment_fsm.c
M src/osmo-bsc/gsm_data.c
M src/osmo-bsc/lchan_fsm.c
M src/osmo-bsc/timeslot_fsm.c
6 files changed, 152 insertions(+), 13 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/77/24377/1
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 8ce5a91..4690a2c 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -1041,8 +1041,11 @@
enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts);
uint8_t pchan_subslots(enum gsm_phys_chan_config pchan);
+uint8_t pchan_subslots_vamos(enum gsm_phys_chan_config pchan);
bool ts_is_tch(struct gsm_bts_trx_ts *ts);
+struct gsm_lchan *gsm_lchan_vamos_to_primary(const struct gsm_lchan *lchan_vamos, int idx);
+struct gsm_lchan *gsm_lchan_primary_to_vamos(const struct gsm_lchan *lchan_primary, int idx);
struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn);
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 476cc3a..e1d8a41 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1670,6 +1670,8 @@
* or unsuccessfully). */
static bool force_free_lchan_for_emergency(struct chan_rqd *rqd)
{
+ int i;
+
/* If the request is not about an emergency call, we may exit early, without doing anything. */
if (rqd->reason != GSM_CHREQ_REASON_EMERG)
return false;
@@ -1691,10 +1693,11 @@
* This will take a short amount of time. We need to come back and check regulary to see if we managed to
* free up another lchan. */
if (!rqd->release_lchan) {
+ struct gsm_lchan *release_lchan;
/* Pick any busy TCH/F or TCH/H lchan and inititate a channel
* release to make room for the incoming emergency call */
- rqd->release_lchan = get_any_lchan(rqd->bts);
- if (!rqd->release_lchan) {
+ rqd->release_lchan = release_lchan = get_any_lchan(rqd->bts);
+ if (!release_lchan) {
/* It can not happen that we first find out that there
* is no TCH/H or TCH/F available and at the same time
* we ware unable to find any busy TCH/H or TCH/F. In
@@ -1707,10 +1710,18 @@
LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,
"CHAN RQD/EMERGENCY-PRIORITY: inducing termination of lchan %s (state:%s) in favor of incoming EMERGENCY CALL!\n",
- gsm_lchan_name(rqd->release_lchan), osmo_fsm_inst_state_name(rqd->release_lchan->fi));
+ gsm_lchan_name(release_lchan), osmo_fsm_inst_state_name(release_lchan->fi));
- lchan_release(rqd->release_lchan, !!(rqd->release_lchan->conn), true, 0,
- gscon_last_eutran_plmn(rqd->release_lchan->conn));
+ lchan_release(release_lchan, !!(release_lchan->conn), true, 0,
+ gscon_last_eutran_plmn(release_lchan->conn));
+
+ /* Also release any overlapping VAMOS multiplexes on this lchan */
+ for (i = 0; i < 2; i++) {
+ struct gsm_lchan *lchan_vamos = gsm_lchan_primary_to_vamos(release_lchan, i);
+ if (lchan_vamos)
+ lchan_release(lchan_vamos, !!(lchan_vamos->conn), true, 0,
+ gscon_last_eutran_plmn(lchan_vamos->conn));
+ }
} else {
/* BTS is shutting down, give up... */
if (rqd->release_lchan->ts->fi->state == TS_ST_NOT_INITIALIZED)
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index d3bdaf1..854a906 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -637,6 +637,7 @@
.ta_known = true,
.tsc_set = req->tsc_set,
.tsc = req->tsc,
+ .vamos = conn->assignment.new_lchan->vamos.is_secondary,
};
lchan_activate(conn->assignment.new_lchan, &activ_info);
}
diff --git a/src/osmo-bsc/gsm_data.c b/src/osmo-bsc/gsm_data.c
index 159c016..85ce8bf 100644
--- a/src/osmo-bsc/gsm_data.c
+++ b/src/osmo-bsc/gsm_data.c
@@ -337,8 +337,9 @@
char *gsm_lchan_name_compute(void *ctx, const struct gsm_lchan *lchan)
{
struct gsm_bts_trx_ts *ts = lchan->ts;
- return talloc_asprintf(ctx, "(bts=%d,trx=%d,ts=%d,ss=%d)",
- ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr);
+ return talloc_asprintf(ctx, "(bts=%d,trx=%d,ts=%d,ss=%d%s)",
+ ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr,
+ lchan->vamos.is_secondary ? "-VAMOS" : "");
}
/* obtain the MO structure for a given object instance */
@@ -545,9 +546,13 @@
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
{
- /* Note: non-standard Osmocom style dyn TS PDCH mode chan_nr is only used within
- * rsl_tx_dyn_ts_pdch_act_deact(). */
- return gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan->nr);
+ uint8_t lchan_nr = lchan->nr;
+ /* The VAMOS lchans are behind the primary ones in the ts->lchan[] array. They keep their lchan->nr as in the
+ * array, but on the wire they are the "shadow" lchans for the primary lchans. For example, for TCH/F, there is
+ * a primary ts->lchan[0] and a VAMOS ts->lchan[1]. Still, the VAMOS lchan should send chan_nr = 0. */
+ if (lchan->vamos.is_secondary)
+ lchan_nr -= lchan->ts->max_primary_lchans;
+ return gsm_pchan2chan_nr(lchan->ts->pchan_is, lchan->ts->nr, lchan_nr);
}
static const uint8_t subslots_per_pchan[] = {
@@ -574,6 +579,30 @@
return subslots_per_pchan[pchan];
}
+static const uint8_t subslots_per_pchan_vamos[] = {
+ [GSM_PCHAN_NONE] = 0,
+ [GSM_PCHAN_CCCH] = 0,
+ [GSM_PCHAN_PDCH] = 0,
+ [GSM_PCHAN_CCCH_SDCCH4] = 0,
+ /* VAMOS: on a TCH/F, there may be a TCH/H shadow */
+ [GSM_PCHAN_TCH_F] = 2,
+ [GSM_PCHAN_TCH_H] = 2,
+ [GSM_PCHAN_SDCCH8_SACCH8C] = 0,
+ [GSM_PCHAN_CCCH_SDCCH4_CBCH] = 0,
+ [GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 0,
+ [GSM_PCHAN_TCH_F_TCH_H_PDCH] = 2,
+ [GSM_PCHAN_TCH_F_PDCH] = 2,
+};
+
+/* Return the maximum number of VAMOS secondary lchans that may be used in a timeslot of the given physical channel
+ * configuration. */
+uint8_t pchan_subslots_vamos(enum gsm_phys_chan_config pchan)
+{
+ if (pchan < 0 || pchan >= ARRAY_SIZE(subslots_per_pchan_vamos))
+ return 0;
+ return subslots_per_pchan_vamos[pchan];
+}
+
static bool pchan_is_tch(enum gsm_phys_chan_config pchan)
{
switch (pchan) {
@@ -590,6 +619,80 @@
return pchan_is_tch(ts->pchan_is);
}
+struct gsm_lchan *gsm_lchan_vamos_to_primary(const struct gsm_lchan *lchan_vamos, int idx)
+{
+ struct gsm_lchan *lchan_primary;
+ if (!lchan_vamos || !lchan_vamos->vamos.is_secondary)
+ return NULL;
+
+ lchan_primary = &lchan_vamos->ts->lchan[0];
+
+ switch (idx) {
+ case 0:
+ goto return_lchan_primary;
+ case 1:
+ break;
+ default:
+ return NULL;
+ }
+
+ switch (lchan_primary->type) {
+ case GSM_LCHAN_TCH_F:
+ return NULL;
+
+ default:
+ case GSM_LCHAN_TCH_H:
+ lchan_primary = &lchan_vamos->ts->lchan[1];
+ break;
+ }
+
+return_lchan_primary:
+ if (!lchan_primary->fi)
+ return NULL;
+ return lchan_primary;
+}
+
+struct gsm_lchan *gsm_lchan_primary_to_vamos(const struct gsm_lchan *lchan_primary, int idx)
+{
+ struct gsm_lchan *first_vamos_lchan;
+ struct gsm_lchan *lchan_vamos;
+ struct gsm_bts_trx_ts *ts;
+ if (!lchan_primary || lchan_primary->vamos.is_secondary)
+ return NULL;
+
+ ts = lchan_primary->ts;
+
+ first_vamos_lchan = &ts->lchan[ts->max_primary_lchans];
+ if (first_vamos_lchan == ts->lchan)
+ return NULL;
+
+ lchan_vamos = first_vamos_lchan;
+
+ switch (idx) {
+ case 0:
+ goto return_lchan_vamos;
+ case 1:
+ break;
+ default:
+ return NULL;
+ }
+
+ switch (lchan_vamos->type) {
+ case GSM_LCHAN_TCH_F:
+ return NULL;
+
+ default:
+ case GSM_LCHAN_TCH_H:
+ lchan_vamos = first_vamos_lchan + 1;
+ break;
+ }
+
+return_lchan_vamos:
+ if (!lchan_vamos->fi)
+ return NULL;
+ return lchan_vamos;
+}
+
struct gsm_bts *conn_get_bts(struct gsm_subscriber_connection *conn) {
if (!conn || !conn->lchan)
return NULL;
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index f20c147..f233a5a 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -649,7 +649,7 @@
lchan->bs_power = bts->bs_power_ctrl.bs_power_val_db / 2;
}
- if (info->ch_mode_rate.chan_mode == GSM48_CMODE_SPEECH_AMR) {
+ if (gsm48_chan_mode_to_non_vamos(info->ch_mode_rate.chan_mode) == GSM48_CMODE_SPEECH_AMR) {
if (lchan_mr_config(&lchan->activate.mr_conf_filtered, lchan, info->ch_mode_rate.s15_s0) < 0) {
lchan_fail("Can not generate multirate configuration IE\n");
return;
diff --git a/src/osmo-bsc/timeslot_fsm.c b/src/osmo-bsc/timeslot_fsm.c
index 8d340fb..d1f49a3 100644
--- a/src/osmo-bsc/timeslot_fsm.c
+++ b/src/osmo-bsc/timeslot_fsm.c
@@ -195,18 +195,39 @@
ts->max_primary_lchans = pchan_subslots(ts->pchan_is);
LOG_TS(ts, LOGL_DEBUG, "pchan_is=%s max_primary_lchans=%d max_lchans_possible=%d\n",
gsm_pchan_name(ts->pchan_is), ts->max_primary_lchans, ts->max_lchans_possible);
+ switch (ts->pchan_is) {
+ case GSM_PCHAN_TCH_F:
+ case GSM_PCHAN_TCH_H:
+ for (i = 0; i < ts->max_lchans_possible; i++) {
+ lchan = &ts->lchan[i];
+ if (i < ts->max_primary_lchans)
+ lchan->vamos.is_secondary = false;
+ else
+ lchan->vamos.is_secondary = true;
+ }
+ break;
+ default:
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible)
+ lchan->vamos.is_secondary = false;
+ break;
+ }
}
static void ts_setup_lchans(struct gsm_bts_trx_ts *ts)
{
int i, max_lchans;
+ int max_lchans_vamos;
ts->pchan_on_init = ts->pchan_from_config;
ts_fsm_update_id(ts);
max_lchans = pchan_subslots(ts->pchan_on_init);
- LOG_TS(ts, LOGL_DEBUG, "max lchans: %d\n", max_lchans);
- ts->max_lchans_possible = max_lchans;
+ if (osmo_bts_has_feature(&ts->trx->bts->features, BTS_FEAT_VAMOS))
+ max_lchans_vamos = pchan_subslots_vamos(ts->pchan_on_init);
+ else
+ max_lchans_vamos = 0;
+ LOG_TS(ts, LOGL_DEBUG, "max lchans: %d + %d VAMOS secondaries\n", max_lchans, max_lchans_vamos);
+ ts->max_lchans_possible = max_lchans + max_lchans_vamos;
ts->max_primary_lchans = 0;
for (i = 0; i < ts->max_lchans_possible; i++) {
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/24377
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I928af99498bba488d317693f3144d4fccbbe9af3
Gerrit-Change-Number: 24377
Gerrit-PatchSet: 1
Gerrit-Owner: neels <nhofmeyr at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210523/6287be3b/attachment.htm>