aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2011-10-17 19:49:33 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2011-10-17 22:12:42 +0200
commit20c660caecc95b03489f870945ae9fe91c839bd3 (patch)
tree77a64e776b56212768574aa8e3bd2a48136969eb /examples
parent1434e40951a4eda107e2e81425f99a2d5de23975 (diff)
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.
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile.am12
-rw-r--r--examples/ipa-stream-client.c185
-rw-r--r--examples/ipa-stream-server.c121
3 files changed, 317 insertions, 1 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/application.h>
+
+#include <osmocom/netif/stream.h>
+#include <osmocom/netif/ipa.h>
+
+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; i<num_msgs; i++) {
+ struct msgb *msg;
+ struct msg_sent *msg_sent;
+ char *ptr;
+ int x;
+
+ msg = osmo_ipa_msg_alloc(0);
+ if (msg == NULL) {
+ LOGP(DLINP, LOGL_ERROR, "cannot alloc msg\n");
+ return -1;
+ }
+ ptr = (char *)msgb_put(msg, sizeof(int));
+ x = htonl(i);
+ memcpy(ptr, &x, sizeof(int));
+
+ msg_sent = talloc_zero(NULL, struct msg_sent);
+ if (msg_sent == NULL) {
+ LOGP(DLINP, LOGL_ERROR, "can't alloc struct\n");
+ return -1;
+ }
+ msg_sent->msg = 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <osmocom/core/select.h>
+#include <osmocom/core/talloc.h>
+#include <osmocom/core/msgb.h>
+#include <osmocom/core/logging.h>
+#include <osmocom/core/application.h>
+
+#include <osmocom/netif/stream.h>
+#include <osmocom/netif/ipa.h>
+
+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);
+ }
+}