aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/acc.h91
-rw-r--r--include/osmocom/bsc/vty.h1
-rw-r--r--src/osmo-bsc/acc.c269
-rw-r--r--src/osmo-bsc/bsc_vty.c351
-rw-r--r--src/osmo-bsc/osmo_bsc_main.c9
-rw-r--r--tests/acc.vty159
-rw-r--r--tests/acc/acc_test.c72
7 files changed, 744 insertions, 208 deletions
diff --git a/include/osmocom/bsc/acc.h b/include/osmocom/bsc/acc.h
index c7be38cb3..b282605cc 100644
--- a/include/osmocom/bsc/acc.h
+++ b/include/osmocom/bsc/acc.h
@@ -77,14 +77,21 @@ void acc_mgr_apply_acc(struct acc_mgr *acc_mgr, struct gsm48_rach_control *rach_
#define ACC_RAMP_CHAN_LOAD_THRESHOLD_LOW 71
#define ACC_RAMP_CHAN_LOAD_THRESHOLD_UP 89
+#define ACC_RAMP_CPU_LOAD_THRESHOLD_LOW 71
+#define ACC_RAMP_CPU_LOAD_THRESHOLD_UP 89
+
/*!
* Data structure used to manage ACC ramping. Please avoid setting or reading fields
* in this structure directly. Use the accessor functions below instead.
*/
-struct acc_ramp {
- struct gsm_bts *bts; /*!< backpointer to BTS using this ACC ramp */
-
- bool acc_ramping_enabled; /*!< whether ACC ramping is enabled */
+struct acc_ramp_thresh_load;
+struct acc_ramp_thresh_load_ops {
+ bool (*can_increase_len_allowed_ramp)(const struct acc_ramp_thresh_load *ld);
+ bool (*can_decrease_len_allowed_ramp)(const struct acc_ramp_thresh_load *ld);
+};
+struct acc_ramp_thresh_load {
+ struct acc_ramp *acc_ramp; /* backpointer */
+ bool enabled; /*!< whether ACC ramping type is enabled */
/*!
* This controls the maximum number of ACCs to allow per ramping step (1 - 10).
@@ -103,67 +110,99 @@ struct acc_ramp {
struct osmo_timer_list step_timer;
/*!
- * Channel Load Upper/Lower Thresholds:
+ * Load Upper/Lower Thresholds:
* They control how ramping subset size of allowed ACCs changes in
- * relation to current channel load (%, 0-100): Under the lower
+ * relation to current load (%, 0-100): Under the lower
* threshold, subset size may be increased; above the upper threshold,
* subset size may be decreased.
*/
- unsigned int chan_load_lower_threshold;
- unsigned int chan_load_upper_threshold;
+ unsigned int lower_threshold;
+ unsigned int upper_threshold;
+ struct acc_ramp_thresh_load_ops ops;
+};
+struct acc_ramp {
+ struct gsm_bts *bts; /*!< backpointer to BTS using this ACC ramp */
+
+ struct acc_ramp_thresh_load chanld;
+ struct acc_ramp_thresh_load cpuld;
};
+/*************
+ * CHAN LOAD *
+ *************/
/*!
- * Enable or disable ACC ramping.
+ * Enable or disable ACC ramping based on Chan Load.
* When enabled, ramping begins once acc_ramp_start() is called.
* When disabled, an ACC ramping process in progress will continue
* unless acc_ramp_abort() is called as well.
* \param[in] acc_ramp Pointer to acc_ramp structure.
*/
-static inline void acc_ramp_set_enabled(struct acc_ramp *acc_ramp, bool enable)
+static inline void acc_ramp_thld_set_enabled(struct acc_ramp_thresh_load *thld, bool enable)
{
- acc_ramp->acc_ramping_enabled = enable;
+ thld->enabled = enable;
}
/*!
- * Return true if ACC ramping is currently enabled, else false.
+ * Return true if ACC ramping based on Chan Load is currently enabled, else false.
* \param[in] acc_ramp Pointer to acc_ramp structure.
*/
-static inline bool acc_ramp_is_enabled(struct acc_ramp *acc_ramp)
+static inline bool acc_ramp_thld_is_enabled(const struct acc_ramp_thresh_load *thld)
{
- return acc_ramp->acc_ramping_enabled;
+ return thld->enabled;
}
/*!
- * Return the current ACC ramp step size.
+ * Return the current Chan Load ACC ramp step size.
* \param[in] acc_ramp Pointer to acc_ramp structure.
*/
-static inline unsigned int acc_ramp_get_step_size(struct acc_ramp *acc_ramp)
+static inline unsigned int acc_ramp_thld_get_step_size(const struct acc_ramp_thresh_load *thld)
{
- return acc_ramp->step_size;
+ return thld->step_size;
}
/*!
- * Return the current ACC ramp step interval (in seconds)
+ * Return the current Chan Load ACC ramp step interval (in seconds)
* \param[in] acc_ramp Pointer to acc_ramp structure.
*/
-static inline unsigned int acc_ramp_get_step_interval(struct acc_ramp *acc_ramp)
+static inline unsigned int acc_ramp_thld_get_step_interval(const struct acc_ramp_thresh_load *thld)
{
- return acc_ramp->step_interval_sec;
+ return thld->step_interval_sec;
}
/*!
- * Return the current ACC ramp step interval (in seconds)
+ * Return the current Chan Load ACC ramp step interval (in seconds)
* \param[in] acc_ramp Pointer to acc_ramp structure.
*/
-static inline unsigned int acc_ramp_is_running(struct acc_ramp *acc_ramp)
+static inline unsigned int acc_ramp_thld_is_running(struct acc_ramp_thresh_load *thld)
+{
+ return osmo_timer_pending(&thld->step_timer);
+}
+
+int acc_ramp_thld_set_step_size(struct acc_ramp_thresh_load *thld, unsigned int step_size);
+int acc_ramp_thld_set_step_interval(struct acc_ramp_thresh_load *thld, unsigned int step_interval);
+int acc_ramp_thld_set_thresholds(struct acc_ramp_thresh_load *thld, unsigned int low_threshold, unsigned int up_threshold);
+
+/*************
+ * GENERIC *
+ *************/
+
+static inline bool acc_ramp_is_enabled(const struct acc_ramp *acc_ramp)
+{
+ return acc_ramp_thld_is_enabled(&acc_ramp->chanld) ||
+ acc_ramp_thld_is_enabled(&acc_ramp->cpuld);
+}
+
+static inline bool acc_ramp_can_increase_len_allowed_ramp(const struct acc_ramp *acc_ramp)
{
- return acc_ramp->step_interval_sec;
+ if (acc_ramp_thld_is_enabled(&acc_ramp->chanld) &&
+ !acc_ramp->chanld.ops.can_increase_len_allowed_ramp(&acc_ramp->chanld))
+ return false;
+ if (acc_ramp_thld_is_enabled(&acc_ramp->cpuld) &&
+ !acc_ramp->cpuld.ops.can_increase_len_allowed_ramp(&acc_ramp->cpuld))
+ return false;
+ return true;
}
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);
-int acc_ramp_set_chan_load_thresholds(struct acc_ramp *acc_ramp, unsigned int low_threshold, unsigned int up_threshold);
void acc_ramp_trigger(struct acc_ramp *acc_ramp);
void acc_ramp_abort(struct acc_ramp *acc_ramp);
diff --git a/include/osmocom/bsc/vty.h b/include/osmocom/bsc/vty.h
index 92f7932bb..f85b3e8cf 100644
--- a/include/osmocom/bsc/vty.h
+++ b/include/osmocom/bsc/vty.h
@@ -17,6 +17,7 @@ enum bsc_vty_node {
BTS_NODE,
TRX_NODE,
TS_NODE,
+ ACC_RAMP_NODE,
OML_NODE,
NAT_NODE,
NAT_BSC_NODE,
diff --git a/src/osmo-bsc/acc.c b/src/osmo-bsc/acc.c
index 06f96c625..4ebf85cd0 100644
--- a/src/osmo-bsc/acc.c
+++ b/src/osmo-bsc/acc.c
@@ -372,9 +372,108 @@ void acc_mgr_apply_acc(struct acc_mgr *acc_mgr, struct gsm48_rach_control *rach_
//////////////////////////
// acc_ramp
//////////////////////////
+
+/*!
+ * Change the ramping step size which controls how many ACCs will be allowed per ramping step.
+ * Returns negative on error (step_size out of range), else zero.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ * \param[in] step_size The new step size value.
+ */
+int acc_ramp_thld_set_step_size(struct acc_ramp_thresh_load *thld, unsigned int step_size)
+{
+ if (step_size < ACC_RAMP_STEP_SIZE_MIN || step_size > ACC_RAMP_STEP_SIZE_MAX)
+ return -ERANGE;
+
+ thld->step_size = step_size;
+ LOG_BTS(thld->acc_ramp->bts, DRSL, LOGL_DEBUG, "ACC RAMP: ramping step size set to %u\n", step_size);
+ return 0;
+}
+
+/*!
+ * Change the ramping step interval to a fixed value. Unless this function is called,
+ * the interval is automatically scaled to the BTS channel load average.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ * \param[in] step_interval The new fixed step interval in seconds.
+ */
+int acc_ramp_thld_set_step_interval(struct acc_ramp_thresh_load *thld, unsigned int step_interval)
+{
+ if (step_interval < ACC_RAMP_STEP_INTERVAL_MIN || step_interval > ACC_RAMP_STEP_INTERVAL_MAX)
+ return -ERANGE;
+
+ thld->step_interval_sec = step_interval;
+ LOG_BTS(thld->acc_ramp->bts, DRSL, LOGL_DEBUG, "ACC RAMP: ramping step interval set to %u seconds\n",
+ step_interval);
+ return 0;
+}
+
+/*!
+ * Change the ramping channel load thresholds. They control how ramping subset
+ * size of allowed ACCs changes in relation to current load (%, 0-100):
+ * Under the lower threshold, subset size may be increased; above the upper
+ * threshold, subset size may be decreased.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ * \param[in] low_threshold The new minimum threshold: values under it allow for increasing the ramping subset size.
+ * \param[in] up_threshold The new maximum threshold: values under it allow for increasing the ramping subset size.
+ */
+int acc_ramp_thld_set_thresholds(struct acc_ramp_thresh_load *thld, unsigned int low_threshold, unsigned int up_threshold)
+{
+ /* for instance, high=49 and lower=50 makes sense:
+ [50-100] -> decrease, [0-49] -> increase */
+ if ((int)up_threshold - (int)low_threshold < -1)
+ return -ERANGE;
+
+ thld->lower_threshold = low_threshold;
+ thld->upper_threshold = up_threshold;
+ return 0;
+}
+
+
+/*!
+ * Determine whether Chan Load conditions are good enough to allow increasing
+ * the ramping size of allowed ACCs.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ */
+static bool acc_ramp_chanld_can_increase_len_allowed_ramp(const struct acc_ramp_thresh_load *thld)
+{
+ return thld->acc_ramp->bts->chan_load_avg > thld->upper_threshold;
+}
+
+/*!
+ * Determine whether Chan Load conditions are bad enough to allow decreasing
+ * the ramping size of allowed ACCs.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ */
+static bool acc_ramp_chanld_can_decrease_len_allowed_ramp(const struct acc_ramp_thresh_load *thld)
+{
+ return thld->acc_ramp->bts->chan_load_avg < thld->lower_threshold;
+}
+
+/*!
+ * Determine whether CPU Load conditions are good enough to allow increasing
+ * the ramping size of allowed ACCs.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ */
+static bool acc_ramp_cpuld_can_increase_len_allowed_ramp(const struct acc_ramp_thresh_load *thld)
+{
+ /* TODO: implement */
+ return true;
+}
+
+/*!
+ * Determine whether CPU Load conditions are bad enough to allow decreasing
+ * the ramping size of allowed ACCs.
+ * \param[in] acc_ramp Pointer to acc_ramp structure.
+ */
+static bool acc_ramp_cpuld_can_decrease_len_allowed_ramp(const struct acc_ramp_thresh_load *thld)
+{
+ /* TODO: implement */
+ return false;
+}
+
static void do_acc_ramping_step(void *data)
{
- struct acc_ramp *acc_ramp = data;
+ struct acc_ramp_thresh_load *thld = data;
+ struct acc_ramp *acc_ramp = thld->acc_ramp;
struct gsm_bts *bts = acc_ramp->bts;
struct acc_mgr *acc_mgr = &bts->acc_mgr;
@@ -385,29 +484,33 @@ static void do_acc_ramping_step(void *data)
* least 1 ACC at ramping lvl to allow subscribers to eventually use the
* network. If total barring is desired, it can be controlled by the
* adminsitrative subset length through VTY.
+ *
* Remark inc: Never try going over the admin subset size, since it
* wouldn't change final subset size anyway and it would create a fake
* sense of safe load handling capacity. If then load became high, being
* on upper size would mean the BTS requires more time to effectively
* drop down the final subset size, hence delaying recovery.
+ *
+ * Remark general: We must follow all restrictions for all enabled
+ * ramping methods in order to increase subset size, but lowering is
+ * enough based on current ramping method stepping.
*/
- if (bts->chan_load_avg > acc_ramp->chan_load_upper_threshold)
- new_len = (uint8_t)OSMO_MAX(1, (int)(old_len - acc_ramp->step_size));
- else if (bts->chan_load_avg < acc_ramp->chan_load_lower_threshold)
+ if (acc_ramp_can_increase_len_allowed_ramp(acc_ramp))
+ new_len = (uint8_t)OSMO_MAX(1, (int)(old_len - thld->step_size));
+ else if (thld->ops.can_decrease_len_allowed_ramp(thld))
new_len = OSMO_MIN(acc_mgr_get_len_allowed_adm(acc_mgr),
- old_len + acc_ramp->step_size);
+ old_len + thld->step_size);
else
new_len = old_len;
if (new_len != old_len) {
LOG_BTS(bts, DRSL, LOGL_DEBUG,
"ACC RAMP: changing ramping subset size %" PRIu8
- " -> %" PRIu8 ", chan_load_avg=%" PRIu8 "%%\n",
- old_len, new_len, bts->chan_load_avg);
+ " -> %" PRIu8 "\n", old_len, new_len);
acc_mgr_set_len_allowed_ramp(acc_mgr, new_len);
}
- osmo_timer_schedule(&acc_ramp->step_timer, acc_ramp->step_interval_sec, 0);
+ osmo_timer_schedule(&thld->step_timer, thld->step_interval_sec, 0);
}
/* Implements osmo_signal_cbfn() -- trigger or abort ACC ramping upon changes RF lock state. */
@@ -530,6 +633,30 @@ static int acc_ramp_nm_sig_cb(unsigned int subsys, unsigned int signal, void *ha
return 0;
}
+static struct acc_ramp_thresh_load chanld_defs = {
+ .enabled = false,
+ .step_size = ACC_RAMP_STEP_SIZE_DEFAULT,
+ .step_interval_sec = ACC_RAMP_STEP_INTERVAL_MIN,
+ .lower_threshold = ACC_RAMP_CHAN_LOAD_THRESHOLD_LOW,
+ .upper_threshold = ACC_RAMP_CHAN_LOAD_THRESHOLD_UP,
+ .ops = {
+ .can_increase_len_allowed_ramp = acc_ramp_chanld_can_increase_len_allowed_ramp,
+ .can_decrease_len_allowed_ramp = acc_ramp_chanld_can_decrease_len_allowed_ramp,
+ },
+};
+
+static struct acc_ramp_thresh_load cpuld_defs = {
+ .enabled = false,
+ .step_size = ACC_RAMP_STEP_SIZE_DEFAULT,
+ .step_interval_sec = ACC_RAMP_STEP_INTERVAL_MIN,
+ .lower_threshold = ACC_RAMP_CPU_LOAD_THRESHOLD_LOW,
+ .upper_threshold = ACC_RAMP_CPU_LOAD_THRESHOLD_UP,
+ .ops = {
+ .can_increase_len_allowed_ramp = acc_ramp_cpuld_can_increase_len_allowed_ramp,
+ .can_decrease_len_allowed_ramp = acc_ramp_cpuld_can_decrease_len_allowed_ramp,
+ },
+};
+
/*!
* Initialize an acc_ramp data structure.
* Storage for this structure must be provided by the caller.
@@ -542,67 +669,16 @@ static int acc_ramp_nm_sig_cb(unsigned int subsys, unsigned int signal, void *ha
void acc_ramp_init(struct acc_ramp *acc_ramp, struct gsm_bts *bts)
{
acc_ramp->bts = bts;
- acc_ramp_set_enabled(acc_ramp, false);
- acc_ramp->step_size = ACC_RAMP_STEP_SIZE_DEFAULT;
- acc_ramp->step_interval_sec = ACC_RAMP_STEP_INTERVAL_MIN;
- acc_ramp->chan_load_lower_threshold = ACC_RAMP_CHAN_LOAD_THRESHOLD_LOW;
- acc_ramp->chan_load_upper_threshold = ACC_RAMP_CHAN_LOAD_THRESHOLD_UP;
- 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);
-}
-/*!
- * Change the ramping step size which controls how many ACCs will be allowed per ramping step.
- * Returns negative on error (step_size out of range), else zero.
- * \param[in] acc_ramp Pointer to acc_ramp structure.
- * \param[in] step_size The new step size value.
- */
-int acc_ramp_set_step_size(struct acc_ramp *acc_ramp, unsigned int step_size)
-{
- if (step_size < ACC_RAMP_STEP_SIZE_MIN || step_size > ACC_RAMP_STEP_SIZE_MAX)
- return -ERANGE;
+ memcpy(&acc_ramp->chanld, &chanld_defs, sizeof(chanld_defs));
+ acc_ramp->chanld.acc_ramp = acc_ramp;
+ osmo_timer_setup(&acc_ramp->chanld.step_timer, do_acc_ramping_step, &acc_ramp->chanld);
- acc_ramp->step_size = step_size;
- LOG_BTS(acc_ramp->bts, DRSL, LOGL_DEBUG, "ACC RAMP: ramping step size set to %u\n", step_size);
- return 0;
-}
+ memcpy(&acc_ramp->cpuld, &cpuld_defs, sizeof(cpuld_defs));
+ acc_ramp->cpuld.acc_ramp = acc_ramp;
+ osmo_timer_setup(&acc_ramp->cpuld.step_timer, do_acc_ramping_step, &acc_ramp->cpuld);
-/*!
- * Change the ramping step interval to a fixed value. Unless this function is called,
- * the interval is automatically scaled to the BTS channel load average.
- * \param[in] acc_ramp Pointer to acc_ramp structure.
- * \param[in] step_interval The new fixed step interval in seconds.
- */
-int acc_ramp_set_step_interval(struct acc_ramp *acc_ramp, unsigned int step_interval)
-{
- if (step_interval < ACC_RAMP_STEP_INTERVAL_MIN || step_interval > ACC_RAMP_STEP_INTERVAL_MAX)
- return -ERANGE;
-
- acc_ramp->step_interval_sec = step_interval;
- LOG_BTS(acc_ramp->bts, DRSL, LOGL_DEBUG, "ACC RAMP: ramping step interval set to %u seconds\n",
- step_interval);
- return 0;
-}
-
-/*!
- * Change the ramping channel load thresholds. They control how ramping subset
- * size of allowed ACCs changes in relation to current channel load (%, 0-100):
- * Under the lower threshold, subset size may be increased; above the upper
- * threshold, subset size may be decreased.
- * \param[in] acc_ramp Pointer to acc_ramp structure.
- * \param[in] low_threshold The new minimum threshold: values under it allow for increasing the ramping subset size.
- * \param[in] up_threshold The new maximum threshold: values under it allow for increasing the ramping subset size.
- */
-int acc_ramp_set_chan_load_thresholds(struct acc_ramp *acc_ramp, unsigned int low_threshold, unsigned int up_threshold)
-{
- /* for instance, high=49 and lower=50 makes sense:
- [50-100] -> decrease, [0-49] -> increase */
- if ((int)up_threshold - (int)low_threshold < -1)
- return -ERANGE;
-
- acc_ramp->chan_load_lower_threshold = low_threshold;
- acc_ramp->chan_load_upper_threshold = up_threshold;
- return 0;
+ osmo_signal_register_handler(SS_NM, acc_ramp_nm_sig_cb, acc_ramp);
}
/*!
@@ -616,19 +692,49 @@ int acc_ramp_set_chan_load_thresholds(struct acc_ramp *acc_ramp, unsigned int lo
void acc_ramp_trigger(struct acc_ramp *acc_ramp)
{
if (acc_ramp_is_enabled(acc_ramp)) {
- if (osmo_timer_pending(&acc_ramp->step_timer))
- return; /* Already started, nothing to do */
-
- /* Set all available ACCs to barred and start ramping up. */
- acc_mgr_set_len_allowed_ramp(&acc_ramp->bts->acc_mgr, 0);
- if (acc_ramp->chan_load_lower_threshold == 0 &&
- acc_ramp->chan_load_upper_threshold == 100) {
- LOG_BTS(acc_ramp->bts, DRSL, LOGL_ERROR,
- "ACC RAMP: starting ramp up with 0 ACCs and "
- "no possibility to grow the allowed subset size! "
- "Check VTY cmd access-control-class-ramping-chan-load\n");
+ /* Some method is enabled, check what changed and whether we need to start/stop them */
+
+ if (!acc_ramp_thld_is_running(&acc_ramp->chanld) &&
+ !acc_ramp_thld_is_running(&acc_ramp->cpuld)) {
+ /* Set all available ACCs to barred and start ramping up some blocks below. */
+ acc_mgr_set_len_allowed_ramp(&acc_ramp->bts->acc_mgr, 0);
+ }
+ /* 2 conditons below: Check if some previously enabled method
+ * has become disabled, but we know at least one stays enabled,
+ * so no need to touch current len_allowed_ramp, it will keep
+ * being controlled by the method still enabled: */
+ if (!acc_ramp_thld_is_enabled(&acc_ramp->chanld) &&
+ acc_ramp_thld_is_running(&acc_ramp->chanld)) {
+ osmo_timer_del(&acc_ramp->chanld.step_timer);
+ }
+ if (!acc_ramp_thld_is_enabled(&acc_ramp->cpuld) &&
+ acc_ramp_thld_is_running(&acc_ramp->cpuld)) {
+ osmo_timer_del(&acc_ramp->cpuld.step_timer);
+ }
+
+ /* Start enabled threshold load methods which were not yet started */
+ if (acc_ramp_thld_is_enabled(&acc_ramp->chanld) &&
+ !acc_ramp_thld_is_running(&acc_ramp->chanld)) {
+ if (acc_ramp->chanld.lower_threshold == 0 &&
+ acc_ramp->chanld.upper_threshold == 100) {
+ LOG_BTS(acc_ramp->bts, DRSL, LOGL_ERROR,
+ "ACC RAMP: starting ramp up with 0 ACCs and "
+ "no possibility to grow the allowed subset size! "
+ "Check VTY cmd access-control-class-ramping-chan-load\n");
+ }
+ do_acc_ramping_step(&acc_ramp->chanld);
+ }
+ if (acc_ramp_thld_is_enabled(&acc_ramp->cpuld) &&
+ !acc_ramp_thld_is_running(&acc_ramp->cpuld)) {
+ if (acc_ramp->cpuld.lower_threshold == 0 &&
+ acc_ramp->cpuld.upper_threshold == 100) {
+ LOG_BTS(acc_ramp->bts, DRSL, LOGL_ERROR,
+ "ACC RAMP: starting ramp up with 0 ACCs and "
+ "no possibility to grow the allowed subset size! "
+ "Check VTY cmd access-control-class-ramping-chan-load\n");
+ }
+ do_acc_ramping_step(&acc_ramp->cpuld);
}
- do_acc_ramping_step(acc_ramp);
} else {
/* Abort any previously running ramping process and allow all available ACCs. */
acc_ramp_abort(acc_ramp);
@@ -641,8 +747,11 @@ void acc_ramp_trigger(struct acc_ramp *acc_ramp)
*/
void acc_ramp_abort(struct acc_ramp *acc_ramp)
{
- if (osmo_timer_pending(&acc_ramp->step_timer))
- osmo_timer_del(&acc_ramp->step_timer);
+ if (osmo_timer_pending(&acc_ramp->chanld.step_timer))
+ osmo_timer_del(&acc_ramp->chanld.step_timer);
+
+ if (osmo_timer_pending(&acc_ramp->cpuld.step_timer))
+ osmo_timer_del(&acc_ramp->cpuld.step_timer);
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 3c60f5f42..a7149e5d7 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -172,6 +172,12 @@ static struct cmd_node ts_node = {
1,
};
+static struct cmd_node acc_ramp_node = {
+ ACC_RAMP_NODE,
+ "%s(config-net-bts-acc-ramp)# ",
+ 1,
+};
+
static struct gsm_network *vty_global_gsm_network = NULL;
struct gsm_network *gsmnet_from_vty(struct vty *v)
@@ -359,6 +365,34 @@ static void bts_dump_vty_features(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " (not available)%s", VTY_NEWLINE);
}
+static void bts_dump_vty_acc_ramp(struct vty *vty, struct gsm_bts *bts)
+{
+ const struct acc_ramp_thresh_load *methods[] = {&bts->acc_ramp.chanld,
+ &bts->acc_ramp.cpuld};
+ const char *method_names[] = {"Channel Load", "CPU Load"};
+ const struct acc_ramp_thresh_load *m;
+ const char *name;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(methods); i++) {
+ m = methods[i];
+ name = method_names[i];
+ vty_out(vty, " Access Control Class ramping (%s): %senabled%s", name,
+ acc_ramp_thld_is_enabled(m) ? "" : "not ", VTY_NEWLINE);
+ if (acc_ramp_thld_is_enabled(m)) {
+ vty_out(vty, " Access Control Class ramping (%s) step interval: %u seconds%s",
+ name, acc_ramp_thld_get_step_interval(m), VTY_NEWLINE);
+ vty_out(vty, " Access Control Class (%s) thresholds: (%" PRIu8 ", %" PRIu8 ")%s",
+ name, bts->acc_ramp.chanld.lower_threshold,
+ bts->acc_ramp.chanld.upper_threshold, VTY_NEWLINE);
+ vty_out(vty, " enabling %u Access Control Class%s per %s ramping step%s",
+ acc_ramp_thld_get_step_size(m),
+ acc_ramp_thld_get_step_size(m) > 1 ? "es" : "",
+ name, VTY_NEWLINE);
+ }
+ }
+}
+
static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
{
struct pchan_load pl;
@@ -417,18 +451,7 @@ static void bts_dump_vty(struct vty *vty, struct gsm_bts *bts)
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)) {
- vty_out(vty, " Access Control Class ramping step interval: %u seconds%s",
- acc_ramp_get_step_interval(&bts->acc_ramp), VTY_NEWLINE);
- vty_out(vty, " Access Control Class channel load thresholds: (%" PRIu8 ", %" PRIu8 ")%s",
- bts->acc_ramp.chan_load_lower_threshold,
- bts->acc_ramp.chan_load_upper_threshold, VTY_NEWLINE);
- vty_out(vty, " enabling %u Access Control Class%s per ramping step%s",
- acc_ramp_get_step_size(&bts->acc_ramp),
- acc_ramp_get_step_size(&bts->acc_ramp) > 1 ? "es" : "", VTY_NEWLINE);
- }
+ bts_dump_vty_acc_ramp(vty, bts);
vty_out(vty, " RACH TX-Integer: %u%s", bts->si_common.rach_control.tx_integer,
VTY_NEWLINE);
vty_out(vty, " RACH Max transmissions: %u%s",
@@ -974,6 +997,33 @@ static void config_write_power_ctrl(struct vty *vty, unsigned int indent,
#undef cfg_out
+static void config_write_bts_acc_ramp(struct vty *vty, struct acc_ramp *acc_ramp, const char* prefix)
+{
+ vty_out(vty, "%saccess-control-class-ramp%s", prefix, VTY_NEWLINE);
+
+ vty_out(vty, "%s %schan-load-enabled%s", prefix,
+ acc_ramp_thld_is_enabled(&acc_ramp->chanld) ? "" : "no ", VTY_NEWLINE);
+ if (acc_ramp_thld_is_enabled(&acc_ramp->chanld)) {
+ vty_out(vty, "%s chan-load-step-interval %u%s", prefix,
+ acc_ramp_thld_get_step_interval(&acc_ramp->chanld), VTY_NEWLINE);
+ vty_out(vty, "%s chan-load-step-size %u%s", prefix,
+ acc_ramp_thld_get_step_size(&acc_ramp->chanld), VTY_NEWLINE);
+ vty_out(vty, "%s chan-load-thresholds %u %u%s", prefix,
+ acc_ramp->chanld.lower_threshold, acc_ramp->chanld.upper_threshold, VTY_NEWLINE);
+ }
+
+ vty_out(vty, "%s %scpu-load-enabled%s", prefix,
+ acc_ramp_thld_is_enabled(&acc_ramp->cpuld) ? "" : "no ", VTY_NEWLINE);
+ if (acc_ramp_thld_is_enabled(&acc_ramp->cpuld)) {
+ vty_out(vty, "%s cpu-load-step-interval %u%s", prefix,
+ acc_ramp_thld_get_step_interval(&acc_ramp->cpuld), VTY_NEWLINE);
+ vty_out(vty, "%s cpu-load-step-size %u%s", prefix,
+ acc_ramp_thld_get_step_size(&acc_ramp->cpuld), VTY_NEWLINE);
+ vty_out(vty, "%s cpu-load-thresholds %u %u%s", prefix,
+ acc_ramp->cpuld.lower_threshold, acc_ramp->cpuld.upper_threshold, VTY_NEWLINE);
+ }
+}
+
static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
{
int i;
@@ -1073,15 +1123,7 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
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_is_enabled(&bts->acc_ramp)) {
- vty_out(vty, " access-control-class-ramping-step-interval %u%s",
- acc_ramp_get_step_interval(&bts->acc_ramp), VTY_NEWLINE);
- vty_out(vty, " access-control-class-ramping-step-size %u%s", acc_ramp_get_step_size(&bts->acc_ramp),
- VTY_NEWLINE);
- vty_out(vty, " access-control-class-ramping-chan-load %u %u%s",
- bts->acc_ramp.chan_load_lower_threshold, bts->acc_ramp.chan_load_upper_threshold, VTY_NEWLINE);
- }
+ config_write_bts_acc_ramp(vty, &bts->acc_ramp, " ");
if (!bts->si_unused_send_empty)
vty_out(vty, " no system-information unused-send-empty%s", VTY_NEWLINE);
for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
@@ -4109,21 +4151,31 @@ DEFUN_ATTR(cfg_bts_acc_rotate_quantum,
return CMD_SUCCESS;
}
-DEFUN_ATTR(cfg_bts_acc_ramping,
- cfg_bts_acc_ramping_cmd,
- "access-control-class-ramping",
- "Enable Access Control Class ramping\n",
+/* per BTS configuration of ACC ramping */
+DEFUN_ATTR(cfg_acc_ramp,
+ cfg_acc_ramp_cmd,
+ "access-control-class-ramp",
+ "Configure Access Control Ramping for current BTS\n",
CMD_ATTR_IMMEDIATE)
{
struct gsm_bts *bts = vty->index;
+
+ vty->index = &bts->acc_ramp;
+ vty->node = ACC_RAMP_NODE;
+
+ return CMD_SUCCESS;
+}
+
+static int _vty_acc_ramp_thld_enable(struct acc_ramp_thresh_load *thld)
+{
struct gsm_bts_trx *trx;
- if (!acc_ramp_is_enabled(&bts->acc_ramp)) {
- acc_ramp_set_enabled(&bts->acc_ramp, true);
+ if (!acc_ramp_thld_is_enabled(thld)) {
+ acc_ramp_thld_set_enabled(thld, true);
/* Start ramping if at least one TRX is usable */
- llist_for_each_entry(trx, &bts->trx_list, list) {
+ llist_for_each_entry(trx, &thld->acc_ramp->bts->trx_list, list) {
if (trx_is_usable(trx)) {
- acc_ramp_trigger(&bts->acc_ramp);
+ acc_ramp_trigger(thld->acc_ramp);
break;
}
}
@@ -4135,29 +4187,132 @@ DEFUN_ATTR(cfg_bts_acc_ramping,
*/
return CMD_SUCCESS;
}
+DEFUN_ATTR(cfg_acc_ramp_chanld_enable,
+ cfg_acc_ramp_chanld_enable_cmd,
+ "chan-load-enabled",
+ "Enable Access Control Class ramping based on Channel Load\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_enable(&acc_ramp->chanld);
+}
+DEFUN_ATTR(cfg_acc_ramp_cpuld_enable,
+ cfg_acc_ramp_cpuld_enable_cmd,
+ "cpu-load-enabled",
+ "Enable Access Control Class ramping based on CPU Load\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_enable(&acc_ramp->cpuld);
+}
+DEFUN_ATTR(cfg_bts_acc_ramping,
+ cfg_bts_acc_ramping_cmd,
+ "access-control-class-ramping",
+ "Enable Access Control Class ramping\n",
+ CMD_ATTR_IMMEDIATE | CMD_ATTR_DEPRECATED)
+{
+ struct gsm_bts *bts = vty->index;
+ vty_out(vty, "%% 'bts' / 'access-control-class-ramping' config is deprecated, "
+ "use 'bts' / 'access-control-class-ramp' / 'chan-load-enabled' instead%s",
+ VTY_NEWLINE);
+ return _vty_acc_ramp_thld_enable(&bts->acc_ramp.chanld);
+}
+
+
+static int _vty_acc_ramp_thld_disable(struct vty *vty, struct acc_ramp_thresh_load *thld)
+{
+ struct gsm_bts_trx *trx;
+
+ if (acc_ramp_thld_is_enabled(thld)) {
+ acc_ramp_thld_set_enabled(thld, false);
+ /* Stop ramping if at least one TRX is usable (otherwise it
+ * should already be stopped) */
+ llist_for_each_entry(trx, &thld->acc_ramp->bts->trx_list, list) {
+ if (trx_is_usable(trx)) {
+ acc_ramp_trigger(thld->acc_ramp);
+ break;
+ }
+ }
+ //if (gsm_bts_set_system_infos(acc_ramp->bts) != 0) {
+ // vty_out(vty, "%% Failed to (re)generate System Information "
+ // "messages, check the logs%s", VTY_NEWLINE);
+ // return CMD_WARNING;
+ //}
+ }
+ return CMD_SUCCESS;
+}
+DEFUN_ATTR(cfg_acc_ramp_chanld_no_enable,
+ cfg_acc_ramp_chanld_no_enable_cmd,
+ "no chan-load-enabled",
+ NO_STR
+ "Enable Access Control Class ramping based on Channel Load\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_disable(vty, &acc_ramp->chanld);
+}
+DEFUN_ATTR(cfg_acc_ramp_cpuld_no_enable,
+ cfg_acc_ramp_cpuld_no_enable_cmd,
+ "no cpu-load-enabled",
+ NO_STR
+ "Enable Access Control Class ramping based on CPU Load\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_disable(vty, &acc_ramp->cpuld);
+}
DEFUN_ATTR(cfg_bts_no_acc_ramping,
cfg_bts_no_acc_ramping_cmd,
"no access-control-class-ramping",
NO_STR
"Disable Access Control Class ramping\n",
- CMD_ATTR_IMMEDIATE)
+ CMD_ATTR_IMMEDIATE | CMD_ATTR_DEPRECATED)
{
struct gsm_bts *bts = vty->index;
+ vty_out(vty, "%% 'bts' / 'no access-control-class-ramping' config is deprecated, "
+ "use 'bts' / 'access-control-class-ramp' / 'no chan-load-enabled' instead%s",
+ VTY_NEWLINE);
+ return _vty_acc_ramp_thld_disable(vty, &bts->acc_ramp.chanld);
+}
- if (acc_ramp_is_enabled(&bts->acc_ramp)) {
- acc_ramp_abort(&bts->acc_ramp);
- acc_ramp_set_enabled(&bts->acc_ramp, false);
- if (gsm_bts_set_system_infos(bts) != 0) {
- vty_out(vty, "%% Filed to (re)generate System Information "
- "messages, check the logs%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+static int _vty_acc_ramp_thld_step_interval(struct vty *vty, struct acc_ramp_thresh_load *thld, unsigned int step_interval)
+{
+ int error = acc_ramp_thld_set_step_interval(thld, step_interval);
+ if (error != 0) {
+ if (error == -ERANGE)
+ vty_out(vty, "%% Unable to set ACC ramp step interval: value out of range%s", VTY_NEWLINE);
+ else
+ vty_out(vty, "%% Unable to set ACC ramp step interval: unknown error%s", VTY_NEWLINE);
+ return CMD_WARNING;
}
return CMD_SUCCESS;
}
-
+DEFUN_ATTR(cfg_acc_ramp_chanld_step_interval,
+ cfg_acc_ramp_chanld_step_interval_cmd,
+ "chan-load-step-interval (<"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MIN) "-"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MAX) ">)",
+ "Configure Access Control Class ramping step interval (Chan Load based)\n"
+ "Set a fixed step interval (in seconds)\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_step_interval(vty, &acc_ramp->chanld, atoi(argv[0]));
+}
+DEFUN_ATTR(cfg_acc_ramp_cpuld_step_interval,
+ cfg_acc_ramp_cpuld_step_interval_cmd,
+ "cpu-load-step-interval (<"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MIN) "-"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_INTERVAL_MAX) ">)",
+ "Configure Access Control Class ramping step interval (CPU Load based)\n"
+ "Set a fixed step interval (in seconds)\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_step_interval(vty, &acc_ramp->cpuld, atoi(argv[0]));
+}
DEFUN_ATTR(cfg_bts_acc_ramping_step_interval,
cfg_bts_acc_ramping_step_interval_cmd,
"access-control-class-ramping-step-interval (<"
@@ -4166,29 +4321,59 @@ DEFUN_ATTR(cfg_bts_acc_ramping_step_interval,
"Configure Access Control Class ramping step interval\n"
"Set a fixed step interval (in seconds)\n"
"Use dynamic step interval based on BTS channel load (deprecated, don't use, ignored)\n",
- CMD_ATTR_IMMEDIATE)
+ CMD_ATTR_IMMEDIATE | CMD_ATTR_DEPRECATED)
{
struct gsm_bts *bts = vty->index;
bool dynamic = (strcmp(argv[0], "dynamic") == 0);
- int error;
-
+ vty_out(vty, "%% 'bts' / 'access-control-class-ramping-step-interval' config is deprecated, "
+ "use 'bts' / 'access-control-class-ramp' / 'chan-load-step-interval' instead%s",
+ VTY_NEWLINE);
if (dynamic) {
vty_out(vty, "%% access-control-class-ramping-step-interval 'dynamic' value is deprecated, ignoring it%s", VTY_NEWLINE);
return CMD_SUCCESS;
}
+ return _vty_acc_ramp_thld_step_interval(vty, &bts->acc_ramp.chanld, atoi(argv[0]));
+}
- error = acc_ramp_set_step_interval(&bts->acc_ramp, atoi(argv[0]));
+
+static int _vty_acc_ramp_thld_step_size(struct vty *vty, struct acc_ramp_thresh_load *thld, unsigned int step_size)
+{
+ int error;
+ error = acc_ramp_thld_set_step_size(thld, step_size);
if (error != 0) {
if (error == -ERANGE)
- vty_out(vty, "%% Unable to set ACC ramp step interval: value out of range%s", VTY_NEWLINE);
+ vty_out(vty, "%% Unable to set ACC ramp step size: value out of range%s", VTY_NEWLINE);
else
- vty_out(vty, "%% Unable to set ACC ramp step interval: unknown error%s", VTY_NEWLINE);
+ vty_out(vty, "%% Unable to set ACC ramp step size: unknown error%s", VTY_NEWLINE);
return CMD_WARNING;
}
return CMD_SUCCESS;
}
-
+DEFUN_ATTR(cfg_acc_ramp_chanld_step_size,
+ cfg_acc_ramp_chanld_step_size_cmd,
+ "chan-load-step-size (<"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MIN) "-"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MAX) ">)",
+ "Configure Access Control Class ramping step size (Chan Load based)\n"
+ "Set the number of Access Control Classes to enable per ramping step\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_step_size(vty, &acc_ramp->chanld, atoi(argv[0]));
+}
+DEFUN_ATTR(cfg_acc_ramp_cpuld_step_size,
+ cfg_acc_ramp_cpuld_step_size_cmd,
+ "cpu-load-step-size (<"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MIN) "-"
+ OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MAX) ">)",
+ "Configure Access Control Class ramping step size (CPU Load based)\n"
+ "Set the number of Access Control Classes to enable per ramping step\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_step_size(vty, &acc_ramp->cpuld, atoi(argv[0]));
+}
DEFUN_ATTR(cfg_bts_acc_ramping_step_size,
cfg_bts_acc_ramping_step_size_cmd,
"access-control-class-ramping-step-size (<"
@@ -4196,41 +4381,62 @@ DEFUN_ATTR(cfg_bts_acc_ramping_step_size,
OSMO_STRINGIFY_VAL(ACC_RAMP_STEP_SIZE_MAX) ">)",
"Configure Access Control Class ramping step size\n"
"Set the number of Access Control Classes to enable per ramping step\n",
- CMD_ATTR_IMMEDIATE)
+ CMD_ATTR_IMMEDIATE | CMD_ATTR_DEPRECATED)
{
struct gsm_bts *bts = vty->index;
- int error;
+ vty_out(vty, "%% 'bts' / 'access-control-class-ramping-step-size' config is deprecated, "
+ "use 'bts' / 'access-control-class-ramp' / 'step-size' instead%s",
+ VTY_NEWLINE);
+ return _vty_acc_ramp_thld_step_size(vty, &bts->acc_ramp.chanld, atoi(argv[0]));
+}
- error = acc_ramp_set_step_size(&bts->acc_ramp, atoi(argv[0]));
- if (error != 0) {
- if (error == -ERANGE)
- vty_out(vty, "%% Unable to set ACC ramp step size: value out of range%s", VTY_NEWLINE);
- else
- vty_out(vty, "%% Unable to set ACC ramp step size: unknown error%s", VTY_NEWLINE);
+
+static int _vty_acc_ramp_thld_thresholds(struct vty *vty, struct acc_ramp_thresh_load *thld,
+ unsigned int low_threshold, unsigned int up_threshold)
+{
+ int rc;
+ rc = acc_ramp_thld_set_thresholds(thld, low_threshold, up_threshold);
+ if (rc < 0) {
+ vty_out(vty, "%% Unable to set ACC channel load thresholds%s", VTY_NEWLINE);
return CMD_WARNING;
}
-
return CMD_SUCCESS;
}
-
+DEFUN_ATTR(cfg_acc_ramp_chanld_thresholds,
+ cfg_acc_ramp_chanld_thresholds_cmd,
+ "chan-load-thresholds <0-100> <0-100>",
+ "Configure Access Control Class ramping channel load thresholds\n"
+ "Lower Channel load threshold (%) below which subset size of allowed broadcast ACCs can be increased\n"
+ "Upper channel load threshold (%) above which subset size of allowed broadcast ACCs can be decreased\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_thresholds(vty, &acc_ramp->chanld, atoi(argv[0]), atoi(argv[1]));
+}
+DEFUN_ATTR(cfg_acc_ramp_cpuld_thresholds,
+ cfg_acc_ramp_cpuld_thresholds_cmd,
+ "cpu-load-thresholds <0-100> <0-100>",
+ "Configure Access Control Class ramping CPU load thresholds\n"
+ "Lower CPU load threshold (%) below which subset size of allowed broadcast ACCs can be increased\n"
+ "Upper CPU load threshold (%) above which subset size of allowed broadcast ACCs can be decreased\n",
+ CMD_ATTR_IMMEDIATE)
+{
+ struct acc_ramp *acc_ramp = vty->index;
+ return _vty_acc_ramp_thld_thresholds(vty, &acc_ramp->cpuld, atoi(argv[0]), atoi(argv[1]));
+}
DEFUN_ATTR(cfg_bts_acc_ramping_chan_load,
cfg_bts_acc_ramping_chan_load_cmd,
"access-control-class-ramping-chan-load <0-100> <0-100>",
"Configure Access Control Class ramping channel load thresholds\n"
"Lower Channel load threshold (%) below which subset size of allowed broadcast ACCs can be increased\n"
"Upper channel load threshold (%) above which subset size of allowed broadcast ACCs can be decreased\n",
- CMD_ATTR_IMMEDIATE)
+ CMD_ATTR_IMMEDIATE | CMD_ATTR_DEPRECATED)
{
struct gsm_bts *bts = vty->index;
- int rc;
-
- rc = acc_ramp_set_chan_load_thresholds(&bts->acc_ramp, atoi(argv[0]), atoi(argv[1]));
- if (rc < 0) {
- vty_out(vty, "%% Unable to set ACC channel load thresholds%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return CMD_SUCCESS;
+ vty_out(vty, "%% 'bts' / 'access-control-class-ramping-chan-load' config is deprecated, "
+ "use 'bts' / 'access-control-class-ramp' / 'chan-load-thresholds' instead%s",
+ VTY_NEWLINE);
+ return _vty_acc_ramp_thld_thresholds(vty, &bts->acc_ramp.chanld, atoi(argv[0]), atoi(argv[1]));
}
#define EXCL_RFLOCK_STR "Exclude this BTS from the global RF Lock\n"
@@ -7838,6 +8044,19 @@ int bsc_vty_init(struct gsm_network *network)
neighbor_ident_vty_init();
/* See also handover commands added on bts level from handover_vty.c */
+ install_element(BTS_NODE, &cfg_acc_ramp_cmd);
+ install_node(&acc_ramp_node, dummy_config_write);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_chanld_enable_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_chanld_no_enable_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_chanld_step_interval_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_chanld_step_size_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_chanld_thresholds_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_cpuld_enable_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_cpuld_no_enable_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_cpuld_step_interval_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_cpuld_step_size_cmd);
+ install_element(ACC_RAMP_NODE, &cfg_acc_ramp_cpuld_thresholds_cmd);
+
install_element(BTS_NODE, &cfg_bts_power_ctrl_cmd);
install_element(BTS_NODE, &cfg_bts_no_power_ctrl_cmd);
install_node(&power_ctrl_node, dummy_config_write);
diff --git a/src/osmo-bsc/osmo_bsc_main.c b/src/osmo-bsc/osmo_bsc_main.c
index 3069cc02f..5e08e2ea2 100644
--- a/src/osmo-bsc/osmo_bsc_main.c
+++ b/src/osmo-bsc/osmo_bsc_main.c
@@ -609,6 +609,15 @@ static int bsc_vty_go_parent(struct vty *vty)
vty->index = ts->trx;
}
break;
+ case ACC_RAMP_NODE:
+ vty->node = BTS_NODE;
+ {
+ /* set vty->index correctly ! */
+ struct acc_ramp *acc_ramp = vty->index;
+ vty->index = acc_ramp->bts;
+ vty->index_sub = &acc_ramp->bts->description;
+ }
+ break;
case OML_NODE:
case OM2K_NODE:
vty->node = ENABLE_NODE;
diff --git a/tests/acc.vty b/tests/acc.vty
new file mode 100644
index 000000000..586f81e73
--- /dev/null
+++ b/tests/acc.vty
@@ -0,0 +1,159 @@
+OsmoBSC> enable
+
+OsmoBSC# ### Default configuration
+OsmoBSC# show running-config
+...
+ access-control-class-ramp
+ no chan-load-enabled
+ no cpu-load-enabled
+...
+
+OsmoBSC# ### Check that 'access-control-class-ramp' node and its commands exist
+OsmoBSC# configure terminal
+OsmoBSC(config)# network
+OsmoBSC(config-net)# bts 0
+OsmoBSC(config-net-bts)# list with-flags
+...
+ ! ... access-control-class-ramp
+...
+
+OsmoBSC(config-net-bts)# ### Check that legacy deprecated cmds still work
+OsmoBSC(config-net-bts)# access-control-class-ramping
+% 'bts' / 'access-control-class-ramping' config is deprecated, use 'bts' / 'access-control-class-ramp' / 'chan-load-enabled' instead
+OsmoBSC(config-net-bts)# show running-config
+...
+ access-control-class-ramp
+ chan-load-enabled
+ chan-load-step-interval 5
+ chan-load-step-size 1
+ chan-load-thresholds 71 89
+ no cpu-load-enabled
+...
+OsmoBSC(config-net-bts)# access-control-class-ramping-step-interval 10
+% 'bts' / 'access-control-class-ramping-step-interval' config is deprecated, use 'bts' / 'access-control-class-ramp' / 'chan-load-step-interval' instead
+OsmoBSC(config-net-bts)# access-control-class-ramping-step-size 2
+% 'bts' / 'access-control-class-ramping-step-size' config is deprecated, use 'bts' / 'access-control-class-ramp' / 'step-size' instead
+OsmoBSC(config-net-bts)# access-control-class-ramping-chan-load 80 90
+% 'bts' / 'access-control-class-ramping-chan-load' config is deprecated, use 'bts' / 'access-control-class-ramp' / 'chan-load-thresholds' instead
+OsmoBSC(config-net-bts)# show running-config
+...
+ access-control-class-ramp
+ chan-load-enabled
+ chan-load-step-interval 10
+ chan-load-step-size 2
+ chan-load-thresholds 80 90
+ no cpu-load-enabled
+...
+OsmoBSC(config-net-bts)# no access-control-class-ramping
+% 'bts' / 'no access-control-class-ramping' config is deprecated, use 'bts' / 'access-control-class-ramp' / 'no chan-load-enabled' instead
+OsmoBSC(config-net-bts)# show running-config
+...
+ access-control-class-ramp
+ no chan-load-enabled
+ no cpu-load-enabled
+...
+
+OsmoBSC(config-net-bts)# ### Now test new cmd set
+OsmoBSC(config-net-bts)# access-control-class-ramp
+OsmoBSC(config-net-bts-acc-ramp)# list with-flags
+...
+ ! chan-load-enabled
+ ! no chan-load-enabled
+ ! chan-load-step-interval (<5-600>)
+ ! chan-load-step-size (<1-10>)
+ ! chan-load-thresholds <0-100> <0-100>
+ ! cpu-load-enabled
+ ! no cpu-load-enabled
+ ! cpu-load-step-interval (<5-600>)
+ ! cpu-load-step-size (<1-10>)
+ ! cpu-load-thresholds <0-100> <0-100>
+...
+OsmoBSC(config-net-bts-acc-ramp)# no chan-load-enabled
+OsmoBSC(config-net-bts-acc-ramp)# chan-load-enabled
+OsmoBSC(config-net-bts-acc-ramp)# show running-config
+...
+ access-control-class-ramp
+ chan-load-enabled
+ chan-load-step-interval 10
+ chan-load-step-size 2
+ chan-load-thresholds 80 90
+ no cpu-load-enabled
+...
+OsmoBSC(config-net-bts-acc-ramp)# chan-load-step-interval 6
+OsmoBSC(config-net-bts-acc-ramp)# chan-load-step-size 2
+OsmoBSC(config-net-bts-acc-ramp)# chan-load-thresholds 10 50
+OsmoBSC(config-net-bts-acc-ramp)# show running-config
+...
+ access-control-class-ramp
+ chan-load-enabled
+ chan-load-step-interval 6
+ chan-load-step-size 2
+ chan-load-thresholds 10 50
+ no cpu-load-enabled
+...
+
+OsmoBSC(config-net-bts-acc-ramp)# ### Now same for CPU load
+OsmoBSC(config-net-bts-acc-ramp)# no cpu-load-enabled
+OsmoBSC(config-net-bts-acc-ramp)# cpu-load-enabled
+OsmoBSC(config-net-bts-acc-ramp)# show running-config
+...
+ access-control-class-ramp
+ chan-load-enabled
+ chan-load-step-interval 6
+ chan-load-step-size 2
+ chan-load-thresholds 10 50
+ cpu-load-enabled
+ cpu-load-step-interval 5
+ cpu-load-step-size 1
+ cpu-load-thresholds 71 89
+...
+OsmoBSC(config-net-bts-acc-ramp)# cpu-load-step-interval 7
+OsmoBSC(config-net-bts-acc-ramp)# cpu-load-step-size 3
+OsmoBSC(config-net-bts-acc-ramp)# cpu-load-thresholds 12 60
+OsmoBSC(config-net-bts-acc-ramp)# show running-config
+...
+ access-control-class-ramp
+ chan-load-enabled
+ chan-load-step-interval 6
+ chan-load-step-size 2
+ chan-load-thresholds 10 50
+ cpu-load-enabled
+ cpu-load-step-interval 7
+ cpu-load-step-size 3
+ cpu-load-thresholds 12 60
+...
+
+
+OsmoBSC(config-net-bts-acc-ramp)# ### Try incorrect use
+OsmoBSC(config-net-bts-acc-ramp)# chan-load-step-interval 2
+% Unknown command.
+OsmoBSC(config-net-bts-acc-ramp)# chan-load-step-size 0
+% Unknown command.
+OsmoBSC(config-net-bts-acc-ramp)# chan-load-thresholds 80 70
+% Unable to set ACC channel load thresholds
+OsmoBSC(config-net-bts-acc-ramp)# cpu-load-step-interval 2
+% Unknown command.
+OsmoBSC(config-net-bts-acc-ramp)# cpu-load-step-size 0
+% Unknown command.
+OsmoBSC(config-net-bts-acc-ramp)# cpu-load-thresholds 80 70
+% Unable to set ACC channel load thresholds
+
+
+OsmoBSC(config-net-bts-acc-ramp)# ### Disable them
+OsmoBSC(config-net-bts-acc-ramp)# no chan-load-enabled
+OsmoBSC(config-net-bts-acc-ramp)# show running-config
+...
+ access-control-class-ramp
+ no chan-load-enabled
+ cpu-load-enabled
+ cpu-load-step-interval 7
+ cpu-load-step-size 3
+ cpu-load-thresholds 12 60
+...
+OsmoBSC(config-net-bts-acc-ramp)# no cpu-load-enabled
+OsmoBSC(config-net-bts-acc-ramp)# show running-config
+...
+ access-control-class-ramp
+ no chan-load-enabled
+ no cpu-load-enabled
+...
diff --git a/tests/acc/acc_test.c b/tests/acc/acc_test.c
index 759ff139f..ef4c59790 100644
--- a/tests/acc/acc_test.c
+++ b/tests/acc/acc_test.c
@@ -64,8 +64,8 @@ static inline void _bts_del(struct gsm_bts *bts, const char *msg)
rate_ctr_group_free(bts->bts_ctrs);
if (osmo_timer_pending(&bts->acc_mgr.rotate_timer))
osmo_timer_del(&bts->acc_mgr.rotate_timer);
- if (osmo_timer_pending(&bts->acc_ramp.step_timer))
- osmo_timer_del(&bts->acc_ramp.step_timer);
+ if (osmo_timer_pending(&bts->acc_ramp.chanld.step_timer))
+ osmo_timer_del(&bts->acc_ramp.chanld.step_timer);
/* no need to llist_del(&bts->list), we never registered the bts there. */
talloc_free(bts->site_mgr);
fprintf(stderr, "BTS deallocated OK in %s()\n", msg);
@@ -254,18 +254,18 @@ static void test_acc_ramp(struct gsm_network *net)
struct acc_ramp *acc_ramp = &bts->acc_ramp;
/* Validate are all allowed by default after allocation: */
- OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
- OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
- OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
+ OSMO_ASSERT(acc_ramp_thld_is_enabled(&acc_ramp->chanld) == false);
+ OSMO_ASSERT(acc_ramp_thld_get_step_size(&acc_ramp->chanld) == ACC_RAMP_STEP_SIZE_DEFAULT);
+ OSMO_ASSERT(acc_ramp_thld_get_step_interval(&acc_ramp->chanld) == ACC_RAMP_STEP_INTERVAL_MIN);
/* Set super high rotation time so it doesn't interfer here: */
acc_mgr_set_rotation_time(acc_mgr, 5000);
- OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 1) == -ERANGE);
- OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 50) == 0);
- OSMO_ASSERT(acc_ramp_set_chan_load_thresholds(acc_ramp, 100, 100) == 0);
- acc_ramp_set_step_size(acc_ramp, 1);
- acc_ramp_set_enabled(acc_ramp, true);
+ OSMO_ASSERT(acc_ramp_thld_set_step_interval(&acc_ramp->chanld, 1) == -ERANGE);
+ OSMO_ASSERT(acc_ramp_thld_set_step_interval(&acc_ramp->chanld, 50) == 0);
+ OSMO_ASSERT(acc_ramp_thld_set_thresholds(&acc_ramp->chanld, 100, 100) == 0);
+ acc_ramp_thld_set_step_size(&acc_ramp->chanld, 1);
+ acc_ramp_thld_set_enabled(&acc_ramp->chanld, true);
osmo_gettimeofday_override_time = (struct timeval) {0, 0};
acc_ramp_trigger(acc_ramp);
@@ -288,17 +288,17 @@ static void test_acc_ramp2(struct gsm_network *net)
struct acc_ramp *acc_ramp = &bts->acc_ramp;
/* Validate are all allowed by default after allocation: */
- OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
- OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
- OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
+ OSMO_ASSERT(acc_ramp_thld_is_enabled(&acc_ramp->chanld) == false);
+ OSMO_ASSERT(acc_ramp_thld_get_step_size(&acc_ramp->chanld) == ACC_RAMP_STEP_SIZE_DEFAULT);
+ OSMO_ASSERT(acc_ramp_thld_get_step_interval(&acc_ramp->chanld) == ACC_RAMP_STEP_INTERVAL_MIN);
/* Set super high rotation time so it doesn't interfer here: */
acc_mgr_set_rotation_time(acc_mgr, 5000);
/* Set adm len to test that ramping won't go over it */
acc_mgr_set_len_allowed_adm(acc_mgr, 7);
- acc_ramp_set_step_size(acc_ramp, 3);
- acc_ramp_set_enabled(acc_ramp, true);
+ acc_ramp_thld_set_step_size(&acc_ramp->chanld, 3);
+ acc_ramp_thld_set_enabled(&acc_ramp->chanld, true);
osmo_gettimeofday_override_time = (struct timeval) {0, 0};
acc_ramp_trigger(acc_ramp);
@@ -321,9 +321,9 @@ static void test_acc_ramp3(struct gsm_network *net)
struct acc_ramp *acc_ramp = &bts->acc_ramp;
/* Validate are all allowed by default after allocation: */
- OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
- OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
- OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
+ OSMO_ASSERT(acc_ramp_thld_is_enabled(&acc_ramp->chanld) == false);
+ OSMO_ASSERT(acc_ramp_thld_get_step_size(&acc_ramp->chanld) == ACC_RAMP_STEP_SIZE_DEFAULT);
+ OSMO_ASSERT(acc_ramp_thld_get_step_interval(&acc_ramp->chanld) == ACC_RAMP_STEP_INTERVAL_MIN);
/* Set super high rotation time so it doesn't interfer here: */
acc_mgr_set_rotation_time(acc_mgr, 5000);
@@ -333,8 +333,8 @@ static void test_acc_ramp3(struct gsm_network *net)
bts->si_common.rach_control.t3 |= 0xa5;
acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
- acc_ramp_set_step_size(acc_ramp, 1);
- acc_ramp_set_enabled(acc_ramp, true);
+ acc_ramp_thld_set_step_size(&acc_ramp->chanld, 1);
+ acc_ramp_thld_set_enabled(&acc_ramp->chanld, true);
osmo_gettimeofday_override_time = (struct timeval) {0, 0};
acc_ramp_trigger(acc_ramp);
@@ -358,20 +358,20 @@ static void test_acc_ramp_up_rotate(struct gsm_network *net, unsigned int chan_l
int n;
/* Validate are all allowed by default after allocation: */
- OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
- OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
- OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
+ OSMO_ASSERT(acc_ramp_thld_is_enabled(&acc_ramp->chanld) == false);
+ OSMO_ASSERT(acc_ramp_thld_get_step_size(&acc_ramp->chanld) == ACC_RAMP_STEP_SIZE_DEFAULT);
+ OSMO_ASSERT(acc_ramp_thld_get_step_interval(&acc_ramp->chanld) == ACC_RAMP_STEP_INTERVAL_MIN);
- OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 250) == 0);
+ OSMO_ASSERT(acc_ramp_thld_set_step_interval(&acc_ramp->chanld, 250) == 0);
acc_mgr_set_rotation_time(acc_mgr, 100);
/* Test that ramping + rotation won't go over permanently barred ACC*/
fprintf(stderr, "*** Barring one ACC ***\n");
bts->si_common.rach_control.t2 |= 0x02;
acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
- OSMO_ASSERT(acc_ramp_set_step_size(acc_ramp, 1) == 0);
- OSMO_ASSERT(acc_ramp_set_chan_load_thresholds(acc_ramp, low_threshold, up_threshold) == 0);
- acc_ramp_set_enabled(acc_ramp, true);
+ OSMO_ASSERT(acc_ramp_thld_set_step_size(&acc_ramp->chanld, 1) == 0);
+ OSMO_ASSERT(acc_ramp_thld_set_thresholds(&acc_ramp->chanld, low_threshold, up_threshold) == 0);
+ acc_ramp_thld_set_enabled(&acc_ramp->chanld, true);
bts->chan_load_avg = chan_load; /*set % channel load */
@@ -380,7 +380,7 @@ static void test_acc_ramp_up_rotate(struct gsm_network *net, unsigned int chan_l
n = 5;
while (true) {
- OSMO_ASSERT(osmo_timer_pending(&acc_ramp->step_timer));
+ OSMO_ASSERT(osmo_timer_pending(&acc_ramp->chanld.step_timer));
if (osmo_timer_pending(&acc_mgr->rotate_timer)) {
if ((osmo_gettimeofday_override_time.tv_sec + 50) % 250 == 0)
osmo_gettimeofday_override_time.tv_sec += 50;
@@ -416,20 +416,20 @@ static void test_acc_ramp_updown_rotate(struct gsm_network *net, unsigned int lo
bool up = true;
/* Validate are all allowed by default after allocation: */
- OSMO_ASSERT(acc_ramp_is_enabled(acc_ramp) == false);
- OSMO_ASSERT(acc_ramp_get_step_size(acc_ramp) == ACC_RAMP_STEP_SIZE_DEFAULT);
- OSMO_ASSERT(acc_ramp_get_step_interval(acc_ramp) == ACC_RAMP_STEP_INTERVAL_MIN);
+ OSMO_ASSERT(acc_ramp_thld_is_enabled(&acc_ramp->chanld) == false);
+ OSMO_ASSERT(acc_ramp_thld_get_step_size(&acc_ramp->chanld) == ACC_RAMP_STEP_SIZE_DEFAULT);
+ OSMO_ASSERT(acc_ramp_thld_get_step_interval(&acc_ramp->chanld) == ACC_RAMP_STEP_INTERVAL_MIN);
- OSMO_ASSERT(acc_ramp_set_step_interval(acc_ramp, 250) == 0);
+ OSMO_ASSERT(acc_ramp_thld_set_step_interval(&acc_ramp->chanld, 250) == 0);
acc_mgr_set_rotation_time(acc_mgr, 100);
/* Test that ramping + rotation won't go over permanently barred ACC*/
fprintf(stderr, "*** Barring one ACC ***\n");
bts->si_common.rach_control.t2 |= 0x02;
acc_mgr_perm_subset_changed(acc_mgr, &bts->si_common.rach_control);
- OSMO_ASSERT(acc_ramp_set_step_size(acc_ramp, 1) == 0);
- OSMO_ASSERT(acc_ramp_set_chan_load_thresholds(acc_ramp, low_threshold, up_threshold) == 0);
- acc_ramp_set_enabled(acc_ramp, true);
+ OSMO_ASSERT(acc_ramp_thld_set_step_size(&acc_ramp->chanld, 1) == 0);
+ OSMO_ASSERT(acc_ramp_thld_set_thresholds(&acc_ramp->chanld, low_threshold, up_threshold) == 0);
+ acc_ramp_thld_set_enabled(&acc_ramp->chanld, true);
bts->chan_load_avg = min_load; /* set % channel load */
@@ -438,7 +438,7 @@ static void test_acc_ramp_updown_rotate(struct gsm_network *net, unsigned int lo
/* 50 ev loop iterations */
for (i = 0; i < 50; i++) {
- OSMO_ASSERT(osmo_timer_pending(&acc_ramp->step_timer));
+ OSMO_ASSERT(osmo_timer_pending(&acc_ramp->chanld.step_timer));
if (osmo_timer_pending(&acc_mgr->rotate_timer)) {
if ((osmo_gettimeofday_override_time.tv_sec + 50) % 250 == 0)
osmo_gettimeofday_override_time.tv_sec += 50;