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>