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