aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorAlexander Couzens <lynxis@fe80.eu>2020-12-14 02:36:53 +0100
committerAlexander Couzens <lynxis@fe80.eu>2021-01-01 22:46:57 +0100
commitc0d02cc16341198ac8c3b4813f1403a856ac047e (patch)
treebb1326239a87221d86582472a39b98521fa564b6 /utils
parentf73753543266917e1b96e81d65ebedc5e9d8792f (diff)
utils: add osmo-ns-dummy
A dummy client to do integration tests of the ns2 layer. It drop all unit data. But allows vty tests. Change-Id: I127c178426bc1a3da8de251740eda93853030d6d
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile.am21
-rw-r--r--utils/osmo-ns-dummy.c274
2 files changed, 292 insertions, 3 deletions
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 653b7190..4fac477d 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -1,11 +1,14 @@
-if ENABLE_UTILITIES
+
+bin_PROGRAMS =
+noinst_PROGRAMS =
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include $(TALLOC_CFLAGS)
AM_CFLAGS = -Wall $(PTHREAD_CFLAGS)
LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la $(PTHREAD_LIBS)
+if ENABLE_UTILITIES
EXTRA_DIST = conv_gen.py conv_codes_gsm.py
-bin_PROGRAMS = osmo-arfcn osmo-auc-gen osmo-config-merge
+bin_PROGRAMS += osmo-arfcn osmo-auc-gen osmo-config-merge
osmo_arfcn_SOURCES = osmo-arfcn.c
@@ -16,9 +19,21 @@ osmo_config_merge_LDADD = $(LDADD) $(TALLOC_LIBS)
osmo_config_merge_CFLAGS = $(TALLOC_CFLAGS)
if ENABLE_PCSC
-noinst_PROGRAMS = osmo-sim-test
+noinst_PROGRAMS += osmo-sim-test
osmo_sim_test_SOURCES = osmo-sim-test.c
osmo_sim_test_LDADD = $(LDADD) $(top_builddir)/src/sim/libosmosim.la $(PCSC_LIBS)
osmo_sim_test_CFLAGS = $(PCSC_CFLAGS)
endif
endif
+
+if ENABLE_EXT_TESTS
+if ENABLE_GB
+noinst_PROGRAMS += osmo-ns-dummy
+osmo_ns_dummy_SOURCES = osmo-ns-dummy.c
+osmo_ns_dummy_LDADD = $(LDADD) $(TALLOC_LIBS) \
+ $(top_builddir)/src/gb/libosmogb.la \
+ $(top_builddir)/src/vty/libosmovty.la \
+ $(top_builddir)/src/gsm/libosmogsm.la
+osmo_ns_dummy_CFLAGS = $(TALLOC_CFLAGS)
+endif
+endif
diff --git a/utils/osmo-ns-dummy.c b/utils/osmo-ns-dummy.c
new file mode 100644
index 00000000..6790b4c3
--- /dev/null
+++ b/utils/osmo-ns-dummy.c
@@ -0,0 +1,274 @@
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <signal.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/application.h>
+#include <osmocom/core/stats.h>
+
+#include <osmocom/gprs/gprs_ns2.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/ports.h>
+#include <osmocom/vty/tdef_vty.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/stats.h>
+#include <osmocom/vty/misc.h>
+
+#include "config.h"
+
+void *tall_nsdummy_ctx = NULL;
+static struct log_info log_info = {};
+static bool quit = false;
+static bool config_given = false;
+static bool daemonize = false;
+static int vty_port = 0;
+static char *config_file = NULL;
+
+static const char vty_copyright[] =
+ "Copyright (C) 2020 by by sysmocom - s.f.m.c. GmbH\r\n"
+ "Author: Alexander Couzens <lynxis@fe80.eu>\r\n"
+ "License GNU GPL version 2 or later\r\n"
+ "This is free software: you are free to change and redistribute it.\r\n"
+ "There is NO WARRANTY, to the extent permitted by law.\r\n";
+
+static struct vty_app_info vty_info = {
+ .name = "OsmoNSdummy",
+ .version = PACKAGE_VERSION,
+ .copyright = vty_copyright,
+};
+
+static void print_help()
+{
+ printf( "Some useful options:\n"
+ " -h --help This text\n"
+ " -c --config-file Specify the filename of the config file\n"
+ " -V --version Print version\n"
+ " -D --daemonize Fork the process into a background daemon\n"
+ " -p --vty-port PORT Set the vty port to listen on.\n"
+ "\nVTY reference generation:\n"
+ " --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n"
+ " --vty-ref-xml Generate the VTY reference XML output and exit.\n"
+ );
+}
+
+static void handle_long_options(const char *prog_name, const int long_option)
+{
+ static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
+
+ switch (long_option) {
+ case 1:
+ vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
+ if (vty_ref_mode < 0) {
+ fprintf(stderr, "%s: Unknown VTY reference generation "
+ "mode '%s'\n", prog_name, optarg);
+ exit(2);
+ }
+ break;
+ case 2:
+ fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
+ get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
+ get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
+ vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
+ exit(0);
+ default:
+ fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
+ exit(2);
+ }
+}
+
+static void handle_options(int argc, char **argv)
+{
+ while (1) {
+ int option_idx = 0, c;
+ static int long_option = 0;
+ static const struct option long_options[] = {
+ { "help", 0, 0, 'h' },
+ { "config-file", 1, 0, 'c' },
+ { "version", 0, 0, 'V' },
+ { "daemonize", 0, 0, 'D' },
+ { "vty-port", 1, 0, 'p' },
+ { "vty-ref-mode", 1, &long_option, 1 },
+ { "vty-ref-xml", 0, &long_option, 2 },
+ { 0, 0, 0, 0 }
+ };
+
+ c = getopt_long(argc, argv, "hc:p:VD",
+ long_options, &option_idx);
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'h':
+ print_help();
+ exit(0);
+ break;
+ case 0:
+ handle_long_options(argv[0], long_option);
+ break;
+ case 'c':
+ if (config_file)
+ free(config_file);
+ config_file = optarg;
+ config_given = true;
+ break;
+ case 'p':
+ vty_port = atoi(optarg);
+ if (vty_port < 0 || vty_port > 65535) {
+ fprintf(stderr, "Invalid port %d given!\n", vty_port);
+ exit(1);
+ }
+ break;
+ case 'V':
+ print_version(1);
+ exit(0);
+ break;
+ case 'D':
+ daemonize = true;
+ break;
+ default:
+ fprintf(stderr, "Unknown option '%c'\n", c);
+ exit(0);
+ break;
+ }
+ }
+
+ if (!config_file)
+ config_file = "osmo-ns-dummy.cfg";
+ if (!vty_port) {
+ fprintf(stderr, "A vty port need to be specified (-p)\n");
+ exit(1);
+ }
+}
+
+void sighandler(int sigset)
+{
+ if (sigset == SIGPIPE)
+ return;
+
+ fprintf(stderr, "Signal %d received.\n", sigset);
+
+ switch (sigset) {
+ case SIGINT:
+ case SIGTERM:
+ /* If another signal is received afterwards, the program
+ * is terminated without finishing shutdown process.
+ */
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGPIPE, SIG_DFL);
+ signal(SIGABRT, SIG_DFL);
+ signal(SIGUSR1, SIG_DFL);
+ signal(SIGUSR2, SIG_DFL);
+
+ quit = 1;
+ break;
+ case SIGABRT:
+ /* in case of abort, we want to obtain a talloc report and
+ * then run default SIGABRT handler, who will generate coredump
+ * and abort the process. abort() should do this for us after we
+ * return, but program wouldn't exit if an external SIGABRT is
+ * received.
+ */
+ talloc_report_full(tall_nsdummy_ctx, stderr);
+ signal(SIGABRT, SIG_DFL);
+ raise(SIGABRT);
+ break;
+ case SIGUSR1:
+ case SIGUSR2:
+ talloc_report_full(tall_nsdummy_ctx, stderr);
+ break;
+ }
+}
+
+/* called by the ns layer */
+int gprs_ns_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ return 0;
+}
+
+int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
+{
+ return 0;
+}
+
+
+int main (int argc, char *argv[])
+{
+ void *ctx = tall_nsdummy_ctx = talloc_named_const(NULL, 0, "osmo-ns-dummy");
+ struct gprs_ns2_inst *nsi;
+ int rc = 0;
+
+ osmo_init_logging2(ctx, &log_info);
+ log_set_use_color(osmo_stderr_target, 0);
+ log_set_print_filename(osmo_stderr_target, 0);
+ log_set_print_filename(osmo_stderr_target, 0);
+ log_set_log_level(osmo_stderr_target, LOGL_INFO);
+ msgb_talloc_ctx_init(ctx, 0);
+ osmo_stats_init(ctx);
+ rate_ctr_init(ctx);
+
+ vty_info.tall_ctx = ctx;
+ vty_init(&vty_info);
+ logging_vty_add_cmds();
+ osmo_stats_vty_add_cmds();
+ osmo_talloc_vty_add_cmds();
+
+ handle_options(argc, argv);
+
+ nsi = gprs_ns2_instantiate(ctx, gprs_ns_prim_cb, NULL);
+ if (!nsi) {
+ LOGP(DLNS, LOGL_ERROR, "Failed to create NS instance\n");
+ exit(1);
+ }
+
+ gprs_ns2_vty2_init(nsi);
+ rc = vty_read_config_file(config_file, NULL);
+ if (rc < 0 && config_given) {
+ fprintf(stderr, "Failed to parse the config file: '%s'\n",
+ config_file);
+ exit(1);
+ }
+ if (rc < 0)
+ fprintf(stderr, "No config file: '%s' Using default config.\n",
+ config_file);
+
+ rc = telnet_init_dynif(ctx, NULL, vty_get_bind_addr(),
+ vty_port);
+ if (rc < 0) {
+ fprintf(stderr, "Error initializing telnet\n");
+ exit(1);
+ }
+
+ signal(SIGINT, sighandler);
+ signal(SIGTERM, sighandler);
+ signal(SIGPIPE, sighandler);
+ signal(SIGABRT, sighandler);
+ signal(SIGUSR1, sighandler);
+ signal(SIGUSR2, sighandler);
+ osmo_init_ignore_signals();
+
+ if (daemonize) {
+ rc = osmo_daemonize();
+ if (rc < 0) {
+ perror("Error during daemonize");
+ exit(1);
+ }
+ }
+
+ while (!quit) {
+ osmo_select_main(0);
+ }
+
+ telnet_exit();
+ gprs_ns2_free(nsi);
+
+ talloc_report_full(tall_nsdummy_ctx, stderr);
+ talloc_free(tall_nsdummy_ctx);
+
+ return 0;
+}