aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2021-05-19 02:28:26 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2021-05-31 05:20:03 +0000
commit27c07690d9ece5c8e752a40b5276934bfa1326e3 (patch)
treebe095a148a490b92610cb4b75518cc5e0ba60c0e
parente262919892ab58fe122ae203d745bd2b6a45626e (diff)
replace ts_*_for_each_lchan() with ts_for_n_lchans()
So far we have a couple of macros iterating a specific number of lchans, depending on dynamic timeslot state etc. With addition of VAMOS lchans, this would become more complex and bloated. Instead of separate iteration macros for each situation, only have one that takes a number of lchans as argument. That allows to more clearly pick the number of lchans, especially for non-trivial VAMOS scenarios. Related: SYS#5315 OS#4940 Change-Id: Ib2c6baf73a81ba371143ba5adc912aef6f79238d
-rw-r--r--include/osmocom/bsc/gsm_data.h39
-rw-r--r--src/osmo-bsc/abis_rsl.c2
-rw-r--r--src/osmo-bsc/bsc_vty.c6
-rw-r--r--src/osmo-bsc/bts_trx.c2
-rw-r--r--src/osmo-bsc/chan_alloc.c10
-rw-r--r--src/osmo-bsc/handover_decision_2.c2
-rw-r--r--src/osmo-bsc/handover_logic.c2
-rw-r--r--src/osmo-bsc/lchan_select.c4
-rw-r--r--src/osmo-bsc/timeslot_fsm.c12
-rw-r--r--tests/handover/handover_test.c3
10 files changed, 28 insertions, 54 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 7bfe3abe6..d128db7a9 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -554,41 +554,20 @@ struct gsm_encr {
bsc_subscr_name(lchan && lchan->conn ? lchan->conn->bsub : NULL), \
## args)
-/* Iterate lchans that have an FSM allocated based based on explicit pchan kind
- * (GSM_PCHAN_* constant).
- * Remark: PDCH related lchans are not handled in BSC but in PCU, so trying to
- * iterate through GSM_PCHAN_PDCH is considered a void loop.
- */
-#define ts_as_pchan_for_each_lchan(lchan, ts, as_pchan) \
- for (lchan = (ts)->lchan; \
- ((lchan - (ts)->lchan) < ARRAY_SIZE((ts)->lchan)) \
- && lchan->fi \
- && lchan->nr < pchan_subslots(as_pchan); \
- lchan++)
-
-/* Iterate lchans that have an FSM allocated based on current PCHAN
- * mode set in \ref ts.
+/* Iterate at most N lchans of the given timeslot.
* usage:
* struct gsm_lchan *lchan;
* struct gsm_bts_trx_ts *ts = get_some_timeslot();
- * ts_for_each_lchan(lchan, ts) {
- * LOGPLCHAN(DMAIN, LOGL_DEBUG, "hello world\n");
+ * ts_for_n_lchans(lchan, ts, 3) {
+ * LOG_LCHAN(lchan, LOGL_DEBUG, "hello world\n");
* }
*/
-#define ts_for_each_lchan(lchan, ts) ts_as_pchan_for_each_lchan(lchan, ts, (ts)->pchan_is)
-
-/* Iterate over all possible lchans available that have an FSM allocated based
- * on PCHAN \ref ts (dynamic) configuration.
- * Iterate all lchan instances set up by this \ref ts type, including those
- * lchans currently disabled or in process of being enabled (e.g. due to dynamic
- * timeslot in switchover). Compare ts_for_each_lchan(), which iterates only the
- * enabled lchans.
- * For example, it is useful in case dynamic timeslot \ref ts is in process of
- * switching from configuration PDCH (no lchans) to TCH_F (1 lchan), where
- * pchan_is is still set to PDCH but \ref ts may contain already an \ref lchan
- * of type TCH_F which initiated the request to switch the \ts configuration.
- */
-#define ts_for_each_potential_lchan(lchan, ts) ts_as_pchan_for_each_lchan(lchan, ts, (ts)->pchan_on_init)
+#define ts_for_n_lchans(lchan, ts, N) \
+ for (lchan = (ts)->lchan; \
+ ((lchan - (ts)->lchan) < ARRAY_SIZE((ts)->lchan)) \
+ && lchan->fi \
+ && ((lchan - (ts)->lchan) < (N)); \
+ lchan++)
enum lchan_activate_for {
ACTIVATE_FOR_NONE,
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 71bf0bbeb..0436bf594 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1606,7 +1606,7 @@ static struct gsm_lchan *get_any_lchan(struct gsm_bts *bts)
trx = gsm_bts_trx_num(bts, trx_nr);
for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
ts = &trx->ts[ts_nr];
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_primary_lchans) {
if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H) {
if (bts->chan_alloc_reverse) {
if (lchan->fi->state == LCHAN_ST_ESTABLISHED)
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 6252d06e7..6f4e2ecf4 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1691,7 +1691,7 @@ static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,
bool all)
{
struct gsm_lchan *lchan;
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan_state_is(lchan, LCHAN_ST_UNUSED) && all == false)
continue;
dump_cb(vty, lchan);
@@ -1997,7 +1997,7 @@ static struct gsm_lchan *find_used_voice_lchan(struct vty *vty, int random_idx)
if (ts->fi->state != TS_ST_IN_USE)
continue;
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan_state_is(lchan, LCHAN_ST_ESTABLISHED)
&& (lchan->type == GSM_LCHAN_TCH_F
|| lchan->type == GSM_LCHAN_TCH_H)) {
@@ -6160,7 +6160,7 @@ static int lchan_act_trx(struct vty *vty, struct gsm_bts_trx *trx, int activate)
for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
ts = &trx->ts[ts_nr];
- ts_for_each_potential_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
switch (ts->pchan_on_init) {
case GSM_PCHAN_SDCCH8_SACCH8C:
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
diff --git a/src/osmo-bsc/bts_trx.c b/src/osmo-bsc/bts_trx.c
index 1dfca9565..64c7985e5 100644
--- a/src/osmo-bsc/bts_trx.c
+++ b/src/osmo-bsc/bts_trx.c
@@ -267,7 +267,7 @@ int trx_count_free_ts(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan)
if (ts->pchan_is != pchan)
continue;
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_primary_lchans) {
if (lchan_state_is(lchan, LCHAN_ST_UNUSED))
count++;
}
diff --git a/src/osmo-bsc/chan_alloc.c b/src/osmo-bsc/chan_alloc.c
index 3569d4eaa..402ca4603 100644
--- a/src/osmo-bsc/chan_alloc.c
+++ b/src/osmo-bsc/chan_alloc.c
@@ -73,15 +73,7 @@ void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts)
pl->total++;
}
- /* Count allocated logical channels.
- * Note: A GSM_PCHAN_TCH_F_TCH_H_PDCH can be switched
- * to a single TCH/F or to two TCH/H. So when it's in
- * the TCH/H mode, total number of available channels
- * is 1 more than when it's in the TCH/F mode.
- * I.e. "total" count will fluctuate depending on
- * whether GSM_PCHAN_TCH_F_TCH_H_PDCH timeslot is
- * in TCH/F or TCH/H (or in NONE/PDCH) mode. */
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_primary_lchans) {
/* don't even count CBCH slots in total */
if (lchan->type == GSM_LCHAN_CBCH)
continue;
diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
index 84ddfa444..34bd99a21 100644
--- a/src/osmo-bsc/handover_decision_2.c
+++ b/src/osmo-bsc/handover_decision_2.c
@@ -171,7 +171,7 @@ static unsigned int ts_usage_count(struct gsm_bts_trx_ts *ts)
{
struct gsm_lchan *lchan;
unsigned int count = 0;
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan_state_is(lchan, LCHAN_ST_ESTABLISHED))
count++;
}
diff --git a/src/osmo-bsc/handover_logic.c b/src/osmo-bsc/handover_logic.c
index c0ed10dc4..1e1b6c319 100644
--- a/src/osmo-bsc/handover_logic.c
+++ b/src/osmo-bsc/handover_logic.c
@@ -112,7 +112,7 @@ int bts_handover_count(struct gsm_bts *bts, int ho_scopes)
if (!nm_is_running(&ts->mo.nm_state))
continue;
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (!lchan->conn)
continue;
if (!lchan->conn->ho.fi)
diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c
index b494f023e..dba3c3aef 100644
--- a/src/osmo-bsc/lchan_select.c
+++ b/src/osmo-bsc/lchan_select.c
@@ -65,6 +65,7 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
}
for (j = start; j != stop; j += dir) {
+ int lchans_as_pchan;
ts = &trx->ts[j];
if (!ts_is_usable(ts))
continue;
@@ -84,7 +85,8 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
}
/* TS is (going to be) in desired pchan mode. Go ahead and check for an available lchan. */
- ts_as_pchan_for_each_lchan(lchan, ts, as_pchan) {
+ lchans_as_pchan = pchan_subslots(as_pchan);
+ ts_for_n_lchans(lchan, ts, lchans_as_pchan) {
if (lchan->fi->state == LCHAN_ST_UNUSED) {
LOGPLCHANALLOC("%s ss=%d is available%s\n",
gsm_ts_and_pchan_name(ts), lchan->nr,
diff --git a/src/osmo-bsc/timeslot_fsm.c b/src/osmo-bsc/timeslot_fsm.c
index 4fe670fea..001319ee5 100644
--- a/src/osmo-bsc/timeslot_fsm.c
+++ b/src/osmo-bsc/timeslot_fsm.c
@@ -112,7 +112,7 @@ static int ts_count_active_lchans(struct gsm_bts_trx_ts *ts)
struct gsm_lchan *lchan;
int count = 0;
- ts_for_each_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan->fi->state == LCHAN_ST_UNUSED)
continue;
count++;
@@ -125,7 +125,7 @@ static void ts_lchans_dispatch(struct gsm_bts_trx_ts *ts, int lchan_state, uint3
{
struct gsm_lchan *lchan;
- ts_for_each_potential_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan_state >= 0
&& !lchan_state_is(lchan, lchan_state))
continue;
@@ -137,7 +137,7 @@ static void ts_terminate_lchan_fsms(struct gsm_bts_trx_ts *ts)
{
struct gsm_lchan *lchan;
- ts_for_each_potential_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
osmo_fsm_inst_term(lchan->fi, OSMO_FSM_TERM_REQUEST, NULL);
}
}
@@ -146,7 +146,7 @@ static int ts_lchans_waiting(struct gsm_bts_trx_ts *ts)
{
struct gsm_lchan *lchan;
int count = 0;
- ts_for_each_potential_lchan(lchan, ts)
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible)
if (lchan->fi->state == LCHAN_ST_WAIT_TS_READY)
count++;
return count;
@@ -565,7 +565,7 @@ static void ts_fsm_in_use_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
ts->pdch_act_allowed = true;
/* For static TS, check validity. For dyn TS, figure out which PCHAN this should become. */
- ts_for_each_potential_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan_state_is(lchan, LCHAN_ST_UNUSED))
continue;
@@ -952,7 +952,7 @@ static struct osmo_fsm ts_fsm = {
bool ts_is_lchan_waiting_for_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config *target_pchan)
{
struct gsm_lchan *lchan;
- ts_for_each_potential_lchan(lchan, ts) {
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan->fi->state == LCHAN_ST_WAIT_TS_READY) {
if (target_pchan)
*target_pchan = gsm_pchan_by_lchan_type(lchan->type);
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index 006e7910c..e65392038 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -463,7 +463,8 @@ static void lchan_clear(struct gsm_lchan *lchan)
static void ts_clear(struct gsm_bts_trx_ts *ts)
{
struct gsm_lchan *lchan;
- ts_for_each_lchan(lchan, ts) {
+
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
if (lchan_state_is(lchan, LCHAN_ST_UNUSED))
continue;
lchan_clear(lchan);