Change in osmo-bsc[master]: handover_ctrl: add control interface for handover settings

dexter gerrit-no-reply at lists.osmocom.org
Mon Jun 7 18:28:15 UTC 2021


dexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bsc/+/24600 )


Change subject: handover_ctrl: add control interface for handover settings
......................................................................

handover_ctrl: add control interface for handover settings

The VTY handover_vtc.c offers a large number of handover specific
settings. Those settings are (with one exception) auto generated using
macros. Lets add an equivalent for the control interface that uses the
same auto generation mechanisms.

Change-Id: I12f143906818fd6b16e8783157cbb1eb51e49ffc
Related: SYS#5369
---
M doc/manuals/chapters/control.adoc
M include/osmocom/bsc/Makefile.am
A include/osmocom/bsc/handover_ctrl.h
M src/osmo-bsc/Makefile.am
A src/osmo-bsc/handover_ctrl.c
M src/osmo-bsc/osmo_bsc_ctrl.c
M tests/handover/Makefile.am
7 files changed, 206 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/00/24600/1

diff --git a/doc/manuals/chapters/control.adoc b/doc/manuals/chapters/control.adoc
index 6b1609a..ec87a72 100644
--- a/doc/manuals/chapters/control.adoc
+++ b/doc/manuals/chapters/control.adoc
@@ -38,6 +38,34 @@
 |bts.N.rf_state|RO|No|"<oper>,<admin>,<pol>"|See <<rfs>> for details.
 |bts.N.trx.M.arfcn|RW|No|"<arfcn>"|Set/Get ARFCN (value between (0, 1023)).
 |bts.N.trx.M.max-power-reduction|RW|No|"<mpr>"|See <<mpr>> for details.
+|handover_ho_active|RW|No|"0","1","default"|Enable/disable handover.
+|handover_algorithm|RW|No|"1","2","default"|Choose algorithm for handover decision (hodec1 or hodec2).
+|handover_hodec1_rxlev_avg_win|RW|No|<1-10>,"default"|How many RxLev measurements to use for averaging.
+|handover_hodec1_rxqual_avg_win|RW|No|<1-10>,"default"|How many RxQual measurements to use for averaging.
+|handover_hodec1_rxlev_neigh_avg_win|RW|No|<1-10>,"default"|How many Neighbor RxLev measurements to use for averaging.
+|handover_hodec1_pwr_interval|RW|No|<1-99>,"default"|How often to check for a better cell (SACCH frames).
+|handover_hodec1_pwr_hysteresis|RW|No|<0-999>,"default"|How many dB stronger must a neighbor be to become a HO candidate.
+|handover_hodec1_max_distance|RW|No|<0-9999>,"default"|Maximum Timing-Advance value (i.e. MS distance) before triggering HO.
+|handover_hodec2_rxlev_avg_win|RW|No|<1-10>,"default"|How many RxLev measurements to use for averaging.
+|handover_hodec2_rxqual_avg_win|RW|No|<1-10>,"default"|How many RxQual measurements to use for averaging.
+|handover_hodec2_rxlev_neigh_avg_win|RW|No|<1-10>,"default"|window rxlev neighbor averaging.
+|handover_hodec2_pwr_interval|RW|No|<1-99>,"default"|How many dB stronger must a neighbor be to become a HO candidate.
+|handover_hodec2_pwr_hysteresis|RW|No|<0-999>,"default"|How many dB stronger must a neighbor be to become a HO candidate.
+|handover_hodec2_max_distance|RW|No|<0-9999>,"default"|Maximum Timing-Advance value (i.e. MS distance) before triggering HO.
+|handover_hodec2_as_active|RW|No|"0","1","default"|Enable or disable in-call channel re-assignment within the same cell.
+|handover_hodec2_full_tdma|RW|No|"full","subset","default"|Define measurement set of TDMA frames.
+|handover_hodec2_min_rxlev|RW|No|<-110--50>,"default"|How weak may RxLev of an MS become before triggering HO.
+|handover_hodec2_min_rxqual|RW|No|<0-7>,"default"|How bad may RxQual of an MS become before triggering HO.
+|handover_hodec2_afs_bias_rxlev|RW|No|<0-20>,"default"|RxLev improvement bias for AFS over other codecs.
+|handover_hodec2_afs_bias_rxqual|RW|No|<0-7>,"default"|RxQual improvement bias for AFS over other codecs.
+|handover_hodec2_tchf_min_slots|RW|No|<0-9999>,"default"|Minimum free TCH/F timeslots before cell is considered congested.
+|handover_hodec2_tchh_min_slots|RW|No|<0-9999>,"default"|Minimum free TCH/H timeslots before cell is considered congested.
+|handover_hodec2_ho_max|RW|No|<1-9999>,"default"|Maximum number of concurrent handovers allowed per cell.
+|handover_hodec2_penalty_max_dist|RW|No|<0-99999>,"default"|ime to suspend handover for a subscriber after leaving this cell due to exceeding max distance.
+|handover_hodec2_penalty_failed_ho|RW|No|<0-99999>,"default"|Time to suspend handover for a subscriber after a failed handover into this cell.
+|handover_hodec2_penalty_failed_as|RW|No|<0-99999>,"default"|Time to suspend handover for a subscriber after a failed re-assignment within this cell.
+|handover_hodec2_retries|RW|No|<0-9>,"default"|Number of times to immediately retry a failed handover/assignment, before a penalty time is applied.
+|handover_congestion_check_interval|RW|No|"disabled",<1-999>,"now"|Congestion check interval in seconds, "now" triggers immediate congestion check.
 |===
 
 [[notif]]
diff --git a/include/osmocom/bsc/Makefile.am b/include/osmocom/bsc/Makefile.am
index be27dae..f157071 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -22,6 +22,7 @@
 	gsm_data.h \
 	handover.h \
 	handover_cfg.h \
+	handover_ctrl.h \
 	handover_decision.h \
 	handover_decision_2.h \
 	handover_fsm.h \
diff --git a/include/osmocom/bsc/handover_ctrl.h b/include/osmocom/bsc/handover_ctrl.h
new file mode 100644
index 0000000..75d0933
--- /dev/null
+++ b/include/osmocom/bsc/handover_ctrl.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int bsc_ho_ctrl_cmds_install(void);
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index f91c6bf..b2913c1 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -60,6 +60,7 @@
 	gsm_04_08_rr.c \
 	gsm_data.c \
 	handover_cfg.c \
+	handover_ctrl.c \
 	handover_decision.c \
 	handover_decision_2.c \
 	handover_fsm.c \
diff --git a/src/osmo-bsc/handover_ctrl.c b/src/osmo-bsc/handover_ctrl.c
new file mode 100644
index 0000000..0c42236
--- /dev/null
+++ b/src/osmo-bsc/handover_ctrl.c
@@ -0,0 +1,168 @@
+/* OsmoBSC handover control interface implementation */
+/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info at sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * Author: Philipp Maier <pmaier at sysmocom.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdbool.h>
+#include <talloc.h>
+#include <osmocom/bsc/vty.h>
+#include <osmocom/bsc/handover_cfg.h>
+#include <osmocom/bsc/gsm_data.h>
+#include <osmocom/bsc/handover_decision_2.h>
+#include <osmocom/ctrl/control_cmd.h>
+
+/* Verify a VTY command argument against its value specification, the value
+ * specification may be in the form of "<from-to>" or "A|B|C|..." */
+bool verify_vty_cmd_arg(void *ctx, const char *range, const char *value)
+{
+	bool success;
+	int range_from;
+	int range_to;
+	int value_int;
+	char *range_tok;
+	char *valid_val;
+	int rc;
+
+	/* "default" value is always a valid value */
+	if (strcmp(value, "default") == 0)
+		return true;
+
+	/* Try to check for a range first since it is the most common case */
+	if (range[0] == '<') {
+		rc = sscanf(range, "<%i-%i>", &range_from, &range_to);
+		if (rc == 2) {
+			rc = sscanf(value, "%i", &value_int);
+			if (rc != 1)
+				return false;
+			if (value_int < range_from)
+				return false;
+			if (value_int > range_to)
+				return false;
+			return true;
+		}
+	}
+
+	/* Try to tokenize the string to check for distintinct values */
+	success = false;
+	range_tok = talloc_zero_size(ctx, strlen(range) + 1);
+	memcpy(range_tok, range, strlen(range));
+	valid_val = strtok(range_tok, "|");
+	while (valid_val != NULL) {
+		if (strcmp(valid_val, value) == 0) {
+			success = true;
+			break;
+		}
+		valid_val = strtok(NULL, "|");
+	}
+
+	talloc_free(range_tok);
+	return success;
+}
+
+#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, VTY0, VTY_CMD, VTY_CMD_ARG, VTY_ARG_EVAL, VTY_WRITE_FMT, VTY_WRITE_CONV, VTY6) \
+CTRL_CMD_DEFINE(NAME, "handover_"#NAME); \
+static int get_##NAME(struct ctrl_cmd *cmd, void *_data) \
+{ \
+	struct gsm_network *net = cmd->node; \
+	struct handover_cfg *ho = net->ho; \
+	TYPE val; \
+	if (ho_isset_##NAME(ho)) { \
+		val = ho_get_##NAME(ho); \
+		cmd->reply = talloc_asprintf(cmd, VTY_WRITE_FMT, VTY_WRITE_CONV(val)); \
+	} else \
+		cmd->reply = talloc_asprintf(cmd, "%s", #DEFAULT_VAL); \
+	return CTRL_CMD_REPLY; \
+} \
+static int set_##NAME(struct ctrl_cmd *cmd, void *_data) \
+{ \
+	struct gsm_network *net = cmd->node; \
+	struct handover_cfg *ho = net->ho; \
+	TYPE value; \
+	if (strcmp(cmd->value, "default") == 0)	\
+		value = VTY_ARG_EVAL(#DEFAULT_VAL); \
+	else \
+		value = VTY_ARG_EVAL(cmd->value); \
+	ho_set_##NAME(ho, value); \
+	return get_##NAME(cmd, _data); \
+} \
+static int verify_##NAME(struct ctrl_cmd *cmd, const char *value, void *_data) \
+{ \
+	if (verify_vty_cmd_arg(cmd, VTY_CMD_ARG, value) != true) \
+		return -1; \
+	return 0; \
+} \
+
+/* Expand the above macro using the definitions from handover_cfg.h */
+HO_CFG_ALL_MEMBERS
+#undef HO_CFG_ONE_MEMBER
+CTRL_CMD_DEFINE(congestion_check_interval, "handover_congestion_check_interval");
+static int get_congestion_check_interval(struct ctrl_cmd *cmd, void *_data)
+{
+	struct gsm_network *net = cmd->node;
+	if (net->hodec2.congestion_check_interval_s > 0)
+		cmd->reply = talloc_asprintf(cmd, "%u", net->hodec2.congestion_check_interval_s);
+	else
+		cmd->reply = "disabled";
+	return CTRL_CMD_REPLY;
+}
+
+static int set_congestion_check_interval(struct ctrl_cmd *cmd, void *_data)
+{
+	struct gsm_network *net = cmd->node;
+	int value;
+
+	/* Trigger congestion check and leave without changing anything */
+	if (strcmp(cmd->value, "now") == 0) {
+		hodec2_congestion_check(net);
+		return get_congestion_check_interval(cmd, _data);
+	}
+
+	if (strcmp(cmd->value, "disabled") == 0)
+		value = 0;
+	else
+		value = atoi(cmd->value);
+	hodec2_on_change_congestion_check_interval(net, value);
+	return CTRL_CMD_REPLY;
+}
+
+static int verify_congestion_check_interval(struct ctrl_cmd *cmd, const char *value, void *_data)
+{
+	if (strcmp(value, "disabled") == 0)
+		return 0;
+	if (strcmp(value, "now") == 0)
+		return 0;
+	if (verify_vty_cmd_arg(cmd, "<1-999>", value))
+		return 0;
+	return -1;
+}
+
+int bsc_ho_ctrl_cmds_install(void)
+{
+	int rc = 0;
+
+#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, VTY0, VTY1, VTY2, VTY_ARG_EVAL, VTY4, VTY5, VTY6) \
+	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_##NAME);\
+
+HO_CFG_ALL_MEMBERS
+#undef HO_CFG_ONE_MEMBER
+	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_congestion_check_interval);
+
+	return rc;
+}
diff --git a/src/osmo-bsc/osmo_bsc_ctrl.c b/src/osmo-bsc/osmo_bsc_ctrl.c
index 05bc86c..5ecee36 100644
--- a/src/osmo-bsc/osmo_bsc_ctrl.c
+++ b/src/osmo-bsc/osmo_bsc_ctrl.c
@@ -28,6 +28,7 @@
 #include <osmocom/bsc/signal.h>
 #include <osmocom/bsc/a_reset.h>
 #include <osmocom/bsc/bts.h>
+#include <osmocom/bsc/handover_ctrl.h>
 
 #include <osmocom/core/linuxlist.h>
 #include <osmocom/core/signal.h>
@@ -697,6 +698,9 @@
 	rc = bsc_base_ctrl_cmds_install();
 	if (rc)
 		goto end;
+	rc = bsc_ho_ctrl_cmds_install();
+	if (rc)
+		goto end;
 	rc = ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_loc);
 	if (rc)
 		goto end;
diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am
index f0b2e7a..e8ebb56 100644
--- a/tests/handover/Makefile.am
+++ b/tests/handover/Makefile.am
@@ -49,6 +49,7 @@
 	$(top_builddir)/src/osmo-bsc/acc.o \
 	$(top_builddir)/src/osmo-bsc/assignment_fsm.o \
 	$(top_builddir)/src/osmo-bsc/bsc_ctrl_commands.o \
+	$(top_builddir)/src/osmo-bsc/handover_ctrl.o \
 	$(top_builddir)/src/osmo-bsc/bsc_init.o \
 	$(top_builddir)/src/osmo-bsc/bsc_rf_ctrl.o \
 	$(top_builddir)/src/osmo-bsc/bsc_rll.o \

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bsc/+/24600
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bsc
Gerrit-Branch: master
Gerrit-Change-Id: I12f143906818fd6b16e8783157cbb1eb51e49ffc
Gerrit-Change-Number: 24600
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210607/e97c643e/attachment.htm>


More information about the gerrit-log mailing list