aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2012-10-15 18:16:21 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2012-10-15 23:07:12 +0200
commit4925acf2975f39a7ba3d6451f77eceae4b7fb203 (patch)
tree9f3203918e3b1e070e1d86bb93429ec9e6fd39b9 /examples
parent384bdf630a59f5611447675dfec962d15bc1eeaa (diff)
examples: add osmux-test-input and osmux-test-output
You can use these utilities to test osmux: 1) in one console, run ./osmux-test-input This listens in port UDP 20000 and convert RTP traffic to osmux Then, it sends osmux traffic via port UDP 20001 2) in another console, run ./osmux-test-output This listens in port UDP 20001 and convert osmux to RTP traffic Then, it sends RTP traffic to UDP port 20002 3) in another console run, nc -u nc -u -l -p 20002 This is the sink, just to avoid ICMP destination unreachable messages Now you can run replay UDP traffic from one pcap trace that contains RTP traffic with this tool: http://1984.lsi.us.es/git/pcap-inject/ Example of command line invocation: ./traffic-inject /home/pablo/rtp-nanobts-2-phones-amr.pcap udp 20000 You can run wireshark in the loopback to make sure osmux is getting back the traces looking like the original. The tests also generate output files in AMR that you can validate via mplayer: /tmp/output.amr and /tmp/input.amr respectively. This is to make sure there are no reordering or problems of any sort.
Diffstat (limited to 'examples')
-rw-r--r--examples/Makefile.am12
-rw-r--r--examples/osmux-test-input.c199
-rw-r--r--examples/osmux-test-output.c185
3 files changed, 395 insertions, 1 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 1063245..e7742cd 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -13,7 +13,9 @@ noinst_PROGRAMS = ipa-stream-client \
rs232-read \
rs232-write \
rtp-udp-test-client \
- rtp-udp-test-server
+ rtp-udp-test-server \
+ osmux-test-input \
+ osmux-test-output
ipa_stream_client_SOURCES = ipa-stream-client.c
ipa_stream_client_LDADD = $(top_builddir)/src/libosmonetif.la \
@@ -54,3 +56,11 @@ rtp_udp_test_client_LDADD = $(top_builddir)/src/libosmonetif.la \
rtp_udp_test_server_SOURCES = rtp-udp-test-server.c
rtp_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)
+
+osmux_test_output_SOURCES = osmux-test-output.c
+osmux_test_output_LDADD = $(top_builddir)/src/libosmonetif.la \
+ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS)
diff --git a/examples/osmux-test-input.c b/examples/osmux-test-input.c
new file mode 100644
index 0000000..3203b4d
--- /dev/null
+++ b/examples/osmux-test-input.c
@@ -0,0 +1,199 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.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/rtp.h>
+#include <osmocom/netif/osmux.h>
+#include <osmocom/netif/datagram.h>
+
+#define DOSMUX_TEST 0
+
+struct log_info_cat osmux_test_cat[] = {
+ [DOSMUX_TEST] = {
+ .name = "DOSMUX_TEST",
+ .description = "osmux test input",
+ .color = "\033[1;35m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+};
+
+const struct log_info osmux_test_log_info = {
+ .filter_fn = NULL,
+ .cat = osmux_test_cat,
+ .num_cat = ARRAY_SIZE(osmux_test_cat),
+};
+
+static int fd;
+
+static void amr_open(void)
+{
+ fd = open("/tmp/input.amr", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd < 0) {
+ perror("open");
+ exit(EXIT_FAILURE);
+ }
+ write(fd, "#!AMR\n", strlen("#!AMR\n"));
+}
+
+static void amr_close(void)
+{
+ close(fd);
+}
+
+static void amr_write(struct msgb *msg)
+{
+ struct rtp_hdr *rtph;
+ void *amr;
+ unsigned int len;
+
+ /* as described by rfc4867, see page 35 */
+ rtph = osmo_rtp_get_hdr(msg);
+ amr = osmo_rtp_get_payload(rtph, msg, &len);
+
+ write(fd, (uint8_t *)amr + 1, len - 1);
+}
+
+static struct osmo_dgram *conn;
+static struct osmo_rtp_handle *rtp;
+
+static void osmux_deliver(struct msgb *batch_msg)
+{
+ printf("sending batch (len=%d)\n", batch_msg->len);
+ osmo_dgram_send(conn, batch_msg);
+}
+
+/*
+ * This is the input handle for osmux. It stores the last osmux sequence that
+ * has been used and the deliver function that sends the osmux batch.
+ */
+struct osmux_in_handle h_input = {
+ .osmux_seq = 0, /* sequence number to start OSmux message from */
+ .batch_factor = 4, /* batch up to 4 RTP messages */
+ .deliver = osmux_deliver,
+};
+
+int read_cb(struct osmo_dgram *conn)
+{
+ struct msgb *msg;
+ struct rtp_hdr *rtph;
+ int ret;
+
+ LOGP(DOSMUX_TEST, LOGL_DEBUG, "received message from datagram\n");
+
+ msg = msgb_alloc(RTP_MSGB_SIZE, "OSMUX/test");
+ if (msg == NULL) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "cannot allocate message\n");
+ return -1;
+ }
+ if (osmo_dgram_recv(conn, msg) < 0) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "cannot receive message\n");
+ return -1;
+ }
+ rtph = osmo_rtp_get_hdr(msg);
+ if (rtph == NULL) {
+ msgb_free(msg);
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "cannot parse RTP message\n");
+ return -1;
+ }
+ LOGP(DLINP, LOGL_DEBUG, "received message with RTP payload type: %d\n",
+ rtph->payload_type);
+
+ if (rtph->payload_type == RTP_PT_AMR)
+ amr_write(msg);
+
+ /* now build the osmux frame */
+ if (osmux_xfrm_input_get_ccid(&h_input, rtph->ssrc) < 0)
+ osmux_xfrm_input_register_ccid(&h_input, rtph->ssrc);
+
+ while ((ret = osmux_xfrm_input(&h_input, msg)) > 0) {
+ /* batch full, deliver it */
+ osmux_xfrm_input_deliver(&h_input);
+ }
+ if (ret == -1)
+ printf("something is wrong\n");
+
+ return 0;
+}
+
+void sighandler(int foo)
+{
+ LOGP(DLINP, LOGL_NOTICE, "closing test.\n");
+ osmo_dgram_close(conn);
+ osmo_dgram_destroy(conn);
+ osmo_rtp_handle_free(rtp);
+ amr_close();
+ exit(EXIT_SUCCESS);
+}
+
+static void *tall_test;
+
+/*
+ * This is the output handle for osmux, it stores last RTP sequence and
+ * timestamp that has been used. There should be one per circuit ID.
+ */
+int main(int argc, char *argv[])
+{
+ amr_open();
+
+ signal(SIGINT, sighandler);
+
+ tall_test = talloc_named_const(NULL, 1, "osmux_test");
+
+ osmo_init_logging(&osmux_test_log_info);
+ log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
+
+ /*
+ * initialize RTP handler.
+ */
+ rtp = osmo_rtp_handle_create(tall_test);
+ if (rtp == NULL) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "Error init RTP handler\n");
+ exit(EXIT_FAILURE);
+ }
+ osmo_rtp_handle_tx_set_sequence(rtp, random());
+ osmo_rtp_handle_tx_set_ssrc(rtp, random());
+ osmo_rtp_handle_tx_set_timestamp(rtp, time(NULL));
+
+ /*
+ * initialize OSMUX handlers.
+ */
+ osmux_xfrm_input_init(&h_input);
+
+ /*
+ * initialize datagram server.
+ */
+
+ conn = osmo_dgram_create(tall_test);
+ if (conn == NULL) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "cannot create UDP socket\n");
+ exit(EXIT_FAILURE);
+ }
+ osmo_dgram_set_local_addr(conn, "127.0.0.1");
+ osmo_dgram_set_local_port(conn, 20000);
+ osmo_dgram_set_remote_addr(conn, "127.0.0.1");
+ osmo_dgram_set_remote_port(conn, 20001);
+ osmo_dgram_set_read_cb(conn, read_cb);
+
+ if (osmo_dgram_open(conn) < 0) {
+ fprintf(stderr, "cannot open client\n");
+ exit(EXIT_FAILURE);
+ }
+
+ LOGP(DOSMUX_TEST, LOGL_NOTICE, "Entering main loop\n");
+
+ while(1) {
+ osmo_select_main(0);
+ }
+}
diff --git a/examples/osmux-test-output.c b/examples/osmux-test-output.c
new file mode 100644
index 0000000..f797f49
--- /dev/null
+++ b/examples/osmux-test-output.c
@@ -0,0 +1,185 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.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/rtp.h>
+#include <osmocom/netif/osmux.h>
+#include <osmocom/netif/datagram.h>
+
+#define DOSMUX_TEST 0
+
+struct log_info_cat osmux_test_cat[] = {
+ [DOSMUX_TEST] = {
+ .name = "DOSMUX_TEST",
+ .description = "osmux test output",
+ .color = "\033[1;35m",
+ .enabled = 1, .loglevel = LOGL_DEBUG,
+ },
+};
+
+const struct log_info osmux_test_log_info = {
+ .filter_fn = NULL,
+ .cat = osmux_test_cat,
+ .num_cat = ARRAY_SIZE(osmux_test_cat),
+};
+
+static struct osmo_dgram *conn;
+static struct osmo_rtp_handle *rtp;
+
+/*
+ * This is the output handle for osmux, it stores last RTP sequence and
+ * timestamp that has been used. There should be one per circuit ID.
+ */
+static struct osmux_out_handle h_output;
+
+static int fd;
+
+static void amr_open(void)
+{
+ fd = open("/tmp/output.amr", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ if (fd < 0) {
+ perror("open");
+ exit(1);
+ }
+ write(fd, "#!AMR\n", strlen("#!AMR\n"));
+}
+
+static void amr_close(void)
+{
+ close(fd);
+}
+
+static void amr_write(struct msgb *msg)
+{
+ struct rtp_hdr *rtph;
+ void *amr;
+ unsigned int len;
+
+ rtph = osmo_rtp_get_hdr(msg);
+ amr = osmo_rtp_get_payload(rtph, msg, &len);
+
+ write(fd, (uint8_t *)amr + 1, len - 1);
+}
+
+static void tx_cb(struct msgb *msg, void *data)
+{
+ char buf[4096];
+
+ osmo_rtp_snprintf(buf, sizeof(buf), msg);
+ printf("sending: %s\n", buf);
+ osmo_dgram_send(conn, msg);
+
+ amr_write(msg);
+}
+
+int read_cb(struct osmo_dgram *conn)
+{
+ struct msgb *msg;
+ struct osmux_hdr *osmuxh;
+ struct llist_head list;
+
+ LOGP(DOSMUX_TEST, LOGL_DEBUG, "received message from datagram\n");
+
+ msg = msgb_alloc(RTP_MSGB_SIZE, "OSMUX/test");
+ if (msg == NULL) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "cannot allocate message\n");
+ return -1;
+ }
+ if (osmo_dgram_recv(conn, msg) < 0) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "cannot receive message\n");
+ return -1;
+ }
+
+ LOGP(DLINP, LOGL_DEBUG, "received OSMUX message (len=%d)\n", msg->len);
+
+ while((osmuxh = osmux_xfrm_output_pull(msg)) != NULL) {
+ printf("tx_sched\n");
+ osmux_xfrm_output(osmuxh, &h_output, &list);
+ osmux_tx_sched(&list, tx_cb, NULL);
+ }
+
+ return 0;
+}
+
+void sighandler(int foo)
+{
+ LOGP(DLINP, LOGL_NOTICE, "closing OSMUX.\n");
+ osmo_dgram_close(conn);
+ osmo_dgram_destroy(conn);
+ osmo_rtp_handle_free(rtp);
+ amr_close();
+ exit(EXIT_SUCCESS);
+}
+
+static void *tall_test;
+
+/*
+ * This is the output handle for osmux, it stores last RTP sequence and
+ * timestamp that has been used. There should be one per circuit ID.
+ */
+int main(int argc, char *argv[])
+{
+ amr_open();
+
+ signal(SIGINT, sighandler);
+
+ tall_test = talloc_named_const(NULL, 1, "osmux_test");
+
+ osmo_init_logging(&osmux_test_log_info);
+ log_set_log_level(osmo_stderr_target, LOGL_DEBUG);
+
+ /*
+ * initialize RTP handler.
+ */
+ rtp = osmo_rtp_handle_create(tall_test);
+ if (rtp == NULL) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "Error init OSMUX handler\n");
+ exit(EXIT_FAILURE);
+ }
+ osmo_rtp_handle_tx_set_sequence(rtp, random());
+ osmo_rtp_handle_tx_set_ssrc(rtp, random());
+ osmo_rtp_handle_tx_set_timestamp(rtp, time(NULL));
+
+ /*
+ * initialize OSMUX handlers.
+ */
+ osmux_xfrm_output_init(&h_output);
+
+ /*
+ * initialize datagram server.
+ */
+
+ conn = osmo_dgram_create(tall_test);
+ if (conn == NULL) {
+ LOGP(DOSMUX_TEST, LOGL_ERROR, "cannot create UDP socket\n");
+ exit(EXIT_FAILURE);
+ }
+ osmo_dgram_set_local_addr(conn, "127.0.0.1");
+ osmo_dgram_set_local_port(conn, 20001);
+ osmo_dgram_set_remote_addr(conn, "127.0.0.1");
+ osmo_dgram_set_remote_port(conn, 20002);
+ osmo_dgram_set_read_cb(conn, read_cb);
+
+ if (osmo_dgram_open(conn) < 0) {
+ fprintf(stderr, "cannot open client\n");
+ exit(EXIT_FAILURE);
+ }
+
+ LOGP(DOSMUX_TEST, LOGL_NOTICE, "Entering main loop\n");
+
+ while(1) {
+ osmo_select_main(0);
+ }
+}