aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2022-06-06 01:43:28 +0600
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2022-06-18 04:00:47 +0700
commit60190c8e1d54f752836caf85add973968101d6aa (patch)
treeb5f0d63d9b8dfeb78dcf90a5f4bcc8145f9c79b5
parentf1c416261bf75e44dd5de9b2dffcf1475189588a (diff)
lchan_select: allow different alloc order for assignment and handover
-rw-r--r--doc/manuals/chapters/bts-examples.adoc12
-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/handover/handover_test.c3
-rw-r--r--tests/osmo-bsc.vty13
12 files changed, 163 insertions, 50 deletions
diff --git a/doc/manuals/chapters/bts-examples.adoc b/doc/manuals/chapters/bts-examples.adoc
index 836dec03d..acd748c10 100644
--- a/doc/manuals/chapters/bts-examples.adoc
+++ b/doc/manuals/chapters/bts-examples.adoc
@@ -32,7 +32,9 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator ascending
+ channel allocator mode chan-req ascending
+ channel allocator mode assignment ascending
+ channel allocator mode handover ascending
rach tx integer 9
rach max transmission 7
ipa unit-id 1801 0 <4>
@@ -110,7 +112,9 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator ascending
+ channel allocator mode chan-req ascending
+ channel allocator mode assignment ascending
+ channel allocator mode handover ascending
rach tx integer 9
rach max transmission 7
ipa unit-id 1800 0 <1>
@@ -203,7 +207,9 @@ network
ms max power 15
cell reselection hysteresis 4
rxlev access min 0
- channel allocator ascending
+ channel allocator mode chan-req ascending
+ channel allocator mode assignment ascending
+ channel allocator mode handover ascending
rach tx integer 9
rach max transmission 7
oml e1 line 0 timeslot 1 sub-slot full <3>
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 fb03d6fdc..4af7b6e77 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..46866e0b1 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_HIDDEN)
+{
+ 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/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/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.