diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | examples/Makefile.am | 10 | ||||
-rw-r--r-- | examples/udp-test-client.c | 43 | ||||
-rw-r--r-- | examples/udp-test-server.c | 35 | ||||
-rw-r--r-- | examples/udp-test.h | 137 |
5 files changed, 227 insertions, 0 deletions
@@ -51,3 +51,5 @@ examples/stream-client examples/stream-server Doxyfile +/examples/udp-test-client +/examples/udp-test-server diff --git a/examples/Makefile.am b/examples/Makefile.am index ddfaa48..df13808 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -14,9 +14,13 @@ noinst_PROGRAMS = ipa-stream-client \ rs232-write \ rtp-udp-test-client \ rtp-udp-test-server \ + udp-test-client \ + udp-test-server \ osmux-test-input \ osmux-test-output +noinst_HEADERS = udp-test.h + ipa_stream_client_SOURCES = ipa-stream-client.c ipa_stream_client_LDADD = $(top_builddir)/src/libosmonetif.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) @@ -57,6 +61,12 @@ rtp_udp_test_server_SOURCES = rtp-udp-test-server.c rtp_udp_test_server_LDADD = $(top_builddir)/src/libosmonetif.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) +udp_test_client_SOURCES = udp-test-client.c +udp_test_client_LDADD = $(top_builddir)/src/libosmonetif.la $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + +udp_test_server_SOURCES = udp-test-server.c +udp_test_server_LDADD = $(top_builddir)/src/libosmonetif.la $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + osmux_test_input_SOURCES = osmux-test-input.c osmux_test_input_LDADD = $(top_builddir)/src/libosmonetif.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) diff --git a/examples/udp-test-client.c b/examples/udp-test-client.c new file mode 100644 index 0000000..efd746b --- /dev/null +++ b/examples/udp-test-client.c @@ -0,0 +1,43 @@ +#include "udp-test.h" + +static int read_cb(struct osmo_dgram *conn) +{ + struct msgb *msg = print_recv(conn); + if (!msg) + return -1; + + if (msgb_length(msg)) + if (msgb_data(msg)[0] >= NUM_MSG - 1) + please_dont_die = false; /* end test: */ + + msgb_free(msg); + + return 0; +} + +int main(int argc, char **argv) +{ + uint8_t i; + + if (!dgram_init(THOST, CPORT, SPORT, read_cb)) + exit(EXIT_FAILURE); + + for(i = 0; i < NUM_MSG + 1; i++) { + /* N. B: moving this alocation outside of the loop will result in segfault */ + struct msgb *msg = msgb_alloc(MAX_MSG, "UDP/client"); + if (!msg) { + LOGP(DUDP_TEST, LOGL_ERROR, "cann't allocate message\n"); + return EXIT_FAILURE; + } + + if (!mtrim(msg, i, i)) + return EXIT_FAILURE; + + LOGP(DUDP_TEST, LOGL_NOTICE, "queue [%u] %s\n", msgb_length(msg), msgb_hexdump(msg)); + osmo_dgram_send(conn, msg); + } + + main_loop(THOST, CPORT, SPORT); + + return 0; +} diff --git a/examples/udp-test-server.c b/examples/udp-test-server.c new file mode 100644 index 0000000..444843a --- /dev/null +++ b/examples/udp-test-server.c @@ -0,0 +1,35 @@ +#include "udp-test.h" + +int read_cb(struct osmo_dgram *conn) +{ + int bytes; + struct msgb *msg = print_recv(conn); + + if (!msg) + return -1; + + /* build reply: */ + bytes = msgb_length(msg); + + if (!mtrim(msg, 0, bytes)) + return -1; + + /* sent reply: */ + osmo_dgram_send(conn, msg); + + /* end test: */ + if (bytes > NUM_MSG - 1) + please_dont_die = false; + + return 0; +} + +int main(int argc, char **argv) +{ + if (!dgram_init(THOST, SPORT, CPORT, read_cb)) + return EXIT_FAILURE; + + main_loop(THOST, SPORT, CPORT); + + return 0; +} diff --git a/examples/udp-test.h b/examples/udp-test.h new file mode 100644 index 0000000..14bbd91 --- /dev/null +++ b/examples/udp-test.h @@ -0,0 +1,137 @@ +#pragma once + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <arpa/inet.h> +#include <time.h> + +#include <osmocom/core/talloc.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/application.h> +#include <osmocom/core/select.h> +#include <osmocom/netif/datagram.h> + +#define MAX_MSG 255 +#define NUM_MSG 11 +#define DUDP_TEST 0 +#define THOST "127.0.0.1" +#define SPORT 15000 +#define CPORT 15001 + +static struct osmo_dgram *conn; +static void *tall_test; +bool please_dont_die = true; + +static void sighandler(int foo) +{ + LOGP(DLINP, LOGL_NOTICE, "closing UDP test...\n"); + osmo_dgram_close(conn); + osmo_dgram_destroy(conn); + please_dont_die = false; +} + +static inline struct msgb *print_recv(struct osmo_dgram *conn) +{ + struct msgb *msg = msgb_alloc(MAX_MSG, "UDP/test"); + int bytes; + + LOGP(DUDP_TEST, LOGL_NOTICE, "received datagram: "); + + if (!msg) { + LOGPC(DUDP_TEST, LOGL_ERROR, "can't allocate message\n"); + return NULL; + } + + /* receive message: */ + bytes = osmo_dgram_recv(conn, msg); + if (bytes < 0) { + LOGPC(DUDP_TEST, LOGL_ERROR, "can't receive message: %u\n", -bytes); + msgb_free(msg); + return NULL; + } + + /* process message: */ + LOGPC(DUDP_TEST, LOGL_NOTICE, "[%u] %s\n", bytes, msgb_hexdump(msg)); + + return msg; +} + +static inline bool dgram_init(const char *host, uint16_t lport, uint16_t rport, void *read_cb) +{ + const struct log_info_cat udp_test_cat[] = { + [DUDP_TEST] = { + .name = "DUDP_TEST", + .description = "UDP test", + .color = "\033[1;35m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + }; + + const struct log_info udp_test_log_info = { + .filter_fn = NULL, + .cat = udp_test_cat, + .num_cat = ARRAY_SIZE(udp_test_cat), + }; + + signal(SIGINT, sighandler); + + tall_test = talloc_named_const(NULL, 1, "udp_test"); + + osmo_init_logging(&udp_test_log_info); + log_set_log_level(osmo_stderr_target, LOGL_NOTICE); + + conn = osmo_dgram_create(tall_test); + if (!conn) { + LOGP(DUDP_TEST, LOGL_ERROR, "cannot create UDP socket\n"); + return false; + } + + osmo_dgram_set_local_addr(conn, host); + osmo_dgram_set_local_port(conn, lport); + osmo_dgram_set_remote_addr(conn, host); + osmo_dgram_set_remote_port(conn, rport); + osmo_dgram_set_read_cb(conn, read_cb); + + if (osmo_dgram_open(conn) < 0) { + LOGP(DUDP_TEST, LOGL_ERROR, "cannot open client connection %s:%u -> %s:%u\n", host, lport, host, rport); + return false; + } + + return true; +} + +static inline void main_loop(const char *host, uint16_t lport, uint16_t rport) +{ + LOGP(DUDP_TEST, LOGL_NOTICE, "Entering main loop: %s:%u -> %s:%u\n", host, lport, host, rport); + + while(please_dont_die) + osmo_select_main(0); +} + +/* Smart message trimmer: + * for all positive i trims msg to i - 1 + * for i = 0 trims msg to 0 + * for all positive x adds x to msg +*/ +/*! Smart message trimmer. + * \param[in] msg message buffer + * \param[in] i trim value: for all positive i, msg is trimmed to i - 1, otherwise msg is trimmed to 0 + * \param[in] x message content: for all positive x, x is added to msg, otherwise it's ignored + */ +static inline bool mtrim(struct msgb *msg, uint8_t i, uint8_t x) +{ + if (msgb_trim(msg, i ? i - 1 : i) != 0) { + LOGP(DLINP, LOGL_ERROR, "failed to trim message by %u\n", i); + return false; + } + + if (x) + msgb_put_u8(msg, x); + + return true; +} |