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

laforge gerrit-no-reply at lists.osmocom.org
Mon Jul 19 08:57:18 UTC 2021


laforge has submitted this change. ( 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
Depends: libosmocore I53fc207677f52b1dc748b01d58424839cdba807c
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, 254 insertions(+), 0 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved
  daniel: Looks good to me, but someone else must approve



diff --git a/doc/manuals/chapters/control.adoc b/doc/manuals/chapters/control.adoc
index 85696a0..2585126 100644
--- a/doc/manuals/chapters/control.adoc
+++ b/doc/manuals/chapters/control.adoc
@@ -40,6 +40,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.
+|[bts.N.]handover.active|RW|No|"0","1","default"|Enable/disable handover.
+|[bts.N.]handover.algorithm|RW|No|"1","2","default"|Choose algorithm for handover decision (hodec1 or hodec2).
+|[bts.N.]handover1.window.rxlev.averaging|RW|No|<1-10>,"default"|How many RxLev measurements to use for averaging.
+|[bts.N.]handover1.window.rxqual.averaging|RW|No|<1-10>,"default"|How many RxQual measurements to use for averaging.
+|[bts.N.]handover1.window.rxlev.neighbor.averaging|RW|No|<1-10>,"default"|How many Neighbor RxLev measurements to use for averaging.
+|[bts.N.]handover1.power.budget.interval|RW|No|<1-99>,"default"|How often to check for a better cell (SACCH frames).
+|[bts.N.]handover1.power.budget.hysteresis|RW|No|<0-999>,"default"|How many dB stronger must a neighbor be to become a HO candidate.
+|[bts.N.]handover1.maximum.distance|RW|No|<0-9999>,"default"|Maximum Timing-Advance value (i.e. MS distance) before triggering HO.
+|[bts.N.]handover2.window.rxlev.averaging|RW|No|<1-10>,"default"|How many RxLev measurements to use for averaging.
+|[bts.N.]handover2.window.rxqual.averaging|RW|No|<1-10>,"default"|How many RxQual measurements to use for averaging.
+|[bts.N.]handover2.window.rxlev.neighbor.averaging|RW|No|<1-10>,"default"|window rxlev neighbor averaging.
+|[bts.N.]handover2.power.budget.interval|RW|No|<1-99>,"default"|How many dB stronger must a neighbor be to become a HO candidate.
+|[bts.N.]handover2.power.budget.hysteresis|RW|No|<0-999>,"default"|How many dB stronger must a neighbor be to become a HO candidate.
+|[bts.N.]handover2.maximum.distance|RW|No|<0-9999>,"default"|Maximum Timing-Advance value (i.e. MS distance) before triggering HO.
+|[bts.N.]handover2.assignment|RW|No|"0","1","default"|Enable or disable in-call channel re-assignment within the same cell.
+|[bts.N.]handover2.tdma-measurement|RW|No|"full","subset","default"|Define measurement set of TDMA frames.
+|[bts.N.]handover2.min.rxlev|RW|No|<-110--50>,"default"|How weak may RxLev of an MS become before triggering HO.
+|[bts.N.]handover2.min.rxqual|RW|No|<0-7>,"default"|How bad may RxQual of an MS become before triggering HO.
+|[bts.N.]handover2.afs-bias.rxlev|RW|No|<0-20>,"default"|RxLev improvement bias for AFS over other codecs.
+|[bts.N.]handover2.afs-bias.rxqual|RW|No|<0-7>,"default"|RxQual improvement bias for AFS over other codecs.
+|[bts.N.]handover2.min-free-slots.tch-f|RW|No|<0-9999>,"default"|Minimum free TCH/F timeslots before cell is considered congested.
+|[bts.N.]handover2.min-free-slots.tch-h|RW|No|<0-9999>,"default"|Minimum free TCH/H timeslots before cell is considered congested.
+|[bts.N.]handover2.max-handovers|RW|No|<1-9999>,"default"|Maximum number of concurrent handovers allowed per cell.
+|[bts.N.]handover2.penalty-time.max-distance|RW|No|<0-99999>,"default"|ime to suspend handover for a subscriber after leaving this cell due to exceeding max distance.
+|[bts.N.]handover2.penalty-time.failed-ho|RW|No|<0-99999>,"default"|Time to suspend handover for a subscriber after a failed handover into this cell.
+|[bts.N.]handover2.penalty-time.failed-assignment|RW|No|<0-99999>,"default"|Time to suspend handover for a subscriber after a failed re-assignment within this cell.
+|[bts.N.]handover2.retries|RW|No|<0-9>,"default"|Number of times to immediately retry a failed handover/assignment, before a penalty time is applied.
+|handover2.congestion-check|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 5e866cc..dde08a1 100644
--- a/include/osmocom/bsc/Makefile.am
+++ b/include/osmocom/bsc/Makefile.am
@@ -23,6 +23,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..c0bd70c
--- /dev/null
+++ b/include/osmocom/bsc/handover_ctrl.h
@@ -0,0 +1,3 @@
+#pragma once
+
+int bsc_ho_ctrl_cmds_install(void *ctx);
diff --git a/src/osmo-bsc/Makefile.am b/src/osmo-bsc/Makefile.am
index df4e0c3..840e956 100644
--- a/src/osmo-bsc/Makefile.am
+++ b/src/osmo-bsc/Makefile.am
@@ -61,6 +61,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..139d038
--- /dev/null
+++ b/src/osmo-bsc/handover_ctrl.c
@@ -0,0 +1,216 @@
+/* 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/bts.h>
+#include <osmocom/bsc/handover_decision_2.h>
+#include <osmocom/ctrl/control_cmd.h>
+
+/* In handover_cfg.h the config items are described in VTY syntax. To be able to
+ * use those here in the CTRL interface, we parse the config arguments like the
+ * VTY would. (the value specification may be in the form of "<from-to>" or
+ * "A|B|C|..." */
+static bool verify_vty_cmd_arg(void *ctx, const char *range, const char *value)
+{
+	bool success;
+	char *range_tok;
+	char *valid_val;
+
+	/* "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] == '<') {
+		if (vty_cmd_range_match(range, value))
+			return true;
+		else
+			return false;
+	}
+
+	/* 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;
+}
+
+/* NOTE: The following macro scheme has been designed for using it in the VTY
+ * code. However, for the most part it also works for CTRL interface code as
+ * well. */
+#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, VTY_CMD_PREFIX, VTY_CMD, VTY_CMD_ARG, VTY_ARG_EVAL, VTY_WRITE_FMT, VTY_WRITE_CONV, VTY6) \
+CTRL_CMD_DEFINE(NAME, VTY_CMD_PREFIX VTY_CMD); \
+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; \
+} \
+CTRL_CMD_DEFINE(bts_##NAME, VTY_CMD_PREFIX VTY_CMD); \
+static int get_bts_##NAME(struct ctrl_cmd *cmd, void *_data) \
+{ \
+        struct gsm_bts *bts = cmd->node; \
+	struct handover_cfg *ho = bts->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_bts_##NAME(struct ctrl_cmd *cmd, void *_data) \
+{ \
+	struct gsm_bts *bts = cmd->node; \
+	struct handover_cfg *ho = bts->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_bts_##NAME(cmd, _data); \
+} \
+static int verify_bts_##NAME(struct ctrl_cmd *cmd, const char *value, void *_data) \
+{ \
+	return verify_##NAME(cmd, value, _data); \
+} \
+
+/* 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, "handover2 congestion-check");
+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 get_congestion_check_interval(cmd, _data);
+}
+
+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;
+}
+
+/* Filter name member in cmd for illegal '/' characters */
+static struct ctrl_cmd_element *filter_name(void *ctx,
+					    struct ctrl_cmd_element *cmd)
+{
+	unsigned int i;
+	char *name;
+
+	if (osmo_separated_identifiers_valid(cmd->name, " -"))
+		return cmd;
+
+	name = talloc_strdup(ctx, cmd->name);
+	for (i = 0; i < strlen(name); i++) {
+		if (name[i] == '/')
+			name[i] = '-';
+	}
+
+	cmd->name = name;
+	return cmd;
+}
+
+int bsc_ho_ctrl_cmds_install(void *ctx)
+{
+	int rc = 0;
+
+	rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_congestion_check_interval);
+
+#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, filter_name(ctx, &cmd_##NAME)); \
+	rc |= ctrl_cmd_install(CTRL_NODE_BTS, filter_name(ctx, &cmd_bts_##NAME)); \
+
+HO_CFG_ALL_MEMBERS
+#undef HO_CFG_ONE_MEMBER
+
+	return rc;
+}
diff --git a/src/osmo-bsc/osmo_bsc_ctrl.c b/src/osmo-bsc/osmo_bsc_ctrl.c
index 05bc86c..1eea690 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(net);
+	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 65eb6a8..c7621d2 100644
--- a/tests/handover/Makefile.am
+++ b/tests/handover/Makefile.am
@@ -50,6 +50,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: 9
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Assignee: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: neels <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210719/fe139a43/attachment.htm>


More information about the gerrit-log mailing list