From 20c660caecc95b03489f870945ae9fe91c839bd3 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 17 Oct 2011 19:49:33 +0200 Subject: ipa: initial addition of helper functions and examples This patch adds IPA helper function that can be use on top of stream sockets. The current API is just a copy and paste from libosmo-abis, it will change in follow up patches to improve it. --- examples/Makefile.am | 12 ++- examples/ipa-stream-client.c | 185 +++++++++++++++++++++++++++++++++++++++++++ examples/ipa-stream-server.c | 121 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 examples/ipa-stream-client.c create mode 100644 examples/ipa-stream-server.c (limited to 'examples') diff --git a/examples/Makefile.am b/examples/Makefile.am index 39e7207..be4ecde 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -2,11 +2,21 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include AM_CFLAGS=-Wall -g $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS) AM_LDFLAGS = $(COVERAGE_LDFLAGS) -noinst_PROGRAMS = lapd-over-datagram-user \ +noinst_PROGRAMS = ipa-stream-client \ + ipa-stream-server \ + lapd-over-datagram-user \ lapd-over-datagram-network \ stream-client \ stream-server +ipa_stream_client_SOURCES = ipa-stream-client.c +ipa_stream_client_LDADD = $(top_builddir)/src/libosmonetif.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + +ipa_stream_server_SOURCES = ipa-stream-server.c +ipa_stream_server_LDADD = $(top_builddir)/src/libosmonetif.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + lapd_over_datagram_user_SOURCES = lapd-over-datagram-user.c lapd_over_datagram_user_LDADD = $(top_builddir)/src/libosmonetif.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) \ diff --git a/examples/ipa-stream-client.c b/examples/ipa-stream-client.c new file mode 100644 index 0000000..2b90f2c --- /dev/null +++ b/examples/ipa-stream-client.c @@ -0,0 +1,185 @@ +/* IPA stream client example. */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +static LLIST_HEAD(msg_sent_list); + +struct msg_sent { + struct llist_head head; + struct msgb *msg; + int num; + struct timeval tv; +}; + +#define DIPATEST 0 + +struct log_info_cat osmo_stream_client_test_cat[] = { + [DIPATEST] = { + .name = "DIPATEST", + .description = "STREAMCLIENT-mode test", + .color = "\033[1;35m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, +}; + +const struct log_info osmo_stream_client_test_log_info = { + .filter_fn = NULL, + .cat = osmo_stream_client_test_cat, + .num_cat = ARRAY_SIZE(osmo_stream_client_test_cat), +}; + +static struct osmo_stream_client_conn *conn; + +void sighandler(int foo) +{ + LOGP(DIPATEST, LOGL_NOTICE, "closing stream.\n"); + exit(EXIT_SUCCESS); +} + +static int connect_cb(struct osmo_stream_client_conn *conn) +{ + int *__num_msgs = osmo_stream_client_conn_get_data(conn); + int num_msgs = *__num_msgs, i; + + LOGP(DIPATEST, LOGL_NOTICE, "connected\n"); + + for (i=0; imsg = msg; + gettimeofday(&msg_sent->tv, NULL); + msg_sent->num = i; + llist_add(&msg_sent->head, &msg_sent_list); + + osmo_ipa_msg_push_header(msg, IPAC_PROTO_OSMO); + + osmo_stream_client_conn_send(conn, msg); + + LOGP(DIPATEST, LOGL_DEBUG, "enqueueing msg %d of " + "%d bytes to be sent\n", i, msg->len); + } + return 0; +} + +static int read_cb(struct osmo_stream_client_conn *conn) +{ + struct msgb *msg; + struct osmo_fd *ofd = osmo_stream_client_conn_get_ofd(conn); + + LOGP(DIPATEST, LOGL_DEBUG, "received message from stream\n"); + + msg = osmo_ipa_msg_alloc(0); + if (msg == NULL) { + LOGP(DIPATEST, LOGL_ERROR, "cannot allocate message\n"); + return 0; + } + if (osmo_ipa_msg_recv(ofd->fd, msg) <= 0) { + LOGP(DIPATEST, LOGL_ERROR, "cannot receive message\n"); + return 0; + } + + int num; + struct msg_sent *cur, *tmp, *found = NULL; + + num = ntohl(*((int *)(msg->data + sizeof(struct ipa_head)))); + LOGP(DLINP, LOGL_DEBUG, "received msg number %d\n", num); + + llist_for_each_entry_safe(cur, tmp, &msg_sent_list, head) { + if (cur->num == num) { + llist_del(&cur->head); + found = cur; + break; + } + } + if (found) { + struct timeval tv, diff; + + gettimeofday(&tv, NULL); + timersub(&tv, &found->tv, &diff); + + LOGP(DLINP, LOGL_NOTICE, "message %d replied " + "in %lu.%.6lu\n", num, diff.tv_sec, diff.tv_usec); + talloc_free(found); + } else { + LOGP(DLINP, LOGL_ERROR, + "message %d not found!\n", num); + } + return 0; +} + +static void *tall_test; + +int main(int argc, char *argv[]) +{ + int num_msgs; + + signal(SIGINT, sighandler); + + if (argc != 2) { + printf("Usage: %s [num_msgs]\n", argv[0]); + exit(EXIT_FAILURE); + } + num_msgs = atoi(argv[1]); + + tall_test = talloc_named_const(NULL, 1, "osmo_stream_client_test"); + + osmo_init_logging(&osmo_stream_client_test_log_info); + log_set_log_level(osmo_stderr_target, LOGL_NOTICE); + + /* + * initialize stream client. + */ + + conn = osmo_stream_client_conn_create(tall_test); + if (conn == NULL) { + fprintf(stderr, "cannot create client\n"); + exit(EXIT_FAILURE); + } + osmo_stream_client_conn_set_addr(conn, "127.0.0.1"); + osmo_stream_client_conn_set_port(conn, 10000); + osmo_stream_client_conn_set_connect_cb(conn, connect_cb); + osmo_stream_client_conn_set_read_cb(conn, read_cb); + osmo_stream_client_conn_set_data(conn, &num_msgs); + + if (osmo_stream_client_conn_open(conn) < 0) { + fprintf(stderr, "cannot open client\n"); + exit(EXIT_FAILURE); + } + + LOGP(DIPATEST, LOGL_NOTICE, "Entering main loop\n"); + + while(1) { + osmo_select_main(0); + } +} diff --git a/examples/ipa-stream-server.c b/examples/ipa-stream-server.c new file mode 100644 index 0000000..5264dab --- /dev/null +++ b/examples/ipa-stream-server.c @@ -0,0 +1,121 @@ +/* IPA stream server example */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +static void *tall_test; + +#define DSTREAMTEST 0 + +struct log_info_cat osmo_stream_server_test_cat[] = { + [DSTREAMTEST] = { + .name = "DSTREAMTEST", + .description = "STREAMSERVER-mode test", + .color = "\033[1;35m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, +}; + +const struct log_info osmo_stream_server_test_log_info = { + .filter_fn = NULL, + .cat = osmo_stream_server_test_cat, + .num_cat = ARRAY_SIZE(osmo_stream_server_test_cat), +}; + +static struct osmo_stream_server_link *server; +static struct osmo_stream_server_conn *conn; + +void sighandler(int foo) +{ + LOGP(DSTREAMTEST, LOGL_NOTICE, "closing STREAMSERVER.\n"); + exit(EXIT_SUCCESS); +} + +int read_cb(struct osmo_stream_server_conn *conn) +{ + struct msgb *msg; + struct osmo_fd *ofd = osmo_stream_server_conn_get_ofd(conn); + + LOGP(DSTREAMTEST, LOGL_DEBUG, "received message from stream\n"); + + msg = osmo_ipa_msg_alloc(0); + if (msg == NULL) { + LOGP(DSTREAMTEST, LOGL_ERROR, "cannot allocate message\n"); + return 0; + } + if (osmo_ipa_msg_recv(ofd->fd, msg) <= 0) { + LOGP(DSTREAMTEST, LOGL_ERROR, "cannot receive message\n"); + osmo_stream_server_conn_destroy(conn); + msgb_free(msg); + return 0; + } + osmo_stream_server_conn_send(conn, msg); + return 0; +} + +static int close_cb(struct osmo_stream_server_conn *dummy) +{ + conn = NULL; + return 0; +} + +static int accept_cb(struct osmo_stream_server_link *server, int fd) +{ + if (conn != NULL) { + LOGP(DSTREAMTEST, LOGL_ERROR, "Sorry, this example only " + "support one client simultaneously\n"); + return -1; + } + + conn = osmo_stream_server_conn_create(tall_test, server, fd, + read_cb, close_cb, NULL); + if (conn == NULL) { + LOGP(DSTREAMTEST, LOGL_ERROR, + "error while creating connection\n"); + return -1; + } + + return 0; +} + +int main(void) +{ + tall_test = talloc_named_const(NULL, 1, "osmo_stream_server_test"); + + osmo_init_logging(&osmo_stream_server_test_log_info); + log_set_log_level(osmo_stderr_target, LOGL_NOTICE); + + /* + * initialize stream server. + */ + + server = osmo_stream_server_link_create(tall_test); + if (server == NULL) { + fprintf(stderr, "cannot create client\n"); + exit(EXIT_FAILURE); + } + osmo_stream_server_link_set_addr(server, "127.0.0.1"); + osmo_stream_server_link_set_port(server, 10000); + osmo_stream_server_link_set_accept_cb(server, accept_cb); + + if (osmo_stream_server_link_open(server) < 0) { + fprintf(stderr, "cannot open client\n"); + exit(EXIT_FAILURE); + } + + LOGP(DSTREAMTEST, LOGL_NOTICE, "Entering main loop\n"); + + while(1) { + osmo_select_main(0); + } +} -- cgit v1.2.3