HO: Implement load based handover, as handover_decision_2.c
Change-Id: Ie597eae82722baf32546331e443dd9d94f1f25e6
This commit is contained in:
parent
8489b463f9
commit
909e972787
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
@ -0,0 +1 @@
|
|||
Test OK
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue