This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/19303 )
Change subject: WIP: Introduce support for ACC subset rotation
......................................................................
WIP: Introduce support for ACC subset rotation
Change-Id: I952c9eeae02809c7184078c655574ec817902e06
---
M include/osmocom/bsc/acc_ramp.h
M include/osmocom/bsc/bts.h
M src/osmo-bsc/acc_ramp.c
M src/osmo-bsc/bsc_vty.c
M src/osmo-bsc/bts.c
M src/osmo-bsc/system_information.c
M tests/gsm0408/gsm0408_test.c
7 files changed, 342 insertions(+), 94 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/03/19303/1
diff --git a/include/osmocom/bsc/acc_ramp.h b/include/osmocom/bsc/acc_ramp.h
index 31fc74f..483f437 100644
--- a/include/osmocom/bsc/acc_ramp.h
+++ b/include/osmocom/bsc/acc_ramp.h
@@ -27,6 +27,40 @@
#include <osmocom/core/timer.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
+#define ACC_MGR_QUANTUM_DEFAULT 20 /* 20 seconds */
+
+/* Manage rotating subset of allowed Access Class as per configuration */
+struct acc_mgr {
+ struct gsm_bts *bts; /*!< backpointer to BTS using this ACC manager */
+ /* Administrative Maximum Number of ACC 0-9 to be allowed at the same time.
+ Configurable through VTY cmd "access-control-class-roundrobin",
+ defaults to all allowed (10) */
+ uint8_t len_allowed_adm;
+ /* Further limiting the number of ACC to use. It may be lower due
+ to ramping, based for instance on channel or system load. */
+ uint8_t len_allowed_ramp;
+
+ /* Time until next subset is generated */
+ uint32_t rotation_time_sec;
+ struct osmo_timer_list rotate_timer;
+
+ /* Bitmask containing subset of allowed ACC 0-9 on current rotation iteration */
+ uint16_t allowed_subset_mask;
+ /* Number of bits (ACC) set in allowed_subset_mask: 0->min(len_allowed_ramp, len_allowed_adm) */
+ uint8_t allowed_subset_mask_count;
+ /* Number of ACC 0-9 allowed as per adminsitrative (permanent) config. */
+ uint8_t allowed_permanent_count;
+};
+
+void acc_mgr_init(struct acc_mgr *acc_mgr, struct gsm_bts *bts);
+uint8_t acc_mgr_get_len_allowed_adm(struct acc_mgr *acc_mgr);
+uint8_t acc_mgr_get_len_allowed_ramp(struct acc_mgr *acc_mgr);
+void acc_mgr_set_len_allowed_adm(struct acc_mgr *acc_mgr, uint8_t len_allowed_adm);
+void acc_mgr_set_len_allowed_ramp(struct acc_mgr *acc_mgr, uint8_t len_allowed_ramp);
+void acc_mgr_set_rotation_time(struct acc_mgr *acc_mgr, uint32_t rotation_time_sec);
+void acc_mgr_perm_subset_changed(struct acc_mgr *acc_mgr, struct gsm48_rach_control *rach_control);
+void acc_mgr_apply_acc(struct acc_mgr *acc_mgr, struct gsm48_rach_control *rach_control);
+
/*!
* Access control class (ACC) ramping is used to slowly make the cell available to
* an increasing number of MS. This avoids overload at startup time in cases where
@@ -126,33 +160,6 @@
return !(acc_ramp->step_interval_is_fixed);
}
-/*!
- * Return bitmasks which correspond to access control classes that are currently
- * denied access. Ramping is only concerned with those bits which control access
- * for ACCs 0-9, and any of the other bits will always be set to zero in these masks, i.e.
- * it is safe to OR these bitmasks with the corresponding fields in struct gsm48_rach_control.
- * \param[in] acc_ramp Pointer to acc_ramp structure.
- */
-static inline uint8_t acc_ramp_get_barred_t2(struct acc_ramp *acc_ramp)
-{
- return ((acc_ramp->barred_accs >> 8) & 0x03);
-};
-static inline uint8_t acc_ramp_get_barred_t3(struct acc_ramp *acc_ramp)
-{
- return (acc_ramp->barred_accs & 0xff);
-}
-
-/*!
- * Potentially mark certain Access Control Classes (ACCs) as barred in accordance to ACC ramping.
- * \param[in] rach_control RACH control parameters in which barred ACCs will be configured.
- * \param[in] acc_ramp Pointer to acc_ramp structure.
- */
-static inline void acc_ramp_apply(struct gsm48_rach_control *rach_control, struct acc_ramp *acc_ramp)
-{
- rach_control->t2 |= acc_ramp_get_barred_t2(acc_ramp);
- rach_control->t3 |= acc_ramp_get_barred_t3(acc_ramp);
-}
-
void acc_ramp_init(struct acc_ramp *acc_ramp, struct gsm_bts *bts);
int acc_ramp_set_step_size(struct acc_ramp *acc_ramp, unsigned int step_size);
int acc_ramp_set_step_interval(struct acc_ramp *acc_ramp, unsigned int step_interval);
diff --git a/include/osmocom/bsc/bts.h b/include/osmocom/bsc/bts.h
index 730dee9..16053a3 100644
--- a/include/osmocom/bsc/bts.h
+++ b/include/osmocom/bsc/bts.h
@@ -449,6 +449,7 @@
uint32_t si_mode_static;
/* access control class ramping */
+ struct acc_mgr acc_mgr;
struct acc_ramp acc_ramp;
/* exclude the BTS from the global RF Lock handling */
diff --git a/src/osmo-bsc/acc_ramp.c b/src/osmo-bsc/acc_ramp.c
index 761ab09..8406b82 100644
--- a/src/osmo-bsc/acc_ramp.c
+++ b/src/osmo-bsc/acc_ramp.c
@@ -20,6 +20,8 @@
*/
#include <strings.h>
+#include <stdint.h>
+#include <inttypes.h>
#include <errno.h>
#include <stdbool.h>
@@ -43,42 +45,276 @@
return (bts->si_common.rach_control.t3 & (1 << (acc)));
}
-static void allow_one_acc(struct acc_ramp *acc_ramp, unsigned int acc)
+/*!
+ * Return bitmasks which correspond to access control classes that are currently
+ * denied access. Ramping is only concerned with those bits which control access
+ * for ACCs 0-9, and any of the other bits will always be set to zero in these masks, i.e.
+ * it is safe to OR these bitmasks with the corresponding fields in struct gsm48_rach_control.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ */
+static inline uint8_t acc_mgr_get_barred_t2(struct acc_mgr *acc_mgr)
{
- OSMO_ASSERT(acc <= 9);
- if (acc_ramp->barred_accs & (1 << acc))
- LOG_BTS(acc_ramp->bts, DRSL, LOGL_NOTICE,
- "ACC RAMP: allowing Access Control Class %u\n", acc);
- acc_ramp->barred_accs &= ~(1 << acc);
+ return ((~acc_mgr->allowed_subset_mask) >> 8) & 0x03;
+};
+static inline uint8_t acc_mgr_get_barred_t3(struct acc_mgr *acc_mgr)
+{
+ return (~acc_mgr->allowed_subset_mask) & 0xff;
}
-static void barr_one_acc(struct acc_ramp *acc_ramp, unsigned int acc)
+static uint8_t acc_mgr_subset_len(struct acc_mgr *acc_mgr)
{
- OSMO_ASSERT(acc <= 9);
- if ((acc_ramp->barred_accs & (1 << acc)) == 0)
- LOG_BTS(acc_ramp->bts, DRSL, LOGL_NOTICE,
- "ACC RAMP: barring Access Control Class %u\n", acc);
- acc_ramp->barred_accs |= (1 << acc);
+ return OSMO_MIN(acc_mgr->len_allowed_ramp, acc_mgr->len_allowed_adm);
}
-static void barr_all_accs(struct acc_ramp *acc_ramp)
+static void acc_mgr_enable_rotation_cond(struct acc_mgr *acc_mgr)
{
- unsigned int acc;
- for (acc = 0; acc < 10; acc++) {
- if (!acc_is_permanently_barred(acc_ramp->bts, acc))
- barr_one_acc(acc_ramp, acc);
+ if (acc_mgr->allowed_permanent_count &&
+ acc_mgr->allowed_permanent_count == acc_mgr->allowed_subset_mask_count) {
+ if (!osmo_timer_pending(&acc_mgr->rotate_timer))
+ osmo_timer_schedule(&acc_mgr->rotate_timer, acc_mgr->rotation_time_sec, 0);
+ } else {
+ /* No rotation needed, disable rotation timer */
+ if (osmo_timer_pending(&acc_mgr->rotate_timer))
+ osmo_timer_del(&acc_mgr->rotate_timer);
}
}
-static void allow_all_accs(struct acc_ramp *acc_ramp)
+static void acc_mgr_gen_subset(struct acc_mgr *acc_mgr, bool update_si)
{
- unsigned int acc;
+ uint8_t acc;
+
+ acc_mgr->allowed_subset_mask = 0; /* clean mask */
+ acc_mgr->allowed_subset_mask_count = 0;
+ acc_mgr->allowed_permanent_count = 0;
+
for (acc = 0; acc < 10; acc++) {
- if (!acc_is_permanently_barred(acc_ramp->bts, acc))
- allow_one_acc(acc_ramp, acc);
+ if (acc_is_permanently_barred(acc_mgr->bts, acc))
+ continue;
+ acc_mgr->allowed_permanent_count++;
+ if (acc_mgr->allowed_subset_mask_count < acc_mgr_subset_len(acc_mgr)) {
+ acc_mgr->allowed_subset_mask &= (1 << acc);
+ acc_mgr->allowed_subset_mask_count++;
+ }
}
+
+ LOG_BTS(acc_mgr->bts, DRSL, LOGL_INFO,
+ "ACC: New ACC allowed subset 0x%" PRIx16 " (allowed=%" PRIu8
+ ", adm_len=%" PRIu8 ", ramp_len=%" PRIu8 ")\n",
+ acc_mgr->allowed_subset_mask, acc_mgr->allowed_subset_mask_count,
+ acc_mgr->len_allowed_adm, acc_mgr->len_allowed_ramp);
+
+ acc_mgr_enable_rotation_cond(acc_mgr);
+
+ /* Trigger SI data update, acc_mgr_apply_acc will bew called */
+ if (update_si)
+ gsm_bts_set_system_infos(acc_mgr->bts);
}
+static uint8_t get_highest_allowed_acc(uint16_t mask)
+{
+ for (int i = 9; i >= 0; i--) {
+ if (mask & (1 << i))
+ return i;
+ }
+ OSMO_ASSERT(0);
+ return 0;
+}
+
+static uint8_t get_lowest_allowed_acc(uint16_t mask)
+{
+ for (int i = 0; i < 10; i++) {
+ if (mask & (1 << i))
+ return i;
+ }
+ OSMO_ASSERT(0);
+ return 0;
+}
+
+/* Call when either adm_len or ramp_len changed (and values have been updated) */
+static void acc_mgr_subset_length_changed(struct acc_mgr *acc_mgr)
+{
+ uint8_t curr_len = acc_mgr->allowed_subset_mask_count;
+ uint8_t new_len = acc_mgr_subset_len(acc_mgr);
+ uint8_t diff = new_len - curr_len;
+ uint8_t i;
+
+ if (curr_len == new_len)
+ return;
+
+ if (new_len == 0) {
+ acc_mgr->allowed_subset_mask = 0;
+ acc_mgr->allowed_subset_mask_count = 0;
+ acc_mgr_enable_rotation_cond(acc_mgr);
+ gsm_bts_set_system_infos(acc_mgr->bts);
+ return;
+ }
+
+ if (curr_len == 0) {
+ acc_mgr_gen_subset(acc_mgr, true);
+ return;
+ }
+
+ /* Try to add new ACCs to the set starting from highest one (since we rotate rolling up) */
+ if (diff > 0) { /* curr_len < new_len */
+ uint8_t highest = get_highest_allowed_acc(acc_mgr->allowed_subset_mask);
+ /* It's fine skipping highest in the loop since it's known to be already set: */
+ for (i = (highest + 1) % 10; i != highest; i = (i + 1) % 10) {
+ if (acc_is_permanently_barred(acc_mgr->bts, i))
+ continue;
+ if (acc_mgr->allowed_subset_mask & (1 << i))
+ continue; /* already in set */
+ acc_mgr->allowed_subset_mask &= (1 << i);
+ acc_mgr->allowed_subset_mask_count++;
+ diff--;
+ if (diff == 0)
+ break;
+ }
+ } else { /* curr_len > new_len, try removing from lowest one. */
+ uint8_t lowest = get_lowest_allowed_acc(acc_mgr->allowed_subset_mask);
+ i = lowest;
+ do {
+ if ((acc_mgr->allowed_subset_mask & (1 << i))) {
+ acc_mgr->allowed_subset_mask &= ~(1 << i);
+ acc_mgr->allowed_subset_mask_count--;
+ diff++;
+ if (diff == 0)
+ break;
+ }
+ i = (i + 1) % 10;
+ } while(i != lowest);
+ }
+
+ acc_mgr_enable_rotation_cond(acc_mgr);
+
+ /* if we updated the set, notify about it */
+ if (curr_len != acc_mgr->allowed_subset_mask_count)
+ gsm_bts_set_system_infos(acc_mgr->bts);
+
+}
+
+static void do_acc_rotate_step(void *data)
+{
+ struct acc_mgr *acc_mgr = data;
+ int i;
+ uint16_t old_mask = acc_mgr->allowed_subset_mask;
+
+ /* Assumption: The size of the subset didn't change, that's handled by
+ * acc_mgr_subset_length_changed()
+ */
+
+ /* Assumption: Rotation timer has been disabled if no ACC is allowed */
+ OSMO_ASSERT(acc_mgr->allowed_subset_mask_count != 0)
+
+ /* One ACC is rotated at a time: Drop lowest ACC and add next from highest ACC */
+ uint8_t lowest = get_lowest_allowed_acc(acc_mgr->allowed_subset_mask);
+ uint8_t highest = get_highest_allowed_acc(acc_mgr->allowed_subset_mask);
+
+ acc_mgr->allowed_subset_mask &= ~(1 << lowest);
+ i = (highest + 1) % 10;
+ do {
+ if (!acc_is_permanently_barred(acc_mgr->bts, i) &&
+ !(acc_mgr->allowed_subset_mask & (1 << i))) {
+ /* found first one which can be allowed, do it and be done */
+ acc_mgr->allowed_subset_mask &= (1 << i);
+ acc_mgr->allowed_subset_mask_count++;
+ break;
+ }
+ i = (i + 1 ) % 10;
+ } while (i != (highest + 1) % 10);
+
+ if (old_mask != acc_mgr->allowed_subset_mask) {
+ LOG_BTS(acc_mgr->bts, DRSL, LOGL_INFO,
+ "ACC: New ACC allowed subset 0x%" PRIx16 " -> 0x%" PRIx16
+ " (allowed=%" PRIu8 ", adm_len=%" PRIu8 ", ramp_len=%" PRIu8 ")\n",
+ old_mask, acc_mgr->allowed_subset_mask,
+ acc_mgr->allowed_subset_mask_count,
+ acc_mgr->len_allowed_adm, acc_mgr->len_allowed_ramp);
+ gsm_bts_set_system_infos(acc_mgr->bts);
+ }
+
+ osmo_timer_schedule(&acc_mgr->rotate_timer, acc_mgr->rotation_time_sec, 0);
+}
+
+void acc_mgr_init(struct acc_mgr *acc_mgr, struct gsm_bts *bts)
+{
+ acc_mgr->bts = bts;
+ acc_mgr->len_allowed_adm = 10; /* Allow all by default */
+ acc_mgr->len_allowed_ramp = 10;
+ acc_mgr->rotation_time_sec = ACC_MGR_QUANTUM_DEFAULT;
+ osmo_timer_setup(&acc_mgr->rotate_timer, do_acc_rotate_step, acc_mgr);
+ /* FIXME: Don't update SI yet, avoid crash due to bts->model being NULL */
+ acc_mgr_gen_subset(acc_mgr, false);
+}
+
+uint8_t acc_mgr_get_len_allowed_adm(struct acc_mgr *acc_mgr)
+{
+ return acc_mgr->len_allowed_adm;
+}
+
+uint8_t acc_mgr_get_len_allowed_ramp(struct acc_mgr *acc_mgr)
+{
+ return acc_mgr->len_allowed_ramp;
+}
+
+void acc_mgr_set_len_allowed_adm(struct acc_mgr *acc_mgr, uint8_t len_allowed_adm)
+{
+ uint8_t old_len;
+ if (acc_mgr->len_allowed_adm == len_allowed_adm)
+ return;
+
+ LOG_BTS(acc_mgr->bts, DRSL, LOGL_DEBUG,
+ "ACC: administrative rotate subset size set to %" PRIu8 "\n", len_allowed_adm);
+
+ old_len = acc_mgr_subset_len(acc_mgr);
+ acc_mgr->len_allowed_adm = len_allowed_adm;
+ if (old_len != acc_mgr_subset_len(acc_mgr))
+ acc_mgr_subset_length_changed(acc_mgr);
+}
+void acc_mgr_set_len_allowed_ramp(struct acc_mgr *acc_mgr, uint8_t len_allowed_ramp)
+{
+ uint8_t old_len;
+ if (acc_mgr->len_allowed_ramp == len_allowed_ramp)
+ return;
+
+ LOG_BTS(acc_mgr->bts, DRSL, LOGL_DEBUG,
+ "ACC: ramping rotate subset size set to %" PRIu8 "\n", len_allowed_ramp);
+
+ old_len = acc_mgr_subset_len(acc_mgr);
+ acc_mgr->len_allowed_ramp = len_allowed_ramp;
+ if (old_len != acc_mgr_subset_len(acc_mgr))
+ acc_mgr_subset_length_changed(acc_mgr);
+}
+
+void acc_mgr_set_rotation_time(struct acc_mgr *acc_mgr, uint32_t rotation_time_sec)
+{
+ LOG_BTS(acc_mgr->bts, DRSL, LOGL_DEBUG,
+ "ACC: rotate subset time set to %" PRIu32 "\n", rotation_time_sec);
+ acc_mgr->rotation_time_sec = rotation_time_sec;
+}
+
+void acc_mgr_perm_subset_changed(struct acc_mgr *acc_mgr, struct gsm48_rach_control *rach_control)
+{
+ /* Even if amount is the same, the allowed/barred ones may have changed,
+ * so let's retrigger generation of an entire subset rather than
+ * rotating it */
+ acc_mgr_gen_subset(acc_mgr, true);
+}
+
+/*!
+ * Potentially mark certain Access Control Classes (ACCs) as barred in accordance to ACC policy.
+ * \param[in] acc_mgr Pointer to acc_mgr structure.
+ * \param[in] rach_control RACH control parameters in which barred ACCs will be configured.
+ */
+void acc_mgr_apply_acc(struct acc_mgr *acc_mgr, struct gsm48_rach_control *rach_control)
+{
+ rach_control->t2 |= acc_mgr_get_barred_t2(acc_mgr);
+ rach_control->t3 |= acc_mgr_get_barred_t3(acc_mgr);
+}
+
+
+//////////////////////////
+// acc_ramp
+//////////////////////////
static unsigned int get_next_step_interval(struct acc_ramp *acc_ramp)
{
struct gsm_bts *bts = acc_ramp->bts;
@@ -104,42 +340,14 @@
static void do_acc_ramping_step(void *data)
{
struct acc_ramp *acc_ramp = data;
- int i;
+ struct acc_mgr *acc_mgr = &acc_ramp->bts->acc_mgr;
+ uint8_t old_len = acc_mgr_get_len_allowed_ramp(acc_mgr);
+ uint8_t new_len = OSMO_MIN(10, old_len + acc_ramp->step_size);
- /* Shortcut in case we only do one ramping step. */
- if (acc_ramp->step_size == ACC_RAMP_STEP_SIZE_MAX) {
- allow_all_accs(acc_ramp);
- gsm_bts_set_system_infos(acc_ramp->bts);
- return;
- }
-
- /* Allow 'step_size' ACCs, starting from ACC0. ACC9 will be allowed last. */
- for (i = 0; i < acc_ramp->step_size; i++) {
- int idx = ffs(acc_ramp_get_barred_t3(acc_ramp));
- if (idx > 0) {
- /* One of ACC0-ACC7 is still bared. */
- unsigned int acc = idx - 1;
- if (!acc_is_permanently_barred(acc_ramp->bts, acc))
- allow_one_acc(acc_ramp, acc);
- } else {
- idx = ffs(acc_ramp_get_barred_t2(acc_ramp));
- if (idx == 1 || idx == 2) {
- /* ACC8 or ACC9 is still barred. */
- unsigned int acc = idx - 1 + 8;
- if (!acc_is_permanently_barred(acc_ramp->bts, acc))
- allow_one_acc(acc_ramp, acc);
- } else {
- /* All ACCs are now allowed. */
- break;
- }
- }
- }
-
- gsm_bts_set_system_infos(acc_ramp->bts);
+ acc_mgr_set_len_allowed_ramp(acc_mgr, new_len);
/* If we have not allowed all ACCs yet, schedule another ramping step. */
- if (acc_ramp_get_barred_t2(acc_ramp) != 0x00 ||
- acc_ramp_get_barred_t3(acc_ramp) != 0x00)
+ if (new_len != 10)
osmo_timer_schedule(&acc_ramp->step_timer, get_next_step_interval(acc_ramp), 0);
}
@@ -279,7 +487,6 @@
acc_ramp->step_size = ACC_RAMP_STEP_SIZE_DEFAULT;
acc_ramp->step_interval_sec = ACC_RAMP_STEP_INTERVAL_MIN;
acc_ramp->step_interval_is_fixed = false;
- allow_all_accs(acc_ramp);
osmo_timer_setup(&acc_ramp->step_timer, do_acc_ramping_step, acc_ramp);
osmo_signal_register_handler(SS_NM, acc_ramp_nm_sig_cb, acc_ramp);
}
@@ -344,7 +551,7 @@
if (acc_ramp_is_enabled(acc_ramp)) {
/* Set all available ACCs to barred and start ramping up. */
- barr_all_accs(acc_ramp);
+ acc_mgr_set_len_allowed_ramp(&acc_ramp->bts->acc_mgr, 0);
do_acc_ramping_step(acc_ramp);
}
}
@@ -358,5 +565,5 @@
if (osmo_timer_pending(&acc_ramp->step_timer))
osmo_timer_del(&acc_ramp->step_timer);
- allow_all_accs(acc_ramp);
+ acc_mgr_set_len_allowed_ramp(&acc_ramp->bts->acc_mgr, 10);
}
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 11e51be..2afb8f6 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -404,6 +404,8 @@
VTY_NEWLINE);
vty_out(vty, " Cell Reselection Hysteresis: %u dBm%s",
bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
+ vty_out(vty, " Access Control Class rotation allow mask: 0x%" PRIx16 "%s",
+ bts->acc_mgr.allowed_subset_mask, VTY_NEWLINE);
vty_out(vty, " Access Control Class ramping: %senabled%s",
acc_ramp_is_enabled(&bts->acc_ramp) ? "" : "not ", VTY_NEWLINE);
if (acc_ramp_is_enabled(&bts->acc_ramp)) {
@@ -948,6 +950,10 @@
for (i = 0; i < 8; i++)
if ((i != 2) && (bts->si_common.rach_control.t2 & (0x1 << i)))
vty_out(vty, " rach access-control-class %d barred%s", i+8, VTY_NEWLINE);
+ if (bts->acc_mgr.len_allowed_adm < 10)
+ vty_out(vty, " access-control-class-rotate %" PRIu8 "%s", bts->acc_mgr.len_allowed_adm, VTY_NEWLINE);
+ if (bts->acc_mgr.rotation_time_sec != ACC_MGR_QUANTUM_DEFAULT)
+ vty_out(vty, " access-control-class-rotate-quantum %" PRIu32 "%s", bts->acc_mgr.rotation_time_sec, VTY_NEWLINE);
vty_out(vty, " %saccess-control-class-ramping%s", acc_ramp_is_enabled(&bts->acc_ramp) ? "" : "no ", VTY_NEWLINE);
if (!acc_ramp_step_interval_is_dynamic(&bts->acc_ramp)) {
vty_out(vty, " access-control-class-ramping-step-interval %u%s",
@@ -2745,6 +2751,9 @@
else
bts->si_common.rach_control.t2 |= (0x1 << (control_class - 8));
+ if (control_class < 10)
+ acc_mgr_perm_subset_changed(&bts->acc_mgr, &bts->si_common.rach_control);
+
return CMD_SUCCESS;
}
@@ -3640,6 +3649,30 @@
return CMD_SUCCESS;
}
+DEFUN(cfg_bts_acc_rotate,
+ cfg_bts_acc_rotate_cmd,
+ "access-control-rotate <0-10>",
+ "Enable Access Control Class allowed subset rotation\n"
+ "Size of the rotating allowed ACC 0-9 subset (default=10, no subset)\n")
+{
+ struct gsm_bts *bts = vty->index;
+ int len_allowed_adm = atoi(argv[0]);
+ acc_mgr_set_len_allowed_adm(&bts->acc_mgr, len_allowed_adm);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_acc_rotate_quantum,
+ cfg_bts_acc_rotate_quantum_cmd,
+ "access-control-rotate-quantum <1-65535>",
+ "Time between rotation of ACC 0-9 generated subsets\n"
+ "Time in seconds (default=" OSMO_STRINGIFY_VAL(ACC_MGR_QUANTUM_DEFAULT) ")\n")
+{
+ struct gsm_bts *bts = vty->index;
+ uint32_t rotation_time_sec = (uint32_t)atoi(argv[0]);
+ acc_mgr_set_rotation_time(&bts->acc_mgr, rotation_time_sec);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_bts_acc_ramping,
cfg_bts_acc_ramping_cmd,
"access-control-class-ramping",
@@ -6493,6 +6526,8 @@
install_element(BTS_NODE, &cfg_bts_amr_hr_hyst3_cmd);
install_element(BTS_NODE, &cfg_bts_amr_hr_start_mode_cmd);
install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd);
+ install_element(BTS_NODE, &cfg_bts_acc_rotate_cmd);
+ install_element(BTS_NODE, &cfg_bts_acc_rotate_quantum_cmd);
install_element(BTS_NODE, &cfg_bts_acc_ramping_cmd);
install_element(BTS_NODE, &cfg_bts_no_acc_ramping_cmd);
install_element(BTS_NODE, &cfg_bts_acc_ramping_step_interval_cmd);
diff --git a/src/osmo-bsc/bts.c b/src/osmo-bsc/bts.c
index 7794024..4318b7e 100644
--- a/src/osmo-bsc/bts.c
+++ b/src/osmo-bsc/bts.c
@@ -387,6 +387,7 @@
bts_init_cbch_state(&bts->cbch_basic, bts);
bts_init_cbch_state(&bts->cbch_extended, bts);
+ acc_mgr_init(&bts->acc_mgr, bts);
acc_ramp_init(&bts->acc_ramp, bts);
return bts;
diff --git a/src/osmo-bsc/system_information.c b/src/osmo-bsc/system_information.c
index 13d0f46..be70600 100644
--- a/src/osmo-bsc/system_information.c
+++ b/src/osmo-bsc/system_information.c
@@ -723,8 +723,7 @@
list_arfcn(si1->cell_channel_description, 0xce, "Serving cell:");
si1->rach_control = bts->si_common.rach_control;
- if (acc_ramp_is_enabled(&bts->acc_ramp))
- acc_ramp_apply(&si1->rach_control, &bts->acc_ramp);
+ acc_mgr_apply_acc(&bts->acc_mgr, &si1->rach_control);
/*
* SI1 Rest Octets (10.5.2.32), contains NCH position and band
@@ -755,8 +754,7 @@
si2->ncc_permitted = bts->si_common.ncc_permitted;
si2->rach_control = bts->si_common.rach_control;
- if (acc_ramp_is_enabled(&bts->acc_ramp))
- acc_ramp_apply(&si2->rach_control, &bts->acc_ramp);
+ acc_mgr_apply_acc(&bts->acc_mgr, &si2->rach_control);
return sizeof(*si2);
}
@@ -790,8 +788,7 @@
bts->si_valid &= ~(1 << SYSINFO_TYPE_2bis);
si2b->rach_control = bts->si_common.rach_control;
- if (acc_ramp_is_enabled(&bts->acc_ramp))
- acc_ramp_apply(&si2b->rach_control, &bts->acc_ramp);
+ acc_mgr_apply_acc(&bts->acc_mgr, &si2b->rach_control);
/* SI2bis Rest Octets as per 3GPP TS 44.018 §10.5.2.33 */
rc = rest_octets_si2bis(si2b->rest_octets);
@@ -912,8 +909,7 @@
si3->cell_options = bts->si_common.cell_options;
si3->cell_sel_par = bts->si_common.cell_sel_par;
si3->rach_control = bts->si_common.rach_control;
- if (acc_ramp_is_enabled(&bts->acc_ramp))
- acc_ramp_apply(&si3->rach_control, &bts->acc_ramp);
+ acc_mgr_apply_acc(&bts->acc_mgr, &si3->rach_control);
/* allow/disallow DTXu */
gsm48_set_dtx(&si3->cell_options, bts->dtxu, bts->dtxu, true);
@@ -962,8 +958,7 @@
gsm48_generate_lai2(&si4->lai, bts_lai(bts));
si4->cell_sel_par = bts->si_common.cell_sel_par;
si4->rach_control = bts->si_common.rach_control;
- if (acc_ramp_is_enabled(&bts->acc_ramp))
- acc_ramp_apply(&si4->rach_control, &bts->acc_ramp);
+ acc_mgr_apply_acc(&bts->acc_mgr, &si4->rach_control);
/* Optional: CBCH Channel Description + CBCH Mobile Allocation */
cbch_lchan = gsm_bts_get_cbch(bts);
diff --git a/tests/gsm0408/gsm0408_test.c b/tests/gsm0408/gsm0408_test.c
index e53b83a..35531f8 100644
--- a/tests/gsm0408/gsm0408_test.c
+++ b/tests/gsm0408/gsm0408_test.c
@@ -140,6 +140,8 @@
{
osmo_stat_item_group_free(bts->bts_statg);
rate_ctr_group_free(bts->bts_ctrs);
+ if (osmo_timer_pending(&bts->acc_mgr.rotate_timer))
+ osmo_timer_del(&bts->acc_mgr.rotate_timer);
/* no need to llist_del(&bts->list), we never registered the bts there. */
talloc_free(bts);
printf("BTS deallocated OK in %s()\n", msg);
--
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/19303
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I952c9eeae02809c7184078c655574ec817902e06
Gerrit-Change-Number: 19303
Gerrit-PatchSet: 1
Gerrit-Owner: pespin <pespin at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200716/995bcde4/attachment.htm>