aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2022-06-06 01:43:28 +0600
committerfixeria <vyanitskiy@sysmocom.de>2022-06-30 16:36:41 +0000
commitc2928ac269a55d2ea1a6ae7984ba9065f8c41db0 (patch)
tree6b51e4a323ab6083589934f399063dd4e22c088f
parentff9d3a64dc8fec465140c244a816db22eea97b6b (diff)
lchan_select: allow different alloc order for assignment and handover
A follow-up patch implements a special channel allocation mode, which is only working for assignment (basically TCH selection for a voice call). This mode cannot be employed for initial CHANNEL REQUEST or handover due to the absence of an already established lchan. Adding this mode to the existing VTY command syntax would be confusing: channel allocator (ascending|desscending|dynamic) ^^^^^^^ so this patch extends the VTY syntax in a way that it becomes possible to configure different channel allocator modes for different cases: OsmoBSC(config-net-bts)# channel allocator mode ? set-all Set a single mode for all variants chan-req Channel allocation for CHANNEL REQUEST (RACH) assignment Channel allocation for assignment handover Channel allocation for handover The old command syntax, which is basically 'set-all', is kept for backwards compatibility, but marked as deprecated. Change-Id: I3ae73b36ee9433cc768376b56f0765e5f416162f Related: SYS#5460
-rw-r--r--doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus01-4trx.cfg2
-rw-r--r--doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-4trx.cfg2
-rw-r--r--doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-8trx.cfg2
-rw-r--r--doc/examples/osmo-bsc/ericsson/osmo-bsc.rbs2308.cfg2
-rw-r--r--doc/examples/osmo-bsc/osmo-bsc-4trx.cfg2
-rw-r--r--doc/examples/osmo-bsc/osmo-bsc.cfg2
-rw-r--r--doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg2
-rw-r--r--doc/manuals/chapters/bts-examples.adoc6
-rw-r--r--doc/manuals/chapters/chan_alloc.adoc21
-rw-r--r--include/osmocom/bsc/bts.h4
-rw-r--r--include/osmocom/bsc/lchan_select.h21
-rw-r--r--src/osmo-bsc/abis_rsl.c19
-rw-r--r--src/osmo-bsc/assignment_fsm.c4
-rw-r--r--src/osmo-bsc/bsc_vty.c7
-rw-r--r--src/osmo-bsc/bts_vty.c62
-rw-r--r--src/osmo-bsc/handover_decision_2.c4
-rw-r--r--src/osmo-bsc/handover_fsm.c9
-rw-r--r--src/osmo-bsc/lchan_select.c55
-rw-r--r--tests/ctrl/osmo-bsc-apply-config-file.cfg2
-rw-r--r--tests/ctrl/osmo-bsc-neigh-test.cfg4
-rw-r--r--tests/handover/handover_test.c3
-rw-r--r--tests/handover/test_dyn_ts_favor_static_ts_as_target.ho_vty2
-rw-r--r--tests/osmo-bsc.vty13
23 files changed, 185 insertions, 65 deletions
diff --git a/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus01-4trx.cfg b/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus01-4trx.cfg
index 68837caf7..8ef161990 100644
--- a/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus01-4trx.cfg
+++ b/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus01-4trx.cfg
@@ -39,7 +39,7 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator descending
+ channel allocator mode set-all descending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full
diff --git a/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-4trx.cfg b/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-4trx.cfg
index ae0b7db3a..7c9b84739 100644
--- a/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-4trx.cfg
+++ b/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-4trx.cfg
@@ -39,7 +39,7 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator descending
+ channel allocator mode set-all descending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full
diff --git a/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-8trx.cfg b/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-8trx.cfg
index ff0b27797..6db88b541 100644
--- a/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-8trx.cfg
+++ b/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-8trx.cfg
@@ -39,7 +39,7 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator descending
+ channel allocator mode set-all descending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full
diff --git a/doc/examples/osmo-bsc/ericsson/osmo-bsc.rbs2308.cfg b/doc/examples/osmo-bsc/ericsson/osmo-bsc.rbs2308.cfg
index f79d45735..a90cfa107 100644
--- a/doc/examples/osmo-bsc/ericsson/osmo-bsc.rbs2308.cfg
+++ b/doc/examples/osmo-bsc/ericsson/osmo-bsc.rbs2308.cfg
@@ -45,7 +45,7 @@ network
ms max power 33
cell reselection hysteresis 4
rxlev access min 0
- channel allocator descending
+ channel allocator mode set-all descending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full
diff --git a/doc/examples/osmo-bsc/osmo-bsc-4trx.cfg b/doc/examples/osmo-bsc/osmo-bsc-4trx.cfg
index 68d6a3829..206a3c7b8 100644
--- a/doc/examples/osmo-bsc/osmo-bsc-4trx.cfg
+++ b/doc/examples/osmo-bsc/osmo-bsc-4trx.cfg
@@ -17,7 +17,7 @@ network
cell reselection hysteresis 4
rxlev access min 0
radio-link-timeout 32
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
channel-description attach 1
diff --git a/doc/examples/osmo-bsc/osmo-bsc.cfg b/doc/examples/osmo-bsc/osmo-bsc.cfg
index c86a491b6..22afa0740 100644
--- a/doc/examples/osmo-bsc/osmo-bsc.cfg
+++ b/doc/examples/osmo-bsc/osmo-bsc.cfg
@@ -29,7 +29,7 @@ network
cell reselection hysteresis 4
rxlev access min 0
radio-link-timeout 32
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
channel-description attach 1
diff --git a/doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg b/doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg
index e60f39a3b..21187c79a 100644
--- a/doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg
+++ b/doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg
@@ -28,7 +28,7 @@ network
cell reselection hysteresis 4
rxlev access min 0
radio-link-timeout 32
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
channel-description attach 1
diff --git a/doc/manuals/chapters/bts-examples.adoc b/doc/manuals/chapters/bts-examples.adoc
index 836dec03d..2afc8ff55 100644
--- a/doc/manuals/chapters/bts-examples.adoc
+++ b/doc/manuals/chapters/bts-examples.adoc
@@ -32,7 +32,7 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
ipa unit-id 1801 0 <4>
@@ -110,7 +110,7 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
ipa unit-id 1800 0 <1>
@@ -203,7 +203,7 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full <3>
diff --git a/doc/manuals/chapters/chan_alloc.adoc b/doc/manuals/chapters/chan_alloc.adoc
index d99512465..b6b7b9285 100644
--- a/doc/manuals/chapters/chan_alloc.adoc
+++ b/doc/manuals/chapters/chan_alloc.adoc
@@ -19,7 +19,9 @@ All parameters with their respective default values are listed below:
----
network
bts 0
- channel allocator ascending
+ channel allocator mode chan-req ascending
+ channel allocator mode assignment ascending
+ channel allocator mode handover ascending
channel allocator avoid-interference 0
channel allocator tch-signalling-policy always
----
@@ -41,10 +43,21 @@ selected in both ascending and descending modes.
The allocation mode to be used can be configured using the following VTY command:
----
-OsmoBSC(config-net-bts)# channel allocator ?
- ascending Allocate Timeslots and Transceivers in ascending order
- descending Allocate Timeslots and Transceivers in descending order
+OsmoBSC(config-net-bts)# channel allocator mode ? <1>
+ set-all Set a single mode for all variants
+ chan-req Channel allocation for CHANNEL REQUEST (RACH)
+ assignment Channel allocation for assignment
+ handover Channel allocation for handover
+
+OsmoBSC(config-net-bts)# channel allocator mode set-all ? <2>
+ ascending Allocate Timeslots and Transceivers in ascending order
+ descending Allocate Timeslots and Transceivers in descending order
----
+<1> It's optionally possible to configure different allocation modes for
+different allocation causes, e.g. `ascending` for `chan-req` and `descending`
+for both `assignment` and `handover`.
+<2> `set-all` is equivalent to the old (deprecated) command syntax:
+`channel allocator (ascending|descending)`.
==== Interference aware channel allocation
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
index 8abcf1323..76945a136 100644
--- a/include/osmocom/bsc/bts.h
+++ b/include/osmocom/bsc/bts.h
@@ -517,7 +517,9 @@ struct gsm_bts {
/* should the channel allocator allocate channels from high TRX to TRX0,
* rather than starting from TRX0 and go upwards? */
- int chan_alloc_reverse;
+ bool chan_alloc_chan_req_reverse;
+ bool chan_alloc_assignment_reverse;
+ bool chan_alloc_handover_reverse;
/* When true, interference measurements from the BTS are used in the channel allocator to favor lchans with less
* interference reported in RSL Resource Indication. */
diff --git a/include/osmocom/bsc/lchan_select.h b/include/osmocom/bsc/lchan_select.h
index 3bb0d1ce6..b5eb078db 100644
--- a/include/osmocom/bsc/lchan_select.h
+++ b/include/osmocom/bsc/lchan_select.h
@@ -1,9 +1,24 @@
/* Select a suitable lchan from a given cell. */
#pragma once
-struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts, enum gsm_chan_t type);
+enum lchan_select_reason {
+ SELECT_FOR_MS_CHAN_REQ,
+ SELECT_FOR_ASSIGNMENT,
+ SELECT_FOR_HANDOVER,
+};
+
+extern const struct value_string lchan_select_reason_names[];
+static inline const char *lchan_select_reason_name(enum lchan_select_reason reason)
+{ return get_value_string(lchan_select_reason_names, reason); }
+
+struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts,
+ enum gsm_chan_t type,
+ enum lchan_select_reason reason);
enum gsm_chan_t chan_mode_to_chan_type(enum gsm48_chan_mode chan_mode, enum channel_rate chan_rate);
struct gsm_lchan *lchan_select_by_chan_mode(struct gsm_bts *bts,
- enum gsm48_chan_mode chan_mode, enum channel_rate chan_rate);
-struct gsm_lchan *lchan_avail_by_type(struct gsm_bts *bts, enum gsm_chan_t type, bool log);
+ enum gsm48_chan_mode chan_mode,
+ enum channel_rate chan_rate,
+ enum lchan_select_reason reason);
+struct gsm_lchan *lchan_avail_by_type(struct gsm_bts *bts, enum gsm_chan_t type,
+ enum lchan_select_reason reason, bool log);
void lchan_select_set_type(struct gsm_lchan *lchan, enum gsm_chan_t type);
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index f6215d954..7f88096e0 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -1978,10 +1978,10 @@ static struct gsm_lchan *get_any_lchan(struct gsm_bts *bts)
ts_for_n_lchans(lchan, ts, ts->max_primary_lchans) {
if (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H) {
if (lchan->fi->state == LCHAN_ST_ESTABLISHED) {
- if (!lchan_est || bts->chan_alloc_reverse)
+ if (!lchan_est || bts->chan_alloc_chan_req_reverse)
lchan_est = lchan;
} else {
- if (!lchan_any || bts->chan_alloc_reverse)
+ if (!lchan_any || bts->chan_alloc_chan_req_reverse)
lchan_any = lchan;
}
}
@@ -2007,12 +2007,12 @@ static bool force_free_lchan_for_emergency(struct chan_rqd *rqd)
/* First check the situation on the BTS, if we have TCH/H or TCH/F resources available for another (EMERGENCY)
* call. If yes, then no (further) action has to be carried out. */
- if (lchan_avail_by_type(rqd->bts, GSM_LCHAN_TCH_F, true)) {
+ if (lchan_avail_by_type(rqd->bts, GSM_LCHAN_TCH_F, SELECT_FOR_MS_CHAN_REQ, true)) {
LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,
"CHAN RQD/EMERGENCY-PRIORITY: at least one TCH/F is (now) available!\n");
return false;
}
- if (lchan_avail_by_type(rqd->bts, GSM_LCHAN_TCH_H, true)) {
+ if (lchan_avail_by_type(rqd->bts, GSM_LCHAN_TCH_H, SELECT_FOR_MS_CHAN_REQ, true)) {
LOG_BTS(rqd->bts, DRSL, LOGL_NOTICE,
"CHAN RQD/EMERGENCY-PRIORITY: at least one TCH/H is (now) available!\n");
return false;
@@ -2083,7 +2083,7 @@ struct gsm_lchan *_select_sdcch_for_call(struct gsm_bts *bts, const struct chan_
int free_tchf, free_tchh;
bool needs_dyn_switch;
- lchan = lchan_avail_by_type(bts, GSM_LCHAN_SDCCH, false);
+ lchan = lchan_avail_by_type(bts, GSM_LCHAN_SDCCH, SELECT_FOR_MS_CHAN_REQ, false);
if (!lchan)
return NULL;
@@ -2172,7 +2172,8 @@ void abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts)
if (rqd->reason == GSM_CHREQ_REASON_CALL) {
lchan = _select_sdcch_for_call(bts, rqd, lctype);
} else if (rqd->reason != GSM_CHREQ_REASON_EMERG) {
- lchan = lchan_select_by_type(bts, GSM_LCHAN_SDCCH);
+ lchan = lchan_select_by_type(bts, GSM_LCHAN_SDCCH,
+ SELECT_FOR_MS_CHAN_REQ);
}
/* else: Emergency calls will be put on a free TCH/H or TCH/F directly
* in the code below, all other channel requests will get an SDCCH first
@@ -2187,13 +2188,15 @@ void abis_rsl_chan_rqd_queue_poll(struct gsm_bts *bts)
LOG_BTS(bts, DRSL, LOGL_NOTICE, "CHAN RQD[%s]: no resources for %s 0x%x, retrying with %s\n",
get_value_string(gsm_chreq_descs, rqd->reason), gsm_lchant_name(GSM_LCHAN_SDCCH),
rqd->ref.ra, gsm_lchant_name(GSM_LCHAN_TCH_H));
- lchan = lchan_select_by_type(bts, GSM_LCHAN_TCH_H);
+ lchan = lchan_select_by_type(bts, GSM_LCHAN_TCH_H,
+ SELECT_FOR_MS_CHAN_REQ);
}
if (!lchan) {
LOG_BTS(bts, DRSL, LOGL_NOTICE, "CHAN RQD[%s]: no resources for %s 0x%x, retrying with %s\n",
get_value_string(gsm_chreq_descs, rqd->reason), gsm_lchant_name(GSM_LCHAN_SDCCH),
rqd->ref.ra, gsm_lchant_name(GSM_LCHAN_TCH_F));
- lchan = lchan_select_by_type(bts, GSM_LCHAN_TCH_F);
+ lchan = lchan_select_by_type(bts, GSM_LCHAN_TCH_F,
+ SELECT_FOR_MS_CHAN_REQ);
}
}
if (!lchan) {
diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c
index a0d008da5..209545fd9 100644
--- a/src/osmo-bsc/assignment_fsm.c
+++ b/src/osmo-bsc/assignment_fsm.c
@@ -604,7 +604,9 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
/* Try to allocate a new lchan in order of preference */
for (i = 0; i < req->n_ch_mode_rate; i++) {
conn->assignment.new_lchan = lchan_select_by_chan_mode(bts,
- req->ch_mode_rate_list[i].chan_mode, req->ch_mode_rate_list[i].chan_rate);
+ req->ch_mode_rate_list[i].chan_mode,
+ req->ch_mode_rate_list[i].chan_rate,
+ SELECT_FOR_ASSIGNMENT);
if (!conn->assignment.new_lchan)
continue;
LOG_ASSIGNMENT(conn, LOGL_DEBUG, "selected new lchan %s for mode[%d] = %s channel_rate=%d\n",
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 5b46e7917..0df5712b7 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -770,7 +770,9 @@ static int trigger_as(struct vty *vty, struct gsm_lchan *from_lchan, struct gsm_
{
LOG_LCHAN(from_lchan, LOGL_NOTICE, "Manually triggering Assignment from VTY\n");
if (!to_lchan) {
- to_lchan = lchan_select_by_type(from_lchan->ts->trx->bts, from_lchan->type);
+ struct gsm_bts *bts = from_lchan->ts->trx->bts;
+ to_lchan = lchan_select_by_type(bts, from_lchan->type,
+ SELECT_FOR_ASSIGNMENT);
vty_out(vty, "Error: cannot find free lchan of type %s%s",
gsm_lchant_name(from_lchan->type), VTY_NEWLINE);
}
@@ -955,7 +957,8 @@ static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gs
continue;
llist_for_each_entry(trx, &bts->trx_list, list) {
- struct gsm_lchan *lchan = lchan_select_by_type(bts, free_type);
+ struct gsm_lchan *lchan = lchan_select_by_type(bts, free_type,
+ SELECT_FOR_HANDOVER);
if (!lchan)
continue;
diff --git a/src/osmo-bsc/bts_vty.c b/src/osmo-bsc/bts_vty.c
index c23c14ee8..1a9b1e339 100644
--- a/src/osmo-bsc/bts_vty.c
+++ b/src/osmo-bsc/bts_vty.c
@@ -533,20 +533,51 @@ DEFUN_USRATTR(cfg_bts_oml_e1_tei,
"Channel Allocator\n" \
"Channel Allocator\n"
-DEFUN_ATTR(cfg_bts_challoc,
- cfg_bts_challoc_cmd,
- CHAN_ALLOC_CMD " (ascending|descending)",
+#define CHAN_ALLOC_ASC_DSC "(ascending|descending)"
+#define CHAN_ALLOC_ASC_DSC_DESC \
+ "Allocate Timeslots and Transceivers in ascending order\n" \
+ "Allocate Timeslots and Transceivers in descending order\n"
+
+DEFUN_ATTR(cfg_bts_challoc_mode_all,
+ cfg_bts_challoc_mode_all_cmd,
+ CHAN_ALLOC_CMD " " CHAN_ALLOC_ASC_DSC,
+ CHAN_ALLOC_DESC CHAN_ALLOC_ASC_DSC_DESC,
+ CMD_ATTR_IMMEDIATE | CMD_ATTR_DEPRECATED)
+{
+ bool reverse = !strcmp(argv[0], "descending");
+ struct gsm_bts *bts = vty->index;
+
+ bts->chan_alloc_chan_req_reverse = reverse;
+ bts->chan_alloc_assignment_reverse = reverse;
+ bts->chan_alloc_handover_reverse = reverse;
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_ATTR(cfg_bts_challoc_mode,
+ cfg_bts_challoc_mode_cmd,
+ CHAN_ALLOC_CMD
+ " mode (set-all|chan-req|assignment|handover) "
+ CHAN_ALLOC_ASC_DSC,
CHAN_ALLOC_DESC
- "Allocate Timeslots and Transceivers in ascending order\n"
- "Allocate Timeslots and Transceivers in descending order\n",
+ "Channel allocation mode\n"
+ "Set a single mode for all variants\n"
+ "Channel allocation for CHANNEL REQUEST (RACH)\n"
+ "Channel allocation for assignment\n"
+ "Channel allocation for handover\n"
+ CHAN_ALLOC_ASC_DSC_DESC,
CMD_ATTR_IMMEDIATE)
{
+ bool reverse = !strcmp(argv[1], "descending");
+ bool set_all = !strcmp(argv[0], "set-all");
struct gsm_bts *bts = vty->index;
- if (!strcmp(argv[0], "ascending"))
- bts->chan_alloc_reverse = 0;
- else
- bts->chan_alloc_reverse = 1;
+ if (set_all || !strcmp(argv[0], "chan-req"))
+ bts->chan_alloc_chan_req_reverse = reverse;
+ if (set_all || !strcmp(argv[0], "assignment"))
+ bts->chan_alloc_assignment_reverse = reverse;
+ if (set_all || !strcmp(argv[0], "handover"))
+ bts->chan_alloc_handover_reverse = reverse;
return CMD_SUCCESS;
}
@@ -4212,8 +4243,14 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " radio-link-timeout %d%s",
gsm_bts_get_radio_link_timeout(bts), VTY_NEWLINE);
- vty_out(vty, " channel allocator %s%s",
- bts->chan_alloc_reverse ? "descending" : "ascending",
+ vty_out(vty, " channel allocator mode chan-req %s%s",
+ bts->chan_alloc_chan_req_reverse ? "descending" : "ascending",
+ VTY_NEWLINE);
+ vty_out(vty, " channel allocator mode assignment %s%s",
+ bts->chan_alloc_assignment_reverse ? "descending" : "ascending",
+ VTY_NEWLINE);
+ vty_out(vty, " channel allocator mode handover %s%s",
+ bts->chan_alloc_handover_reverse ? "descending" : "ascending",
VTY_NEWLINE);
if (bts->chan_alloc_avoid_interf)
vty_out(vty, " channel allocator avoid-interference 1%s", VTY_NEWLINE);
@@ -4543,7 +4580,8 @@ int bts_vty_init(void)
install_element(BTS_NODE, &cfg_bts_deprecated_stream_id_cmd);
install_element(BTS_NODE, &cfg_bts_oml_e1_cmd);
install_element(BTS_NODE, &cfg_bts_oml_e1_tei_cmd);
- install_element(BTS_NODE, &cfg_bts_challoc_cmd);
+ install_element(BTS_NODE, &cfg_bts_challoc_mode_cmd);
+ install_element(BTS_NODE, &cfg_bts_challoc_mode_all_cmd);
install_element(BTS_NODE, &cfg_bts_chan_alloc_interf_cmd);
install_element(BTS_NODE, &cfg_bts_chan_alloc_tch_signalling_policy_cmd);
install_element(BTS_NODE, &cfg_bts_chan_alloc_allow_tch_for_signalling_cmd);
diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
index a1a8ffa8f..3c4b3baac 100644
--- a/src/osmo-bsc/handover_decision_2.c
+++ b/src/osmo-bsc/handover_decision_2.c
@@ -1050,7 +1050,7 @@ static void candidate_set_free_tch(struct ho_candidate *c)
/* Would the next TCH/F lchan occupy a dynamic timeslot that currently counts for free TCH/H timeslots?
*/
- next_lchan = lchan_avail_by_type(c->target.bts, GSM_LCHAN_TCH_F, false);
+ next_lchan = lchan_avail_by_type(c->target.bts, GSM_LCHAN_TCH_F, SELECT_FOR_HANDOVER, false);
if (next_lchan && next_lchan->ts->pchan_on_init == GSM_PCHAN_OSMO_DYN)
c->target.next_tchf_reduces_tchh = 2;
else
@@ -1058,7 +1058,7 @@ static void candidate_set_free_tch(struct ho_candidate *c)
/* Would the next TCH/H lchan occupy a dynamic timeslot that currently counts for free TCH/F timeslots?
* Note that a dyn TS already in TCH/H mode (half occupied) would not reduce free TCH/F. */
- next_lchan = lchan_avail_by_type(c->target.bts, GSM_LCHAN_TCH_H, false);
+ next_lchan = lchan_avail_by_type(c->target.bts, GSM_LCHAN_TCH_H, SELECT_FOR_HANDOVER, false);
if (next_lchan && next_lchan->ts->pchan_on_init == GSM_PCHAN_OSMO_DYN
&& next_lchan->ts->pchan_is != GSM_PCHAN_TCH_H)
c->target.next_tchh_reduces_tchf = 1;
diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c
index a4221c4bc..0797bf3f8 100644
--- a/src/osmo-bsc/handover_fsm.c
+++ b/src/osmo-bsc/handover_fsm.c
@@ -379,7 +379,9 @@ static void handover_start_intra_bsc(struct gsm_subscriber_connection *conn)
ho->async = true;
gsm_bts_cell_id_list(&ho->target_cell_ids, ho->new_bts);
- ho->new_lchan = lchan_select_by_type(ho->new_bts, ho->new_lchan_type);
+ ho->new_lchan = lchan_select_by_type(ho->new_bts,
+ ho->new_lchan_type,
+ SELECT_FOR_HANDOVER);
if (ho->scope & HO_INTRA_CELL) {
ho_count(bts, CTR_INTRA_CELL_HO_ATTEMPTED);
@@ -696,7 +698,10 @@ void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn,
ch_mode_rate.chan_rate == CH_RATE_FULL ? "full-rate" : "half-rate",
gsm0808_channel_type_name(&req->ct));
- lchan = lchan_select_by_chan_mode(bts, ch_mode_rate.chan_mode, ch_mode_rate.chan_rate);
+ lchan = lchan_select_by_chan_mode(bts,
+ ch_mode_rate.chan_mode,
+ ch_mode_rate.chan_rate,
+ SELECT_FOR_HANDOVER);
if (!lchan) {
LOG_HO(conn, LOGL_DEBUG, "BTS %u has no matching free channels\n", bts->nr);
continue;
diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c
index a322f07a4..8b6da4036 100644
--- a/src/osmo-bsc/lchan_select.c
+++ b/src/osmo-bsc/lchan_select.c
@@ -35,6 +35,13 @@ struct lchan_select_ts_list {
unsigned int num;
};
+const struct value_string lchan_select_reason_names[] = {
+ OSMO_VALUE_STRING(SELECT_FOR_MS_CHAN_REQ),
+ OSMO_VALUE_STRING(SELECT_FOR_ASSIGNMENT),
+ OSMO_VALUE_STRING(SELECT_FOR_HANDOVER),
+ {0, NULL}
+};
+
static struct gsm_lchan *pick_better_lchan(struct gsm_lchan *a, struct gsm_lchan *b)
{
if (!a)
@@ -190,6 +197,7 @@ enum gsm_chan_t chan_mode_to_chan_type(enum gsm48_chan_mode chan_mode, enum chan
static void populate_ts_list(struct lchan_select_ts_list *ts_list,
struct gsm_bts *bts,
+ bool chan_alloc_reverse,
bool log)
{
struct gsm_bts_trx *trx;
@@ -208,7 +216,7 @@ static void populate_ts_list(struct lchan_select_ts_list *ts_list,
ts_list->num = num;
/* Reverse the timeslot list if required */
- if (bts->chan_alloc_reverse) {
+ if (chan_alloc_reverse) {
for (unsigned int tn = 0; tn < num / 2; tn++) {
struct gsm_bts_trx_ts *temp = ts_list->list[tn];
ts_list->list[tn] = ts_list->list[num - tn - 1];
@@ -218,22 +226,40 @@ static void populate_ts_list(struct lchan_select_ts_list *ts_list,
}
struct gsm_lchan *lchan_select_by_chan_mode(struct gsm_bts *bts,
- enum gsm48_chan_mode chan_mode, enum channel_rate chan_rate)
+ enum gsm48_chan_mode chan_mode,
+ enum channel_rate chan_rate,
+ enum lchan_select_reason reason)
{
enum gsm_chan_t type = chan_mode_to_chan_type(chan_mode, chan_rate);
if (type == GSM_LCHAN_NONE)
return NULL;
- return lchan_select_by_type(bts, type);
+ return lchan_select_by_type(bts, type, reason);
}
-struct gsm_lchan *lchan_avail_by_type(struct gsm_bts *bts, enum gsm_chan_t type, bool log)
+struct gsm_lchan *lchan_avail_by_type(struct gsm_bts *bts, enum gsm_chan_t type,
+ enum lchan_select_reason reason, bool log)
{
struct gsm_lchan *lchan = NULL;
enum gsm_phys_chan_config first, first_cbch, second, second_cbch;
struct lchan_select_ts_list ts_list;
+ bool chan_alloc_reverse;
+
+ if (log) {
+ LOG_BTS(bts, DRLL, LOGL_DEBUG, "lchan_avail_by_type(type=%s, reason=%s)\n",
+ gsm_lchant_name(type), lchan_select_reason_name(reason));
+ }
- if (log)
- LOG_BTS(bts, DRLL, LOGL_DEBUG, "lchan_avail_by_type(%s)\n", gsm_lchant_name(type));
+ switch (reason) {
+ case SELECT_FOR_MS_CHAN_REQ:
+ chan_alloc_reverse = bts->chan_alloc_chan_req_reverse;
+ break;
+ case SELECT_FOR_ASSIGNMENT:
+ chan_alloc_reverse = bts->chan_alloc_assignment_reverse;
+ break;
+ case SELECT_FOR_HANDOVER:
+ chan_alloc_reverse = bts->chan_alloc_handover_reverse;
+ break;
+ }
/* Allocate an array with pointers to all timeslots of a BTS */
ts_list.list = talloc_array_ptrtype(bts, ts_list.list, bts->num_trx * 8);
@@ -241,11 +267,11 @@ struct gsm_lchan *lchan_avail_by_type(struct gsm_bts *bts, enum gsm_chan_t type,
return NULL;
/* Populate this array with the actual pointers */
- populate_ts_list(&ts_list, bts, log);
+ populate_ts_list(&ts_list, bts, chan_alloc_reverse, log);
switch (type) {
case GSM_LCHAN_SDCCH:
- if (bts->chan_alloc_reverse) {
+ if (chan_alloc_reverse) {
first = GSM_PCHAN_SDCCH8_SACCH8C;
first_cbch = GSM_PCHAN_SDCCH8_SACCH8C_CBCH;
second = GSM_PCHAN_CCCH_SDCCH4;
@@ -302,17 +328,20 @@ struct gsm_lchan *lchan_avail_by_type(struct gsm_bts *bts, enum gsm_chan_t type,
/* Return a matching lchan from a specific BTS that is currently available. The next logical step is
* lchan_activate() on it, which would possibly cause dynamic timeslot pchan switching, taken care of by
* the lchan and timeslot FSMs. */
-struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts, enum gsm_chan_t type)
+struct gsm_lchan *lchan_select_by_type(struct gsm_bts *bts,
+ enum gsm_chan_t type,
+ enum lchan_select_reason reason)
{
struct gsm_lchan *lchan = NULL;
- LOG_BTS(bts, DRLL, LOGL_DEBUG, "lchan_select_by_type(%s)\n", gsm_lchant_name(type));
+ LOG_BTS(bts, DRLL, LOGL_DEBUG, "lchan_select_by_type(type=%s, reason=%s)\n",
+ gsm_lchant_name(type), lchan_select_reason_name(reason));
- lchan = lchan_avail_by_type(bts, type, true);
+ lchan = lchan_avail_by_type(bts, type, reason, true);
if (!lchan) {
- LOG_BTS(bts, DRLL, LOGL_NOTICE, "Failed to select %s channel\n",
- gsm_lchant_name(type));
+ LOG_BTS(bts, DRLL, LOGL_NOTICE, "Failed to select %s channel (%s)\n",
+ gsm_lchant_name(type), lchan_select_reason_name(reason));
return NULL;
}
diff --git a/tests/ctrl/osmo-bsc-apply-config-file.cfg b/tests/ctrl/osmo-bsc-apply-config-file.cfg
index 1a069ce75..0094cd70d 100644
--- a/tests/ctrl/osmo-bsc-apply-config-file.cfg
+++ b/tests/ctrl/osmo-bsc-apply-config-file.cfg
@@ -9,7 +9,7 @@ network
cell reselection hysteresis 4
rxlev access min 0
radio-link-timeout 32
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
channel-description attach 1
diff --git a/tests/ctrl/osmo-bsc-neigh-test.cfg b/tests/ctrl/osmo-bsc-neigh-test.cfg
index 93d7fca83..8c04db6d6 100644
--- a/tests/ctrl/osmo-bsc-neigh-test.cfg
+++ b/tests/ctrl/osmo-bsc-neigh-test.cfg
@@ -35,7 +35,7 @@ network
cell reselection hysteresis 4
rxlev access min 0
radio-link-timeout 32
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
channel-description attach 1
@@ -92,7 +92,7 @@ network
cell reselection hysteresis 4
rxlev access min 0
radio-link-timeout 32
- channel allocator ascending
+ channel allocator mode set-all ascending
rach tx integer 9
rach max transmission 7
channel-description attach 1
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index d82ba9f90..77fa3712e 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -488,7 +488,8 @@ struct gsm_lchan *create_lchan(struct gsm_bts *bts, int full_rate, const char *c
{
struct gsm_lchan *lchan;
- lchan = lchan_select_by_type(bts, (full_rate) ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H);
+ lchan = lchan_select_by_type(bts, (full_rate) ? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H,
+ SELECT_FOR_HANDOVER);
if (!lchan) {
fprintf(stderr, "No resource for lchan\n");
exit(EXIT_FAILURE);
diff --git a/tests/handover/test_dyn_ts_favor_static_ts_as_target.ho_vty b/tests/handover/test_dyn_ts_favor_static_ts_as_target.ho_vty
index c50b00705..0c55a2c97 100644
--- a/tests/handover/test_dyn_ts_favor_static_ts_as_target.ho_vty
+++ b/tests/handover/test_dyn_ts_favor_static_ts_as_target.ho_vty
@@ -3,7 +3,7 @@ create-bts trx-count 1 timeslots c+s4 dyn TCH/H dyn TCH/H dyn TCH/H
network
bts 0
- channel allocator ascending
+ channel allocator mode set-all ascending
set-ts-use trx 0 0 states * TCH/-H TCH/-H TCH/-H TCH/-H TCH/-H TCH/-H *
diff --git a/tests/osmo-bsc.vty b/tests/osmo-bsc.vty
index f2af32bca..e0b9bdc18 100644
--- a/tests/osmo-bsc.vty
+++ b/tests/osmo-bsc.vty
@@ -166,11 +166,20 @@ OsmoBSC(config-net-bts)# channel ?
allocator Channel Allocator
OsmoBSC(config-net-bts)# channel allocator ?
- ascending Allocate Timeslots and Transceivers in ascending order
- descending Allocate Timeslots and Transceivers in descending order
+ mode Channel allocation mode
avoid-interference Configure whether reported interference levels from RES IND are used in channel allocation
tch-signalling-policy Configure when TCH/H or TCH/F channels can be used to serve signalling if SDCCHs are exhausted
+OsmoBSC(config-net-bts)# channel allocator mode ?
+ set-all Set a single mode for all variants
+ chan-req Channel allocation for CHANNEL REQUEST (RACH)
+ assignment Channel allocation for assignment
+ handover Channel allocation for handover
+
+OsmoBSC(config-net-bts)# channel allocator mode set-all ?
+ ascending Allocate Timeslots and Transceivers in ascending order
+ descending Allocate Timeslots and Transceivers in descending order
+
OsmoBSC(config-net-bts)# channel allocator avoid-interference ?
0 Ignore interference levels (default). Always assign lchans in a deterministic order.
1 In channel allocation, prefer lchans with less interference.