fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/28327 )
Change subject: lchan_select: allow different alloc order for assignment and handover ......................................................................
lchan_select: allow different alloc order for assignment and handover
Change-Id: I3ae73b36ee9433cc768376b56f0765e5f416162f Related: SYS#5460 --- M doc/manuals/chapters/bts-examples.adoc M include/osmocom/bsc/bts.h M include/osmocom/bsc/lchan_select.h M src/osmo-bsc/abis_rsl.c M src/osmo-bsc/assignment_fsm.c M src/osmo-bsc/bsc_vty.c M src/osmo-bsc/bts_vty.c M src/osmo-bsc/handover_decision_2.c M src/osmo-bsc/handover_fsm.c M src/osmo-bsc/lchan_select.c M tests/handover/handover_test.c M tests/osmo-bsc.vty 12 files changed, 165 insertions(+), 52 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/27/28327/1
diff --git a/doc/manuals/chapters/bts-examples.adoc b/doc/manuals/chapters/bts-examples.adoc index 836dec0..acd748c 100644 --- a/doc/manuals/chapters/bts-examples.adoc +++ b/doc/manuals/chapters/bts-examples.adoc @@ -32,7 +32,9 @@ 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 @@ 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 @@ 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 8abcf13..76945a1 100644 --- a/include/osmocom/bsc/bts.h +++ b/include/osmocom/bsc/bts.h @@ -517,7 +517,9 @@
/* 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 3bb0d1c..b5eb078 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 f6215d9..7f88096 100644 --- a/src/osmo-bsc/abis_rsl.c +++ b/src/osmo-bsc/abis_rsl.c @@ -1978,10 +1978,10 @@ 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 @@
/* 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 @@ 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 @@ 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 @@ 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 a0d008d..209545f 100644 --- a/src/osmo-bsc/assignment_fsm.c +++ b/src/osmo-bsc/assignment_fsm.c @@ -604,7 +604,9 @@ /* 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 fb03d6f..4af7b6e 100644 --- a/src/osmo-bsc/bsc_vty.c +++ b/src/osmo-bsc/bsc_vty.c @@ -770,7 +770,9 @@ { 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 @@ 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 c23c14e..46866e0 100644 --- a/src/osmo-bsc/bts_vty.c +++ b/src/osmo-bsc/bts_vty.c @@ -533,20 +533,51 @@ "Channel Allocator\n" \ "Channel Allocator\n"
-DEFUN_ATTR(cfg_bts_challoc, - cfg_bts_challoc_cmd, - CHAN_ALLOC_CMD " (ascending|descending)", - CHAN_ALLOC_DESC - "Allocate Timeslots and Transceivers in ascending order\n" - "Allocate Timeslots and Transceivers in descending order\n", - CMD_ATTR_IMMEDIATE) +#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;
- if (!strcmp(argv[0], "ascending")) - bts->chan_alloc_reverse = 0; - else - bts->chan_alloc_reverse = 1; + 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 + "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 (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 @@ 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 @@ 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 a1a8ffa..3c4b3ba 100644 --- a/src/osmo-bsc/handover_decision_2.c +++ b/src/osmo-bsc/handover_decision_2.c @@ -1050,7 +1050,7 @@
/* 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 @@
/* 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 a4221c4..0797bf3 100644 --- a/src/osmo-bsc/handover_fsm.c +++ b/src/osmo-bsc/handover_fsm.c @@ -379,7 +379,9 @@ 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 @@ 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 a322f07..8b6da40 100644 --- a/src/osmo-bsc/lchan_select.c +++ b/src/osmo-bsc/lchan_select.c @@ -35,6 +35,13 @@ 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 @@
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 @@ 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 @@ }
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(%s)\n", gsm_lchant_name(type)); + 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)); + } + + 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 @@ 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 @@ /* 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 d82ba9f..77fa371 100644 --- a/tests/handover/handover_test.c +++ b/tests/handover/handover_test.c @@ -488,7 +488,8 @@ { 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 f2af32b..e0b9bdc 100644 --- a/tests/osmo-bsc.vty +++ b/tests/osmo-bsc.vty @@ -166,11 +166,20 @@ 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.