From 72cd95b3527ee45639f0445817781afc3e732f45 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 24 Jan 2012 14:32:37 +0100 Subject: add RTP support This patch adds the initial RTP support for libosmo-netif, it's based on Harald's RTP support available in openBSC. I have also added a couple of example to show how our new channel infrastructure interacts with the RTP layer. Signed-off-by: Pablo Neira Ayuso --- examples/Makefile.am | 12 +++- examples/rtp-udp-test-client.c | 143 ++++++++++++++++++++++++++++++++++++++++ examples/rtp-udp-test-server.c | 145 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 examples/rtp-udp-test-client.c create mode 100644 examples/rtp-udp-test-server.c (limited to 'examples') diff --git a/examples/Makefile.am b/examples/Makefile.am index 173b620..c9849db 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -9,7 +9,9 @@ noinst_PROGRAMS = ipa-stream-client \ lapd-over-datagram-user \ lapd-over-datagram-network \ stream-client \ - stream-server + stream-server \ + rtp-udp-test-client \ + rtp-udp-test-server ipa_stream_client_SOURCES = ipa-stream-client.c ipa_stream_client_LDADD = $(top_builddir)/src/libosmonetif.la \ @@ -36,3 +38,11 @@ stream_client_LDADD = $(top_builddir)/src/libosmonetif.la \ stream_server_SOURCES = stream-server.c stream_server_LDADD = $(top_builddir)/src/libosmonetif.la \ $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + +rtp_udp_test_client_SOURCES = rtp-udp-test-client.c +rtp_udp_test_client_LDADD = $(top_builddir)/src/libosmonetif.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) + +rtp_udp_test_server_SOURCES = rtp-udp-test-server.c +rtp_udp_test_server_LDADD = $(top_builddir)/src/libosmonetif.la \ + $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) diff --git a/examples/rtp-udp-test-client.c b/examples/rtp-udp-test-client.c new file mode 100644 index 0000000..4989a6c --- /dev/null +++ b/examples/rtp-udp-test-client.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DRTP_TEST 0 + +struct log_info_cat rtp_test_cat[] = { + [DRTP_TEST] = { + .name = "DRTP_TEST", + .description = "RTP client test", + .color = "\033[1;35m", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +const struct log_info rtp_test_log_info = { + .filter_fn = NULL, + .cat = rtp_test_cat, + .num_cat = ARRAY_SIZE(rtp_test_cat), +}; + +static struct osmo_dgram_conn *conn; +static struct osmo_rtp_handle *rtp; + +static int read_cb(struct osmo_dgram_conn *conn) +{ + struct msgb *msg; + int payload_type; + + LOGP(DLINP, LOGL_DEBUG, "received message\n"); + + msg = msgb_alloc(RTP_MSGB_SIZE, "RTP/test"); + if (msg == NULL) { + LOGP(DRTP_TEST, LOGL_ERROR, "cannot allocate message\n"); + return -1; + } + if (osmo_dgram_conn_recv(conn, msg) < 0) { + msgb_free(msg); + LOGP(DRTP_TEST, LOGL_ERROR, "cannot receive message\n"); + return -1; + } + payload_type = osmo_rtp_parse(rtp, msg); + if (payload_type < 0) { + msgb_free(msg); + LOGP(DRTP_TEST, LOGL_ERROR, "cannot parse RTP message\n"); + return -1; + } + + LOGP(DLINP, LOGL_DEBUG, "received message with RTP payload type: %d\n", + payload_type); + + msgb_free(msg); + return 0; +} + +void sighandler(int foo) +{ + LOGP(DLINP, LOGL_NOTICE, "closing RTP.\n"); + osmo_dgram_conn_close(conn); + osmo_dgram_conn_destroy(conn); + osmo_rtp_handle_free(rtp); + exit(EXIT_SUCCESS); +} + +static void *tall_test; + +int main(int argc, char *argv[]) +{ + int i; + char dummy_data[RTP_PT_GSM_FULL_PAYLOAD_LEN] = {}; + + signal(SIGINT, sighandler); + + tall_test = talloc_named_const(NULL, 1, "rtp_test"); + + osmo_init_logging(&rtp_test_log_info); + log_set_log_level(osmo_stderr_target, LOGL_DEBUG); + + /* + * initialize RTP stuff. + */ + rtp = osmo_rtp_handle_create(tall_test); + if (rtp == NULL) { + LOGP(DLINP, LOGL_ERROR, "creating 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 datagram socket. + */ + + conn = osmo_dgram_conn_create(tall_test); + if (conn == NULL) { + fprintf(stderr, "cannot create client\n"); + exit(EXIT_FAILURE); + } + osmo_dgram_conn_set_local_addr(conn, "127.0.0.1"); + osmo_dgram_conn_set_local_port(conn, 20001); + osmo_dgram_conn_set_remote_addr(conn, "127.0.0.1"); + osmo_dgram_conn_set_remote_port(conn, 20000); + osmo_dgram_conn_set_read_cb(conn, read_cb); + + if (osmo_dgram_conn_open(conn) < 0) { + fprintf(stderr, "cannot open client\n"); + exit(EXIT_FAILURE); + } + + for(i=0; i<10; i++) { + struct msgb *msg; + + msg = osmo_rtp_build(rtp, RTP_PT_GSM_FULL, + RTP_PT_GSM_FULL_PAYLOAD_LEN, + dummy_data, RTP_PT_GSM_FULL_DURATION); + if (msg == NULL) { + LOGP(DLINP, LOGL_ERROR, "OOM\n"); + continue; + } + osmo_dgram_conn_send(conn, msg); + } + + LOGP(DLINP, LOGL_NOTICE, "Entering main loop\n"); + + while(1) { + osmo_select_main(0); + } +} diff --git a/examples/rtp-udp-test-server.c b/examples/rtp-udp-test-server.c new file mode 100644 index 0000000..f1920b8 --- /dev/null +++ b/examples/rtp-udp-test-server.c @@ -0,0 +1,145 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define DRTP_TEST 0 + +struct log_info_cat rtp_test_cat[] = { + [DRTP_TEST] = { + .name = "DRTP_TEST", + .description = "RPT-server test", + .color = "\033[1;35m", + .enabled = 1, .loglevel = LOGL_DEBUG, + }, +}; + +const struct log_info rtp_test_log_info = { + .filter_fn = NULL, + .cat = rtp_test_cat, + .num_cat = ARRAY_SIZE(rtp_test_cat), +}; + +static struct osmo_dgram_conn *conn; +static struct osmo_rtp_handle *rtp; + +int read_cb(struct osmo_dgram_conn *conn) +{ + struct msgb *msg; + char dummy_data[RTP_PT_GSM_FULL_PAYLOAD_LEN] = {}; + int payload_type; + + LOGP(DRTP_TEST, LOGL_DEBUG, "received message from datagram\n"); + + msg = msgb_alloc(RTP_MSGB_SIZE, "RTP/test"); + if (msg == NULL) { + LOGP(DRTP_TEST, LOGL_ERROR, "cannot allocate message\n"); + return -1; + } + if (osmo_dgram_conn_recv(conn, msg) < 0) { + LOGP(DRTP_TEST, LOGL_ERROR, "cannot receive message\n"); + return -1; + } + payload_type = osmo_rtp_parse(rtp, msg); + if (payload_type < 0) { + msgb_free(msg); + LOGP(DRTP_TEST, LOGL_ERROR, "cannot parse RTP message\n"); + return -1; + } + LOGP(DLINP, LOGL_DEBUG, "received message with payload type: %d\n", + payload_type); + + /* + * ... now build gsm_data_frame, set callref and msg_type based + * on the rtp payload type (map RTP_PT_GSM_FULL to GSM_THCF_FRAME). + * Then, pass it to the RSL layer. + */ + + msg = msgb_alloc(1200, "RTP/test"); + if (msg == NULL) { + LOGP(DRTP_TEST, LOGL_ERROR, "cannot allocate message\n"); + return -1; + } + + /* build reply. */ + msg = osmo_rtp_build(rtp, RTP_PT_GSM_FULL, + RTP_PT_GSM_FULL_PAYLOAD_LEN, + dummy_data, RTP_PT_GSM_FULL_DURATION); + if (msg == NULL) { + LOGP(DLINP, LOGL_ERROR, "OOM\n"); + return -1; + } + osmo_dgram_conn_send(conn, msg); + + return 0; +} + +void sighandler(int foo) +{ + LOGP(DLINP, LOGL_NOTICE, "closing RTP.\n"); + osmo_dgram_conn_close(conn); + osmo_dgram_conn_destroy(conn); + osmo_rtp_handle_free(rtp); + exit(EXIT_SUCCESS); +} + +static void *tall_test; + +int main(int argc, char *argv[]) +{ + signal(SIGINT, sighandler); + + tall_test = talloc_named_const(NULL, 1, "udp_rtp_test"); + + osmo_init_logging(&rtp_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(DRTP_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 datagram server. + */ + + conn = osmo_dgram_conn_create(tall_test); + if (conn == NULL) { + LOGP(DRTP_TEST, LOGL_ERROR, "cannot create UDP socket\n"); + exit(EXIT_FAILURE); + } + osmo_dgram_conn_set_local_addr(conn, "127.0.0.1"); + osmo_dgram_conn_set_local_port(conn, 20000); + osmo_dgram_conn_set_remote_addr(conn, "127.0.0.1"); + osmo_dgram_conn_set_remote_port(conn, 20001); + osmo_dgram_conn_set_read_cb(conn, read_cb); + + if (osmo_dgram_conn_open(conn) < 0) { + fprintf(stderr, "cannot open client\n"); + exit(EXIT_FAILURE); + } + + LOGP(DRTP_TEST, LOGL_NOTICE, "Entering main loop\n"); + + while(1) { + osmo_select_main(0); + } +} -- cgit v1.2.3