HO: Implement load based handover, as handover_decision_2.c

Change-Id: Ie597eae82722baf32546331e443dd9d94f1f25e6
This commit is contained in:
Neels Hofmeyr 2017-12-07 03:54:01 +01:00
parent 8489b463f9
commit 909e972787
18 changed files with 3725 additions and 2 deletions

View File

@ -164,6 +164,7 @@ AC_OUTPUT(
tests/subscr/Makefile
tests/nanobts_omlattr/Makefile
tests/bssap/Makefile
tests/handover/Makefile
doc/Makefile
doc/examples/Makefile
Makefile)

View File

@ -10,6 +10,7 @@ network
neci 0
paging any use tch 0
handover 0
handover algorithm 1
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10

View File

@ -9,6 +9,7 @@ network
neci 0
paging any use tch 0
handover 0
handover algorithm 1
handover window rxlev averaging 10
handover window rxqual averaging 1
handover window rxlev neighbor averaging 10

View File

@ -24,6 +24,7 @@ noinst_HEADERS = \
handover.h \
handover_cfg.h \
handover_decision.h \
handover_decision_2.h \
handover_vty.h \
ipaccess.h \
meas_feed.h \

View File

@ -116,6 +116,7 @@ struct gsm_subscriber_connection {
unsigned int ho_dtap_cache_len;
struct {
int failures;
struct penalty_timers *penalty_timers;
} hodec2;
@ -1197,7 +1198,12 @@ struct gsm_network {
/* bit-mask of permitted encryption algorithms. LSB=A5/0, MSB=A5/7 */
uint8_t a5_encryption_mask;
int neci;
struct handover_cfg *ho;
struct {
unsigned int congestion_check_interval_s;
struct osmo_timer_list congestion_check_timer;
} hodec2;
struct rate_ctr_group *bsc_ctrs;

View File

@ -10,6 +10,8 @@ struct vty;
* the defaults from 'network' level are used implicitly, and changes take effect immediately. */
struct handover_cfg;
#define HO_CFG_CONGESTION_CHECK_DEFAULT 10
struct handover_cfg *ho_cfg_init(void *ctx, struct handover_cfg *higher_level_cfg);
#define HO_CFG_STR_HANDOVER1 "Handover options for handover decision algorithm 1\n"

View File

@ -0,0 +1,9 @@
/* Handover Decision Algorithm 2 for intra-BSC (inter-BTS) handover, public API for OsmoBSC */
#pragma once
struct gsm_bts;
void hodec2_init(struct gsm_network *net);
void hodec2_on_change_congestion_check_interval(struct gsm_network *net, unsigned int new_interval);
void hodec2_congestion_check(struct gsm_network *net);

View File

@ -60,5 +60,6 @@ libbsc_a_SOURCES = \
handover_vty.c \
handover_cfg.c \
penalty_timers.c \
handover_decision_2.c \
$(NULL)

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include <osmocom/bsc/gsm_data.h>
#include <osmocom/bsc/vty.h>
#include <osmocom/bsc/handover_cfg.h>
#include <osmocom/bsc/handover_decision_2.h>
static struct handover_cfg *ho_cfg_from_vty(struct vty *vty)
{
@ -70,6 +71,41 @@ HO_CFG_ALL_MEMBERS
#undef HO_CFG_ONE_MEMBER
static inline const int a2congestion_check_interval(const char *arg)
{
if (!strcmp(arg, "disabled"))
return 0;
return atoi(arg);
}
static inline const char *congestion_check_interval2a(int val)
{
static char str[9];
if (val < 1
|| snprintf(str, sizeof(str), "%d", val) >= sizeof(str))
return "disabled";
return str;
}
DEFUN(cfg_net_ho_congestion_check_interval, cfg_net_ho_congestion_check_interval_cmd,
"handover2 congestion-check (disabled|<1-999>|now)",
HO_CFG_STR_HANDOVER2
"Configure congestion check interval" HO_CFG_STR_2
"Disable congestion checking, do not handover based on cell overload\n"
"Congestion check interval in seconds (default "
OSMO_STRINGIFY_VAL(HO_CFG_CONGESTION_CHECK_DEFAULT) ")\n"
"Manually trigger a congestion check to run right now\n")
{
if (!strcmp(argv[0], "now")) {
hodec2_congestion_check(gsmnet_from_vty(vty));
return CMD_SUCCESS;
}
hodec2_on_change_congestion_check_interval(gsmnet_from_vty(vty),
a2congestion_check_interval(argv[0]));
return CMD_SUCCESS;
}
static void ho_vty_write(struct vty *vty, const char *indent, struct handover_cfg *ho)
{
#define HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL, \
@ -93,7 +129,10 @@ void ho_vty_write_net(struct vty *vty, struct gsm_network *net)
{
ho_vty_write(vty, " ", net->ho);
/* future: net specific vty commands */
if (net->hodec2.congestion_check_interval_s != HO_CFG_CONGESTION_CHECK_DEFAULT)
vty_out(vty, " handover congestion-check %s%s",
congestion_check_interval2a(net->hodec2.congestion_check_interval_s),
VTY_NEWLINE);
}
static void ho_vty_init_cmds(int parent_node)
@ -108,6 +147,8 @@ static void ho_vty_init_cmds(int parent_node)
void ho_vty_init()
{
ho_vty_init_cmds(GSMNET_NODE);
install_element(GSMNET_NODE, &cfg_net_ho_congestion_check_interval_cmd);
ho_vty_init_cmds(BTS_NODE);
}

View File

@ -87,6 +87,7 @@ struct gsm_network *bsc_network_init(void *ctx,
net->T3141 = GSM_T3141_DEFAULT;
net->ho = ho_cfg_init(net, NULL);
net->hodec2.congestion_check_interval_s = HO_CFG_CONGESTION_CHECK_DEFAULT;
INIT_LLIST_HEAD(&net->bts_list);

View File

@ -31,6 +31,7 @@
#include <osmocom/bsc/osmo_bsc_sigtran.h>
#include <osmocom/bsc/osmo_bsc_mgcp.h>
#include <osmocom/bsc/handover_decision.h>
#include <osmocom/bsc/handover_decision_2.h>
#include <osmocom/ctrl/control_cmd.h>
#include <osmocom/ctrl/control_if.h>
@ -513,6 +514,7 @@ int main(int argc, char **argv)
mgcp_init(bsc_gsmnet);
handover_decision_1_init();
hodec2_init(bsc_gsmnet);
signal(SIGINT, &signal_handler);
signal(SIGTERM, &signal_handler);

View File

@ -8,6 +8,7 @@ SUBDIRS = \
bsc-nat \
bsc-nat-trie \
bssap \
handover \
$(NULL)
# The `:;' works around a Bash 3.2 bug when the output is not writeable.

View File

@ -0,0 +1,35 @@
AM_CPPFLAGS = \
$(all_includes) \
-I$(top_srcdir)/include \
$(NULL)
AM_CFLAGS = \
-Wall \
-ggdb3 \
$(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) \
$(NULL)
AM_LDFLAGS = \
$(COVERAGE_LDFLAGS) \
$(NULL)
EXTRA_DIST = \
handover_test.ok \
$(NULL)
noinst_PROGRAMS = \
handover_test \
$(NULL)
handover_test_SOURCES = \
handover_test.c \
$(NULL)
handover_test_LDADD = \
$(LIBOSMOCORE_LIBS) \
$(LIBOSMOGSM_LIBS) \
$(LIBOSMOABIS_LIBS) \
$(top_builddir)/src/libbsc/libbsc.a \
$(NULL)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
Test OK

View File

@ -190,6 +190,7 @@ OsmoBSC(config-net)# list
handover2 penalty-time failed-ho (<0-99999>|default)
handover2 penalty-time failed-assignment (<0-99999>|default)
handover2 retries (<0-9>|default)
handover2 congestion-check (disabled|<1-999>|now)
...
OsmoBSC(config-net)# handover?
@ -219,6 +220,7 @@ OsmoBSC(config-net)# handover2 ?
max-handovers Maximum number of concurrent handovers allowed per cell (HO algo 2 only)
penalty-time Set penalty times to wait between repeated handovers (HO algo 2 only)
retries Immediately retry on handover/assignment failure (HO algo 2 only)
congestion-check Configure congestion check interval (HO algo 2 only)
OsmoBSC(config-net)# handover algorithm ?
1 Algorithm 1: trigger handover based on comparing current cell and neighbor RxLev and RxQual, only.
@ -395,8 +397,13 @@ OsmoBSC(config-net)# handover2 retries ?
<0-9> Number of retries
default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# handover2 congestion-check ?
disabled Disable congestion checking, do not handover based on cell overload
<1-999> Congestion check interval in seconds (default 10)
now Manually trigger a congestion check to run right now
OsmoBSC(config-net)# ### Same on BTS level
OsmoBSC(config-net)# ### Same on BTS level, except for the congestion-check
OsmoBSC(config-net)# bts 0
OsmoBSC(config-net-bts)# handover?

View File

@ -51,3 +51,177 @@ cat $abs_srcdir/bssap/bssap_test.ok > expout
cat $abs_srcdir/bssap/bssap_test.err > experr
AT_CHECK([$abs_top_builddir/tests/bssap/bssap_test], [], [expout], [experr])
AT_CLEANUP
AT_SETUP([handover test 0])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 0], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 1])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 1], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 2])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 2], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 3])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 3], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 4])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 4], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 5])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 5], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 6])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 6], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 7])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 7], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 8])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 8], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 9])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 9], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 10])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 10], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 11])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 11], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 12])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 12], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 13])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 13], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 14])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 14], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 15])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 15], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 16])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 16], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 17])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 17], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 18])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 18], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 19])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 19], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 20])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 20], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 21])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 21], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 22])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 22], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 23])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 23], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 24])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 24], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 25])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 25], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 26])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 26], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 27])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 27], [], [expout], [ignore])
AT_CLEANUP
AT_SETUP([handover test 28])
AT_KEYWORDS([handover])
cat $abs_srcdir/handover/handover_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/handover/handover_test 28], [], [expout], [ignore])
AT_CLEANUP