aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJere Leppänen <jere.leppanen@nokia.com>2021-01-29 13:26:03 +0200
committerPetri Savolainen <petri.savolainen@nokia.com>2021-02-23 11:01:07 +0200
commitfee7bbb8a1512c37c118605a09867476f3bbef77 (patch)
tree8d43e253f2d355d600532edb1ba0d06ef66b269f
parentf9f29f9aad106bfd31b0e50ff5b886d9a7a7a5bf (diff)
example: add CLI helper example
This example shows how to start and stop ODP CLI using the CLI helper API functions. Signed-off-by: Jere Leppänen <jere.leppanen@nokia.com> Reviewed-by: Matias Elo <matias.elo@nokia.com>
-rw-r--r--doc/application-api-guide/examples.dox5
-rw-r--r--example/Makefile.am4
-rw-r--r--example/cli/.gitignore3
-rw-r--r--example/cli/Makefile.am31
-rw-r--r--example/cli/odp_cli.c176
-rwxr-xr-xexample/cli/odp_cli_run.sh9
-rw-r--r--example/m4/configure.m41
7 files changed, 229 insertions, 0 deletions
diff --git a/doc/application-api-guide/examples.dox b/doc/application-api-guide/examples.dox
index 98e66d72b..18817cd63 100644
--- a/doc/application-api-guide/examples.dox
+++ b/doc/application-api-guide/examples.dox
@@ -10,6 +10,11 @@
*/
/**
+ * @example odp_cli.c
+ * CLI example application
+ */
+
+/**
* @example odp_debug.c
* Debug example application
*/
diff --git a/example/Makefile.am b/example/Makefile.am
index fc4623d1f..d6d242cf9 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -18,3 +18,7 @@ SUBDIRS = classifier \
if HAVE_DW_ATOMIC_CMP_EXC
SUBDIRS += ipfragreass
endif
+
+if helper_cli
+SUBDIRS += cli
+endif
diff --git a/example/cli/.gitignore b/example/cli/.gitignore
new file mode 100644
index 000000000..2a19d7a64
--- /dev/null
+++ b/example/cli/.gitignore
@@ -0,0 +1,3 @@
+odp_cli
+*.log
+*.trs
diff --git a/example/cli/Makefile.am b/example/cli/Makefile.am
new file mode 100644
index 000000000..0e97a09ed
--- /dev/null
+++ b/example/cli/Makefile.am
@@ -0,0 +1,31 @@
+include $(top_srcdir)/example/Makefile.inc
+
+bin_PROGRAMS = odp_cli
+
+odp_cli_SOURCES = odp_cli.c
+
+if test_example
+TESTS = odp_cli_run.sh
+endif
+
+EXTRA_DIST = odp_cli_run.sh
+
+# If building out-of-tree, make check will not copy the scripts and data to the
+# $(builddir) assuming that all commands are run locally. However this prevents
+# running tests on a remote target using LOG_COMPILER.
+# So copy all script and data files explicitly here.
+all-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ if [ -e $(srcdir)/$$f ]; then \
+ mkdir -p $(builddir)/$$(dirname $$f); \
+ cp -f $(srcdir)/$$f $(builddir)/$$f; \
+ fi \
+ done \
+ fi
+clean-local:
+ if [ "x$(srcdir)" != "x$(builddir)" ]; then \
+ for f in $(EXTRA_DIST); do \
+ rm -f $(builddir)/$$f; \
+ done \
+ fi
diff --git a/example/cli/odp_cli.c b/example/cli/odp_cli.c
new file mode 100644
index 000000000..e3998129c
--- /dev/null
+++ b/example/cli/odp_cli.c
@@ -0,0 +1,176 @@
+/* Copyright (c) 2021, Nokia
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * ODP CLI Helper Example
+ *
+ * This example shows how to start and stop ODP CLI using the CLI helper
+ * API functions. This example application can also be used to try out
+ * the CLI by connecting to a running application with a telnet client.
+ */
+
+#include <odp_api.h>
+#include <odp/helper/odph_api.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <signal.h>
+
+typedef struct {
+ int time;
+ char *addr;
+ uint16_t port;
+} options_t;
+
+static void usage(const char *prog)
+{
+ printf("\n"
+ "Usage: %s [options]\n"
+ "\n"
+ "OPTIONS:\n"
+ " -t, --time <sec> Keep CLI open for <sec> seconds. (default -1 (infinite))\n"
+ " -a, --address <addr> Bind listening socket to IP address <addr>.\n"
+ " -p, --port <port> Bind listening socket to port <port>.\n"
+ "\n"
+ "ODP helper defaults are used for address and port, if the options are\n"
+ "not given.\n"
+ "\n",
+ prog);
+}
+
+static void parse_args(int argc, char *argv[], options_t *opt)
+{
+ static const struct option longopts[] = {
+ { "time", required_argument, NULL, 't' },
+ { "address", required_argument, NULL, 'a' },
+ { "port", required_argument, NULL, 'p' },
+ { "help", no_argument, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ static const char *shortopts = "+t:a:p:h";
+
+ while (1) {
+ int c = getopt_long(argc, argv, shortopts, longopts, NULL);
+
+ if (c == -1)
+ break; /* No more options */
+
+ switch (c) {
+ case 't':
+ opt->time = atoi(optarg);
+ break;
+ case 'a':
+ opt->addr = optarg;
+ break;
+ case 'p':
+ opt->port = atoi(optarg);
+ break;
+ default:
+ usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ break;
+ }
+ }
+
+ optind = 1; /* reset 'extern optind' from the getopt lib */
+}
+
+static volatile int shutdown_sig;
+
+static void sig_handler(int signo)
+{
+ (void)signo;
+
+ shutdown_sig = 1;
+}
+
+int main(int argc, char *argv[])
+{
+ signal(SIGINT, sig_handler);
+
+ odph_helper_options_t helper_options;
+
+ /* Let helper collect its own arguments (e.g. --odph_proc) */
+ argc = odph_parse_options(argc, argv);
+ if (odph_options(&helper_options)) {
+ ODPH_ERR("Error: reading ODP helper options failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ odp_init_t init;
+
+ odp_init_param_init(&init);
+ init.mem_model = helper_options.mem_model;
+
+ options_t opt = {
+ .time = -1,
+ .addr = NULL,
+ .port = 0,
+ };
+
+ parse_args(argc, argv, &opt);
+
+ /* Initialize ODP. */
+
+ odp_instance_t inst;
+
+ if (odp_init_global(&inst, &init, NULL)) {
+ ODPH_ERR("Global init failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_init_local(inst, ODP_THREAD_CONTROL)) {
+ ODPH_ERR("Local init failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Prepare CLI parameters. */
+
+ odph_cli_param_t cli_param;
+
+ odph_cli_param_init(&cli_param);
+
+ if (opt.addr)
+ cli_param.address = opt.addr;
+
+ if (opt.port)
+ cli_param.port = opt.port;
+
+ /* Start CLI server. */
+ if (odph_cli_start(inst, &cli_param)) {
+ ODPH_ERR("CLI start failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("CLI server started on %s:%d\n", cli_param.address, cli_param.port);
+
+ /* Wait for the given number of seconds. */
+ for (int i = 0; (opt.time < 0 || i < opt.time) && !shutdown_sig; i++)
+ odp_time_wait_ns(ODP_TIME_SEC_IN_NS);
+
+ printf("Stopping CLI server.\n");
+
+ /* Stop CLI server. */
+ if (odph_cli_stop()) {
+ ODPH_ERR("CLI stop failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Terminate ODP. */
+
+ if (odp_term_local()) {
+ ODPH_ERR("Local term failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (odp_term_global(inst)) {
+ ODPH_ERR("Global term failed.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
diff --git a/example/cli/odp_cli_run.sh b/example/cli/odp_cli_run.sh
new file mode 100755
index 000000000..0dc00b793
--- /dev/null
+++ b/example/cli/odp_cli_run.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+#
+# Copyright (c) 2021, Nokia
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+./odp_cli${EXEEXT} -t 2
diff --git a/example/m4/configure.m4 b/example/m4/configure.m4
index a1668e2b3..b02fd72a5 100644
--- a/example/m4/configure.m4
+++ b/example/m4/configure.m4
@@ -20,6 +20,7 @@ AC_ARG_ENABLE([test-example],
AM_CONDITIONAL([test_example], [test x$test_example = xyes ])
AC_CONFIG_FILES([example/classifier/Makefile
+ example/cli/Makefile
example/debug/Makefile
example/generator/Makefile
example/hello/Makefile