From 828e03715f67f358671c6691c3e9c0f2a66ec6ec Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 3 Apr 2006 21:00:13 +0000 Subject: [PATCH] try out new builtin RTP using srtp lib git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1012 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- Makefile.am | 12 +- Makefile.in | 42 +- configure | 4 +- configure.in | 2 +- src/include/switch.h | 4 +- .../{config.h.in => switch_am_config.h.in} | 5 +- src/include/switch_platform.h | 6 + src/include/switch_rtp.h | 88 ++++ src/include/switch_types.h | 14 + .../applications/mod_playback/mod_playback.c | 2 + src/mod/endpoints/mod_dingaling/Makefile | 2 +- .../endpoints/mod_dingaling/mod_dingaling.c | 53 +-- src/mod/endpoints/mod_exosip/Makefile | 2 +- src/mod/endpoints/mod_exosip/mod_exosip.c | 46 +-- src/switch_rtp.c | 379 ++++++++++++++++++ 15 files changed, 589 insertions(+), 72 deletions(-) rename src/include/{config.h.in => switch_am_config.h.in} (95%) create mode 100644 src/include/switch_rtp.h create mode 100644 src/switch_rtp.c diff --git a/Makefile.am b/Makefile.am index 61460482ca..ef8cea3836 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,12 +7,12 @@ NAME=freeswitch PREFIX=$(prefix) APR_CONFIG=$(prefix)/bin/apr-1-config APU_CONFIG=$(prefix)/bin/apu-1-config -AM_CFLAGS = -I$(PREFIX)/include $(shell $(APR_CONFIG) --cflags --cppflags --includes) +AM_CFLAGS = -I$(PREFIX)/include $(shell $(APR_CONFIG) --cflags --cppflags --includes) -I${prefix}/include/srtp AM_LDFLAGS = -L$(PREFIX)/lib AM_LDFLAGS += $(shell $(APR_CONFIG) --link-ld --libs ) AM_CFLAGS += $(shell $(APU_CONFIG) --includes) AM_LDFLAGS += $(shell $(APU_CONFIG) --link-ld --libs ) -AM_LDFLAGS += -lm -L/usr/local/lib/db42 -L/usr/local/lib +AM_LDFLAGS += -lm -L/usr/local/lib/db42 -L/usr/local/lib -lsrtp OSARCH=$(shell uname -s) if ISLINUX AM_LDFLAGS += -Wl,-E @@ -43,7 +43,7 @@ AM_CFLAGS += -DSWITCH_SCRIPT_DIR=\"$(PREFIX)/scripts\" libfreeswitch_la_SOURCES = \ -src/include/config.h\ +src/include/switch_am_config.h\ src/include/switch.h\ src/include/switch_apr.h\ src/include/switch_buffer.h\ @@ -63,6 +63,8 @@ src/include/switch_sqlite.h\ src/include/switch_types.h\ src/include/switch_utils.h\ src/include/switch_version.h\ +src/inclide/switch_rtp.h\ +src/switch_rtp.c\ src/switch_buffer.c \ src/switch_caller.c \ src/switch_channel.c \ @@ -81,7 +83,7 @@ src/switch_ivr.c #libdir = $(PREFIX)/lib library_includedir = $(PREFIX)/include library_include_HEADERS = \ -src/include/config.h\ +src/include/switch_am_config.h\ src/include/switch.h\ src/include/switch_apr.h\ src/include/switch_buffer.h\ @@ -100,6 +102,7 @@ src/include/switch_resample.h\ src/include/switch_sqlite.h\ src/include/switch_types.h\ src/include/switch_utils.h\ +src/include/switch_rtp.h\ src/include/switch_version.h BUILT_SOURCES = version depends @@ -146,6 +149,7 @@ depends: ./build/buildlib.sh . install apr-util-1.2.6.tar.gz --with-apr=../apr-1.2.6 --prefix=$(PREFIX) ./build/buildlib.sh . libresample-0.1.3.tgz --prefix=$(PREFIX) ./build/buildlib.sh . install libteletone --prefix=$(PREFIX) + ./build/buildlib.sh . install srtp.tgz --prefix=$(PREFIX) rm build/freeswitch.env diff --git a/Makefile.in b/Makefile.in index c8921d7ebf..c8c79d925e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -44,7 +44,8 @@ host_triplet = @host@ bin_PROGRAMS = freeswitch$(EXEEXT) DIST_COMMON = README $(am__configure_deps) $(library_include_HEADERS) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(top_srcdir)/configure $(top_srcdir)/src/include/config.h.in \ + $(top_srcdir)/configure \ + $(top_srcdir)/src/include/switch_am_config.h.in \ $(top_srcdir)/src/include/switch_version.h.in AUTHORS COPYING \ ChangeLog INSTALL NEWS build/config/compile \ build/config/config.guess build/config/config.sub \ @@ -58,7 +59,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno configure.status.lineno mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/src/include/config.h +CONFIG_HEADER = $(top_builddir)/src/include/switch_am_config.h CONFIG_CLEAN_FILES = src/include/switch_version.h am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -71,7 +72,8 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libfreeswitch_la_DEPENDENCIES = -am_libfreeswitch_la_OBJECTS = libfreeswitch_la-switch_buffer.lo \ +am_libfreeswitch_la_OBJECTS = libfreeswitch_la-switch_rtp.lo \ + libfreeswitch_la-switch_buffer.lo \ libfreeswitch_la-switch_caller.lo \ libfreeswitch_la-switch_channel.lo \ libfreeswitch_la-switch_config.lo \ @@ -238,9 +240,9 @@ PREFIX = $(prefix) APR_CONFIG = $(prefix)/bin/apr-1-config APU_CONFIG = $(prefix)/bin/apu-1-config AM_CFLAGS = -I$(PREFIX)/include $(shell $(APR_CONFIG) --cflags \ - --cppflags --includes) $(shell $(APU_CONFIG) --includes) \ - $(am__append_2) $(am__append_3) -fPIC -Wall \ - -I$(PWD)/src/sqlite -I$(PWD) -I$(PWD)/src/include \ + --cppflags --includes) -I${prefix}/include/srtp $(shell \ + $(APU_CONFIG) --includes) $(am__append_2) $(am__append_3) \ + -fPIC -Wall -I$(PWD)/src/sqlite -I$(PWD) -I$(PWD)/src/include \ -I$(PREFIX)/include -DSWITCH_MOD_DIR=\"$(PREFIX)/mod\" \ -DSWITCH_PREFIX_DIR=\"$(PREFIX)\" \ -DSWITCH_CONF_DIR=\"$(PREFIX)/conf\" \ @@ -249,7 +251,7 @@ AM_CFLAGS = -I$(PREFIX)/include $(shell $(APR_CONFIG) --cflags \ -DSWITCH_SCRIPT_DIR=\"$(PREFIX)/scripts\" AM_LDFLAGS = -L$(PREFIX)/lib $(shell $(APR_CONFIG) --link-ld --libs ) \ $(shell $(APU_CONFIG) --link-ld --libs ) -lm \ - -L/usr/local/lib/db42 -L/usr/local/lib $(am__append_1) + -L/usr/local/lib/db42 -L/usr/local/lib -lsrtp $(am__append_1) OSARCH = $(shell uname -s) @ISMAC_FALSE@SOLINK = -shared -Xlinker -x @@ -258,7 +260,7 @@ OSARCH = $(shell uname -s) @ISMAC_FALSE@DYNAMIC_LIB_EXTEN = so @ISMAC_TRUE@DYNAMIC_LIB_EXTEN = dylib libfreeswitch_la_SOURCES = \ -src/include/config.h\ +src/include/switch_am_config.h\ src/include/switch.h\ src/include/switch_apr.h\ src/include/switch_buffer.h\ @@ -278,6 +280,8 @@ src/include/switch_sqlite.h\ src/include/switch_types.h\ src/include/switch_utils.h\ src/include/switch_version.h\ +src/inclide/switch_rtp.h\ +src/switch_rtp.c\ src/switch_buffer.c \ src/switch_caller.c \ src/switch_channel.c \ @@ -295,7 +299,7 @@ src/switch_ivr.c #libdir = $(PREFIX)/lib library_includedir = $(PREFIX)/include library_include_HEADERS = \ -src/include/config.h\ +src/include/switch_am_config.h\ src/include/switch.h\ src/include/switch_apr.h\ src/include/switch_buffer.h\ @@ -314,6 +318,7 @@ src/include/switch_resample.h\ src/include/switch_sqlite.h\ src/include/switch_types.h\ src/include/switch_utils.h\ +src/include/switch_rtp.h\ src/include/switch_version.h BUILT_SOURCES = version depends @@ -367,22 +372,22 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) -src/include/config.h: src/include/stamp-h1 +src/include/switch_am_config.h: src/include/stamp-h1 @if test ! -f $@; then \ rm -f src/include/stamp-h1; \ $(MAKE) src/include/stamp-h1; \ else :; fi -src/include/stamp-h1: $(top_srcdir)/src/include/config.h.in $(top_builddir)/config.status +src/include/stamp-h1: $(top_srcdir)/src/include/switch_am_config.h.in $(top_builddir)/config.status @rm -f src/include/stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status src/include/config.h -$(top_srcdir)/src/include/config.h.in: $(am__configure_deps) + cd $(top_builddir) && $(SHELL) ./config.status src/include/switch_am_config.h +$(top_srcdir)/src/include/switch_am_config.h.in: $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f src/include/stamp-h1 touch $@ distclean-hdr: - -rm -f src/include/config.h src/include/stamp-h1 + -rm -f src/include/switch_am_config.h src/include/stamp-h1 src/include/switch_version.h: $(top_builddir)/config.status $(top_srcdir)/src/include/switch_version.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) @@ -463,6 +468,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_ivr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_loadable_module.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_resample.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_rtp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfreeswitch_la-switch_utils.Plo@am__quote@ .c.o: @@ -486,6 +492,13 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +libfreeswitch_la-switch_rtp.lo: src/switch_rtp.c +@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfreeswitch_la_CFLAGS) $(CFLAGS) -MT libfreeswitch_la-switch_rtp.lo -MD -MP -MF "$(DEPDIR)/libfreeswitch_la-switch_rtp.Tpo" -c -o libfreeswitch_la-switch_rtp.lo `test -f 'src/switch_rtp.c' || echo '$(srcdir)/'`src/switch_rtp.c; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libfreeswitch_la-switch_rtp.Tpo" "$(DEPDIR)/libfreeswitch_la-switch_rtp.Plo"; else rm -f "$(DEPDIR)/libfreeswitch_la-switch_rtp.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/switch_rtp.c' object='libfreeswitch_la-switch_rtp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfreeswitch_la_CFLAGS) $(CFLAGS) -c -o libfreeswitch_la-switch_rtp.lo `test -f 'src/switch_rtp.c' || echo '$(srcdir)/'`src/switch_rtp.c + libfreeswitch_la-switch_buffer.lo: src/switch_buffer.c @am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfreeswitch_la_CFLAGS) $(CFLAGS) -MT libfreeswitch_la-switch_buffer.lo -MD -MP -MF "$(DEPDIR)/libfreeswitch_la-switch_buffer.Tpo" -c -o libfreeswitch_la-switch_buffer.lo `test -f 'src/switch_buffer.c' || echo '$(srcdir)/'`src/switch_buffer.c; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libfreeswitch_la-switch_buffer.Tpo" "$(DEPDIR)/libfreeswitch_la-switch_buffer.Plo"; else rm -f "$(DEPDIR)/libfreeswitch_la-switch_buffer.Tpo"; exit 1; fi @@ -1019,6 +1032,7 @@ depends: ./build/buildlib.sh . install apr-util-1.2.6.tar.gz --with-apr=../apr-1.2.6 --prefix=$(PREFIX) ./build/buildlib.sh . libresample-0.1.3.tgz --prefix=$(PREFIX) ./build/buildlib.sh . install libteletone --prefix=$(PREFIX) + ./build/buildlib.sh . install srtp.tgz --prefix=$(PREFIX) rm build/freeswitch.env modules: $(NAME) diff --git a/configure b/configure index e5511d8176..bf9493dc54 100755 --- a/configure +++ b/configure @@ -1948,7 +1948,7 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - ac_config_headers="$ac_config_headers src/include/config.h" + ac_config_headers="$ac_config_headers src/include/switch_am_config.h" @@ -22268,7 +22268,7 @@ do "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "src/include/switch_version.h" ) CONFIG_FILES="$CONFIG_FILES src/include/switch_version.h" ;; "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - "src/include/config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/include/config.h" ;; + "src/include/switch_am_config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/include/switch_am_config.h" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; diff --git a/configure.in b/configure.in index 6126a612c4..5ded1202e8 100644 --- a/configure.in +++ b/configure.in @@ -6,7 +6,7 @@ AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS) AC_CONFIG_AUX_DIR(build/config) AM_INIT_AUTOMAKE(libfreeswitch,0.1) AC_CONFIG_SRCDIR([src/switch.c]) -AC_CONFIG_HEADER([src/include/config.h]) +AC_CONFIG_HEADER([src/include/switch_am_config.h]) AC_PREFIX_DEFAULT(/usr/local/freeswitch) diff --git a/src/include/switch.h b/src/include/switch.h index f8551332a9..1d6a32db84 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -43,7 +43,7 @@ extern "C" { #include #ifndef WIN32 -#include +#include #endif #include @@ -65,6 +65,8 @@ extern "C" { #include #include #include +#include +#include #ifdef __cplusplus } #endif diff --git a/src/include/config.h.in b/src/include/switch_am_config.h.in similarity index 95% rename from src/include/config.h.in rename to src/include/switch_am_config.h.in index ef699dda75..f085b4ebf5 100644 --- a/src/include/config.h.in +++ b/src/include/switch_am_config.h.in @@ -1,4 +1,6 @@ -/* src/include/config.h.in. Generated from configure.in by autoheader. */ +#ifndef SWITCH_AM_CONFIG_H +#define SWITCH_AM_CONFIG_H +/* src/include/switch_am_config.h.in. Generated from configure.in by autoheader. */ /* Define to 1 if you have the header file, and it defines `DIR'. */ @@ -114,3 +116,4 @@ /* Define to `unsigned' if does not define. */ #undef size_t +#endif diff --git a/src/include/switch_platform.h b/src/include/switch_platform.h index f093cfc68e..1d3b56c8a3 100644 --- a/src/include/switch_platform.h +++ b/src/include/switch_platform.h @@ -38,6 +38,12 @@ extern "C" { #endif +#ifdef WIN32 +typedef SOCKET switch_raw_socket_t; +#else +typedef int switch_raw_socket_t; +#endif + #ifdef __ICC #pragma warning (disable:810 869 981 279 1469 188) #endif diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h new file mode 100644 index 0000000000..d4c855788f --- /dev/null +++ b/src/include/switch_rtp.h @@ -0,0 +1,88 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * + * switch_channel.h -- Media Channel Interface + * + */ +/** + * @file switch_rtp.h + * @brief RTP + * + */ + +#ifndef SWITCH_RTP_H +#define SWITCH_RTP_H + +#ifdef __cplusplus +extern "C" { +#ifdef _FORMATBUG +} +#endif +#endif + + + + +typedef void (*switch_rtp_invalid_handler)(switch_rtp *rtp_session, + switch_raw_socket_t sock, + void *data, + unsigned int datalen, + uint32_t fromip, + uint16_t fromport); + +switch_rtp *switch_rtp_new(char *rx_ip, + int rx_port, + char *tx_ip, + int tx_port, + int payload, + switch_rtp_flag_t flags, + const char **err, + switch_memory_pool *pool); + +void switch_rtp_destroy(switch_rtp **rtp_session); +switch_raw_socket_t switch_rtp_get_rtp_socket(switch_rtp *rtp_session); +void switch_rtp_set_invald_handler(switch_rtp *rtp_session, switch_rtp_invalid_handler on_invalid); +int switch_rtp_read(switch_rtp *rtp_session, void *data, uint32_t datalen, int *payload_type); +int switch_rtp_zerocopy_read(switch_rtp *rtp_session, void **data, int *payload_type); +int switch_rtp_write(switch_rtp *rtp_session, void *data, int datalen, uint32_t ts); +int switch_rtp_write_payload(switch_rtp *rtp_session, void *data, int datalen, int payload, uint32_t ts, uint32_t mseq); +uint32_t switch_rtp_start(switch_rtp *rtp_session); +uint32_t switch_rtp_get_ssrc(switch_rtp *rtp_session); +void switch_rtp_killread(switch_rtp *rtp_session); +void switch_rtp_set_private(switch_rtp *rtp_session, void *private_data); +void *switch_rtp_get_private(switch_rtp *rtp_session); + + + +#include + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/include/switch_types.h b/src/include/switch_types.h index c6de5e0b7e..aa4c031274 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -94,6 +94,18 @@ SWITCH_DECLARE_DATA extern switch_directories SWITCH_GLOBAL_dirs; #define SWITCH_TRUE 1 #define SWITCH_FALSE 0 +/*! + \enum switch_rtp_flag_t + \brief RTP Related Flags +
+    SWITCH_RTP_NOBLOCK      - Do not block
+    SWITCH_RTP_FLAG_IO      - IO is ready
+
+ */ +typedef enum { + SWITCH_RTP_NOBLOCK = ( 1 << 0), + SWITCH_RTP_FLAG_IO = (1 << 1) +} switch_rtp_flag_t; /*! \enum switch_priority_t @@ -429,6 +441,8 @@ typedef enum { SWITCH_EVENT_ALL } switch_event_t; + +typedef struct switch_rtp switch_rtp; typedef struct switch_core_session_message switch_core_session_message; typedef struct switch_audio_resampler switch_audio_resampler; typedef struct switch_event_header switch_event_header; diff --git a/src/mod/applications/mod_playback/mod_playback.c b/src/mod/applications/mod_playback/mod_playback.c index 10089ba43e..9546d5063a 100644 --- a/src/mod/applications/mod_playback/mod_playback.c +++ b/src/mod/applications/mod_playback/mod_playback.c @@ -64,6 +64,8 @@ static void playback_function(switch_core_session *session, char *data) channel = switch_core_session_get_channel(session); assert(channel != NULL); + switch_channel_answer(channel); + if (switch_ivr_play_file(session, NULL, file_name, timer_name, on_dtmf, NULL, 0) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel); } diff --git a/src/mod/endpoints/mod_dingaling/Makefile b/src/mod/endpoints/mod_dingaling/Makefile index 492dc765af..7f053c0d6e 100644 --- a/src/mod/endpoints/mod_dingaling/Makefile +++ b/src/mod/endpoints/mod_dingaling/Makefile @@ -3,7 +3,7 @@ LDFLAGS += -ldingaling -ljrtp all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN) depends: - MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install jrtplib --prefix=$(PREFIX) --disable-gst + #MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install jrtplib --prefix=$(PREFIX) --disable-gst MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install iksemel-1.2.tar.gz --prefix=$(PREFIX) MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install libdingaling --prefix=$(PREFIX) diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index cccff92b0d..d0a4370041 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -32,7 +32,6 @@ #include #include #include -#include #ifdef _MSC_VER #include #else @@ -113,7 +112,7 @@ struct private_object { switch_codec_interface *codecs[SWITCH_MAX_CODECS]; unsigned int num_codecs; int codec_index; - struct jrtp4c *rtp_session; + struct switch_rtp *rtp_session; ldl_session_t *dlsession; char *remote_ip; uint16_t remote_port; @@ -121,7 +120,7 @@ struct private_object { char *remote_user; unsigned int cand_id; unsigned int desc_id; - jrtp_socket_t rtp_sock; + switch_raw_socket_t rtp_sock; char last_digit; unsigned int dc; time_t last_digit_time; @@ -177,7 +176,7 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr static switch_status channel_kill_channel(switch_core_session *session, int sig); static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *msg); static ldl_status handle_response(ldl_handle_t *handle, char *id); -static void stun_callback(struct jrtp4c *jrtp4c, jrtp_socket_t sock, void *data, unsigned int len, uint32_t ip, uint16_t port); +static void stun_callback(struct switch_rtp *switch_rtp, switch_raw_socket_t sock, void *data, unsigned int len, uint32_t ip, uint16_t port); static switch_status load_config(void); @@ -361,6 +360,7 @@ static void *SWITCH_THREAD_FUNC negotiate_thread_run(switch_thread *thread, void switch_core_session_set_read_codec(session, &tech_pvt->read_codec); switch_core_session_set_write_codec(session, &tech_pvt->write_codec); + //switch_set_flag(tech_pvt, TFLAG_SILENCE); //printf("WAIT %s %d\n", switch_channel_get_name(channel), switch_test_flag(tech_pvt, TFLAG_OUTBOUND)); @@ -465,7 +465,7 @@ static switch_status channel_on_hangup(switch_core_session *session) } if (tech_pvt->rtp_session) { - jrtp4c_destroy(&tech_pvt->rtp_session); + switch_rtp_destroy(&tech_pvt->rtp_session); switch_console_printf(SWITCH_CHANNEL_CONSOLE, "NUKE RTP\n"); tech_pvt->rtp_session = NULL; } @@ -498,7 +498,7 @@ static switch_status channel_kill_channel(switch_core_session *session, int sig) ldl_session_terminate(tech_pvt->dlsession); } if (tech_pvt->rtp_session) { - jrtp4c_killread(tech_pvt->rtp_session); + switch_rtp_killread(tech_pvt->rtp_session); } switch_console_printf(SWITCH_CHANNEL_CONSOLE, "%s CHANNEL KILL\n", switch_channel_get_name(channel)); } @@ -582,7 +582,7 @@ static switch_status channel_read_frame(switch_core_session *session, switch_fra while (!switch_test_flag(tech_pvt, TFLAG_BYE) && switch_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) { payload = -1; - tech_pvt->read_frame.datalen = jrtp4c_read(tech_pvt->rtp_session, tech_pvt->read_frame.data, sizeof(tech_pvt->read_buf), &payload); + tech_pvt->read_frame.datalen = switch_rtp_read(tech_pvt->rtp_session, tech_pvt->read_frame.data, sizeof(tech_pvt->read_buf), &payload); if (switch_test_flag(tech_pvt, TFLAG_SILENCE)) { if (tech_pvt->read_frame.datalen) { switch_clear_flag(tech_pvt, TFLAG_SILENCE); @@ -631,9 +631,9 @@ static switch_status channel_read_frame(switch_core_session *session, switch_fra } - if (switch_test_flag(tech_pvt->profile, PFLAG_GENSILENCE)) { if ((switch_test_flag(tech_pvt, TFLAG_SILENCE) || payload == 13) && tech_pvt->cng_frame.datalen) { + memset(tech_pvt->cng_frame.data, 255, tech_pvt->cng_frame.datalen); *frame = &tech_pvt->cng_frame; //printf("GENERATE bytes=%d payload=%d frames=%d samples=%d ms=%d ts=%d sampcount=%d\n", tech_pvt->cng_frame.datalen, payload, frames, samples, ms, tech_pvt->timestamp_recv, tech_pvt->read_frame.samples); switch_set_flag(tech_pvt, TFLAG_SILENCE); @@ -767,9 +767,11 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr for (x = 0; x < loops; x++) { - jrtp4c_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); + switch_rtp_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); + /* printf("Send %s packet for [%c] ts=%d sofar=%u dur=%d\n", loops == 1 ? "middle" : "end", tech_pvt->out_digit, ts, tech_pvt->out_digit_sofar, duration); + */ } } @@ -790,9 +792,11 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr ts = tech_pvt->timestamp_dtmf += samples; tech_pvt->out_digit_seq++; for (x = 0; x < 3; x++) { - jrtp4c_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); + switch_rtp_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); + /* printf("Send start packet for [%c] ts=%d sofar=%u dur=%d\n", tech_pvt->out_digit, ts, tech_pvt->out_digit_sofar, 0); + */ } free(rdigit); @@ -803,10 +807,10 @@ static switch_status channel_write_frame(switch_core_session *session, switch_fr - //printf("%s send %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), frame->datalen, samples, frames, ms, tech_pvt->timestamp_send); + //printf("%s send %d bytes %d samples in %d frames ts=%d\n", switch_channel_get_name(channel), frame->datalen, samples, frames, tech_pvt->timestamp_send); - jrtp4c_write(tech_pvt->rtp_session, frame->data, (int) frame->datalen, samples); + switch_rtp_write(tech_pvt->rtp_session, frame->data, (int) frame->datalen, samples); tech_pvt->timestamp_send += (int) samples; switch_clear_flag(tech_pvt, TFLAG_WRITING); @@ -1335,21 +1339,22 @@ static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsessi const char *err; switch_console_printf(SWITCH_CHANNEL_CONSOLE, "SETUP RTP %s:%d -> %s:%d\n", profile->ip, cand[0].port, tech_pvt->remote_ip, tech_pvt->remote_port); - if (!(tech_pvt->rtp_session = jrtp4c_new(profile->ip, - cand[0].port, - tech_pvt->remote_ip, - tech_pvt->remote_port, - tech_pvt->codec_num, - 8000, &err))) { + if (!(tech_pvt->rtp_session = switch_rtp_new(profile->ip, + cand[0].port, + tech_pvt->remote_ip, + tech_pvt->remote_port, + tech_pvt->codec_num, + switch_test_flag(tech_pvt->profile, PFLAG_GENSILENCE) ? SWITCH_RTP_NOBLOCK : 0, + &err, switch_core_session_get_pool(tech_pvt->session)))) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "RTP ERROR %s\n", err); switch_channel_hangup(channel); return LDL_STATUS_FALSE; } - tech_pvt->rtp_sock = jrtp4c_get_rtp_socket(tech_pvt->rtp_session); - jrtp4c_set_invald_handler(tech_pvt->rtp_session, stun_callback); - jrtp4c_set_private(tech_pvt->rtp_session, tech_pvt); + tech_pvt->rtp_sock = switch_rtp_get_rtp_socket(tech_pvt->rtp_session); + switch_rtp_set_invald_handler(tech_pvt->rtp_session, stun_callback); + switch_rtp_set_private(tech_pvt->rtp_session, tech_pvt); switch_set_flag(tech_pvt, TFLAG_RTP_READY); - jrtp4c_start(tech_pvt->rtp_session); + switch_rtp_start(tech_pvt->rtp_session); } return LDL_STATUS_SUCCESS; @@ -1386,7 +1391,7 @@ static ldl_status handle_response(ldl_handle_t *handle, char *id) return LDL_STATUS_SUCCESS; } -static void stun_callback(struct jrtp4c *jrtp4c, jrtp_socket_t sock, void *data, unsigned int len, uint32_t ip, uint16_t port) +static void stun_callback(struct switch_rtp *switch_rtp, switch_raw_socket_t sock, void *data, unsigned int len, uint32_t ip, uint16_t port) { stun_packet_t *packet; stun_packet_attribute_t *attr; @@ -1394,7 +1399,7 @@ static void stun_callback(struct jrtp4c *jrtp4c, jrtp_socket_t sock, void *data, struct private_object *tech_pvt; unsigned char buf[512] = {0}; - tech_pvt = jrtp4c_get_private(jrtp4c); + tech_pvt = switch_rtp_get_private(switch_rtp); assert(tech_pvt != NULL); memcpy(buf, data, len); diff --git a/src/mod/endpoints/mod_exosip/Makefile b/src/mod/endpoints/mod_exosip/Makefile index 44d61ba161..6630d7599b 100644 --- a/src/mod/endpoints/mod_exosip/Makefile +++ b/src/mod/endpoints/mod_exosip/Makefile @@ -10,7 +10,7 @@ endif all: depends $(OBJS) $(MODNAME).$(DYNAMIC_LIB_EXTEN) depends: - MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install jrtplib --prefix=$(PREFIX) --disable-gst + #MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install jrtplib --prefix=$(PREFIX) --disable-gst MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install libosip2-2.2.2.tar.gz --prefix=$(PREFIX) MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install libeXosip2-2.2.3-pre1.tar.gz --disable-josua --prefix=$(PREFIX) diff --git a/src/mod/endpoints/mod_exosip/mod_exosip.c b/src/mod/endpoints/mod_exosip/mod_exosip.c index 1131709f26..b846c3d323 100644 --- a/src/mod/endpoints/mod_exosip/mod_exosip.c +++ b/src/mod/endpoints/mod_exosip/mod_exosip.c @@ -32,7 +32,6 @@ #define HAVE_APR #include -#include #include #include #include @@ -101,8 +100,7 @@ struct private_object { switch_frame cng_frame; switch_codec read_codec; switch_codec write_codec; - unsigned char read_buf[SWITCH_RECCOMMENDED_BUFFER_SIZE]; - unsigned char cng_buf[SWITCH_RECCOMMENDED_BUFFER_SIZE]; + unsigned char cng_buf[320]; switch_caller_profile *caller_profile; int cid; int did; @@ -111,7 +109,7 @@ struct private_object { int32_t timestamp_recv; int32_t timestamp_dtmf; int payload_num; - struct jrtp4c *rtp_session; + struct switch_rtp *rtp_session; struct osip_rfc3264 *sdp_config; sdp_message_t *remote_sdp; sdp_message_t *local_sdp; @@ -248,8 +246,8 @@ static switch_status exosip_on_init(switch_core_session *session) tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - tech_pvt->read_frame.data = tech_pvt->read_buf; - tech_pvt->read_frame.buflen = sizeof(tech_pvt->read_buf); + tech_pvt->read_frame.data = tech_pvt->cng_buf; + tech_pvt->read_frame.buflen = sizeof(tech_pvt->cng_buf); tech_pvt->cng_frame.data = tech_pvt->cng_buf; tech_pvt->cng_frame.buflen = sizeof(tech_pvt->cng_buf); @@ -422,11 +420,11 @@ static void deactivate_rtp(struct private_object *tech_pvt) loops++; } /* - if ((sock = jrtp4c_get_rtp_socket(tech_pvt->rtp_session)) > -1) { + if ((sock = switch_rtp_get_rtp_socket(tech_pvt->rtp_session)) > -1) { close(sock); } */ - jrtp4c_destroy(&tech_pvt->rtp_session); + switch_rtp_destroy(&tech_pvt->rtp_session); tech_pvt->rtp_session = NULL; switch_mutex_unlock(tech_pvt->rtp_lock); } @@ -469,17 +467,18 @@ static void activate_rtp(struct private_object *tech_pvt) tech_pvt->remote_sdp_audio_port, tech_pvt->read_codec.codec_interface->ianacode, ms); - - tech_pvt->rtp_session = jrtp4c_new(tech_pvt->local_sdp_audio_ip, - tech_pvt->local_sdp_audio_port, - tech_pvt->remote_sdp_audio_ip, - tech_pvt->remote_sdp_audio_port, - tech_pvt->read_codec.codec_interface->ianacode, - tech_pvt->read_codec.implementation->samples_per_second, &err); + + tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip, + tech_pvt->local_sdp_audio_port, + tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, + tech_pvt->read_codec.codec_interface->ianacode, + 0, + &err, switch_core_session_get_pool(tech_pvt->session)); if (tech_pvt->rtp_session) { - tech_pvt->ssrc = jrtp4c_get_ssrc(tech_pvt->rtp_session); - jrtp4c_start(tech_pvt->rtp_session); + tech_pvt->ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session); + switch_rtp_start(tech_pvt->rtp_session); switch_set_flag(tech_pvt, TFLAG_RTP); } else { switch_channel *channel = switch_core_session_get_channel(tech_pvt->session); @@ -565,7 +564,7 @@ static switch_status exosip_read_frame(switch_core_session *session, switch_fram while (!switch_test_flag(tech_pvt, TFLAG_BYE) && switch_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) { now = switch_time_now(); - tech_pvt->read_frame.datalen = jrtp4c_read(tech_pvt->rtp_session, tech_pvt->read_frame.data, sizeof(tech_pvt->read_buf), &payload); + tech_pvt->read_frame.datalen = switch_rtp_zerocopy_read(tech_pvt->rtp_session, &tech_pvt->read_frame.data, &payload); if (switch_test_flag(tech_pvt, TFLAG_SILENCE)) { if (tech_pvt->read_frame.datalen) { @@ -659,7 +658,8 @@ static switch_status exosip_read_frame(switch_core_session *session, switch_fram } } else { - memset(tech_pvt->read_buf, 0, 160); + memset(tech_pvt->cng_buf, 0, 160); + tech_pvt->read_frame.data = tech_pvt->cng_buf; tech_pvt->read_frame.datalen = 160; } @@ -735,7 +735,7 @@ static switch_status exosip_write_frame(switch_core_session *session, switch_fra for (x = 0; x < loops; x++) { - jrtp4c_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); + switch_rtp_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); printf("Send %s packet for [%c] ts=%d sofar=%u dur=%d\n", loops == 1 ? "middle" : "end", tech_pvt->out_digit, @@ -762,7 +762,7 @@ static switch_status exosip_write_frame(switch_core_session *session, switch_fra ts = tech_pvt->timestamp_dtmf += samples; tech_pvt->out_digit_seq++; for (x = 0; x < 3; x++) { - jrtp4c_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); + switch_rtp_write_payload(tech_pvt->rtp_session, tech_pvt->out_digit_packet, 4, 101, ts, tech_pvt->out_digit_seq); printf("Send start packet for [%c] ts=%d sofar=%u dur=%d\n", tech_pvt->out_digit, ts, tech_pvt->out_digit_sofar, 0); } @@ -776,7 +776,7 @@ static switch_status exosip_write_frame(switch_core_session *session, switch_fra //printf("%s %s->%s send %d bytes %d samples in %d frames taking up %d ms ts=%d\n", switch_channel_get_name(channel), tech_pvt->local_sdp_audio_ip, tech_pvt->remote_sdp_audio_ip, frame->datalen, samples, frames, ms, tech_pvt->timestamp_send); - jrtp4c_write(tech_pvt->rtp_session, frame->data, (int) frame->datalen, samples); + switch_rtp_write(tech_pvt->rtp_session, frame->data, (int) frame->datalen, samples); tech_pvt->timestamp_send += (int) samples; switch_clear_flag(tech_pvt, TFLAG_WRITING); @@ -801,7 +801,7 @@ static switch_status exosip_kill_channel(switch_core_session *session, int sig) switch_set_flag(tech_pvt, TFLAG_BYE); if (tech_pvt->rtp_session) { - jrtp4c_killread(tech_pvt->rtp_session); + switch_rtp_killread(tech_pvt->rtp_session); } return SWITCH_STATUS_SUCCESS; diff --git a/src/switch_rtp.c b/src/switch_rtp.c new file mode 100644 index 0000000000..872a5107c3 --- /dev/null +++ b/src/switch_rtp.c @@ -0,0 +1,379 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005/2006, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * + * switch_rtp.c -- RTP + * + */ + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_NETINET_IN_H +# include +#elif defined HAVE_WINSOCK2_H +# include +# include +# define RTPW_USE_WINSOCK2 1 +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif + + + +#ifdef RTPW_USE_WINSOCK2 +# define DICT_FILE "words.txt" +#else +# define DICT_FILE "/usr/share/dict/words" +#endif +#define USEC_RATE (5e5) +#define MAX_WORD_LEN 128 +#define ADDR_IS_MULTICAST(a) IN_MULTICAST(htonl(a)) +#define MAX_KEY_LEN 64 +#define MASTER_KEY_LEN 30 + +#include +#undef PACKAGE_NAME +#undef PACKAGE_STRING +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef PACKAGE_BUGREPORT +#include +#include + +#include +#include +#include + + +#define do_close(s) if (s > -1) {close(s); s = -1;} + +#define rtp_header_len 12 + +typedef srtp_hdr_t rtp_hdr_t; + +#define RTP_MAX_BUF_LEN 16384 + +typedef struct { + srtp_hdr_t header; + char body[RTP_MAX_BUF_LEN]; +} rtp_msg_t; + + +struct switch_rtp { + switch_raw_socket_t sock; + + struct sockaddr_in local_addr; + rtp_msg_t send_msg; + srtp_ctx_t *send_ctx; + + struct sockaddr_in remote_addr; + rtp_msg_t recv_msg; + srtp_ctx_t *recv_ctx; + + uint32_t seq; + uint32_t payload; + + switch_rtp_invalid_handler invalid_handler; + void *private_data; + + uint32_t ts; + uint32_t flags; +}; + +static int global_init = 0; + +static void init_rtp(void) +{ + if (global_init) { + return; + } + +#ifdef RTPW_USE_WINSOCK2 + WORD wVersionRequested = MAKEWORD(2, 0); + WSADATA wsaData; + + ret = WSAStartup(wVersionRequested, &wsaData); +#endif + + srtp_init(); + global_init = 1; + +} + +switch_rtp *switch_rtp_new(char *rx_ip, + int rx_port, + char *tx_ip, + int tx_port, + int payload, + switch_rtp_flag_t flags, + const char **err, + switch_memory_pool *pool) +{ + switch_raw_socket_t sock; + switch_rtp *rtp_session = NULL; + struct in_addr rx_addr, tx_addr; + srtp_policy_t policy; + char key[MAX_KEY_LEN]; + uint32_t ssrc = rand() & 0xffff; + + if (!global_init) { + init_rtp(); + } + + if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + *err = "Socket Error!\n"; + return NULL; + } + + if (!inet_aton(rx_ip, &rx_addr)) { + *err = "RX Address Error!\n"; + return NULL; + } + + if (!inet_aton(tx_ip, &tx_addr)) { + *err = "TX Address Error!\n"; + return NULL; + } + + if (!(rtp_session = switch_core_alloc(pool, sizeof(*rtp_session)))) { + *err = "Memory Error!"; + return NULL; + } + + rtp_session->flags = flags; + rtp_session->local_addr.sin_addr = rx_addr; + rtp_session->local_addr.sin_family = PF_INET; + rtp_session->local_addr.sin_port = htons(rx_port); + + rtp_session->remote_addr.sin_addr = tx_addr; + rtp_session->remote_addr.sin_family = PF_INET; + rtp_session->remote_addr.sin_port = htons(tx_port); + rtp_session->sock = sock; + + + if (bind(sock, (struct sockaddr *)&rtp_session->local_addr, sizeof(rtp_session->local_addr)) < 0) { + *err = "Bind Err!"; + close(sock); + return NULL; + } + + if switch_test_flag(rtp_session, SWITCH_RTP_NOBLOCK) { + fcntl(sock, F_SETFL, O_NONBLOCK); + } + + policy.key = (uint8_t *)key; + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = ssrc; + policy.rtp.cipher_type = NULL_CIPHER; + policy.rtp.cipher_key_len = 0; + policy.rtp.auth_type = NULL_AUTH; + policy.rtp.auth_key_len = 0; + policy.rtp.auth_tag_len = 0; + policy.rtp.sec_serv = sec_serv_none; + policy.rtcp.cipher_type = NULL_CIPHER; + policy.rtcp.cipher_key_len = 0; + policy.rtcp.auth_type = NULL_AUTH; + policy.rtcp.auth_key_len = 0; + policy.rtcp.auth_tag_len = 0; + policy.rtcp.sec_serv = sec_serv_none; + policy.next = NULL; + + + rtp_session->send_msg.header.ssrc = htonl(ssrc); + rtp_session->send_msg.header.ts = 0; + rtp_session->send_msg.header.seq = (uint16_t) rand(); + rtp_session->send_msg.header.m = 0; + rtp_session->send_msg.header.pt = htonl(payload); + rtp_session->send_msg.header.version = 2; + rtp_session->send_msg.header.p = 0; + rtp_session->send_msg.header.x = 0; + rtp_session->send_msg.header.cc = 0; + + + rtp_session->recv_msg.header.ssrc = htonl(ssrc); + rtp_session->recv_msg.header.ts = 0; + rtp_session->recv_msg.header.seq = 0; + rtp_session->recv_msg.header.m = 0; + rtp_session->recv_msg.header.pt = htonl(payload); + rtp_session->recv_msg.header.version = 2; + rtp_session->recv_msg.header.p = 0; + rtp_session->recv_msg.header.x = 0; + rtp_session->recv_msg.header.cc = 0; + + rtp_session->seq = rtp_session->send_msg.header.seq; + rtp_session->payload = payload; + srtp_create(&rtp_session->recv_ctx, &policy); + srtp_create(&rtp_session->send_ctx, &policy); + + return rtp_session; +} + +void switch_rtp_killread(switch_rtp *rtp_session) +{ + switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_IO); + shutdown(rtp_session->sock, SHUT_RDWR); +} + + +void switch_rtp_destroy(switch_rtp **rtp_session) +{ + + switch_rtp_killread(*rtp_session); + do_close((*rtp_session)->sock); + *rtp_session = NULL; + return; +} + +switch_raw_socket_t switch_rtp_get_rtp_socket(switch_rtp *rtp_session) +{ + return rtp_session->sock; +} + +void switch_rtp_set_invald_handler(switch_rtp *rtp_session, switch_rtp_invalid_handler on_invalid) +{ + rtp_session->invalid_handler = on_invalid; +} + +int switch_rtp_read(switch_rtp *rtp_session, void *data, uint32_t datalen, int *payload_type) +{ + int32_t bytes; + struct sockaddr_in in; + int len = sizeof(struct sockaddr_in); + + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) { + return -1; + } + + bytes = recvfrom(rtp_session->sock, (void *)&rtp_session->recv_msg, sizeof(rtp_msg_t), 0, (struct sockaddr *) &in, &len); + if (bytes <= 0) { + return 0; + } + + if (rtp_session->recv_msg.header.version != 2) { + if (rtp_session->invalid_handler) { + rtp_session->invalid_handler(rtp_session, rtp_session->sock, (void *) &rtp_session->recv_msg, bytes, in.sin_addr.s_addr, in.sin_port); + } + return 0; + } + memcpy(data, rtp_session->recv_msg.body, bytes); + *payload_type = rtp_session->recv_msg.header.pt; + return bytes - rtp_header_len; + +} + + +int switch_rtp_zerocopy_read(switch_rtp *rtp_session, void **data, int *payload_type) +{ + int32_t bytes; + struct sockaddr_in in; + int len = sizeof(struct sockaddr_in); + + *data = NULL; + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) { + return -1; + } + + bytes = recvfrom(rtp_session->sock, (void *)&rtp_session->recv_msg, sizeof(rtp_msg_t), 0, (struct sockaddr *) &in, &len); + if (bytes <= 0) { + return 0; + } + + if (rtp_session->recv_msg.header.version != 2) { + if (rtp_session->invalid_handler) { + rtp_session->invalid_handler(rtp_session, rtp_session->sock, (void *) &rtp_session->recv_msg, bytes, in.sin_addr.s_addr, ntohs(in.sin_port)); + } + return 0; + } + *payload_type = rtp_session->recv_msg.header.pt; + *data = rtp_session->recv_msg.body; + + return bytes - rtp_header_len; +} + +int switch_rtp_write(switch_rtp *rtp_session, void *data, int datalen, uint32_t ts) +{ + int32_t bytes; + + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) { + return -1; + } + rtp_session->ts += ts; + rtp_session->seq = ntohs(rtp_session->seq) + 1; + rtp_session->seq = htons(rtp_session->seq); + rtp_session->send_msg.header.seq = rtp_session->seq; + rtp_session->send_msg.header.ts = htonl(rtp_session->ts); + rtp_session->payload = htonl(rtp_session->payload); + + memcpy(rtp_session->send_msg.body, data, datalen); + bytes = sendto(rtp_session->sock, (void*)&rtp_session->send_msg, + datalen + rtp_header_len, 0, (struct sockaddr *)&rtp_session->remote_addr, sizeof (struct sockaddr_in)); + + return bytes; +} + +int switch_rtp_write_payload(switch_rtp *rtp_session, void *data, int datalen, int payload, uint32_t ts, uint32_t mseq) +{ + int32_t bytes; + + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) { + return -1; + } + rtp_session->ts += ts; + rtp_session->send_msg.header.seq = htons(mseq); + rtp_session->send_msg.header.ts = htonl(rtp_session->ts); + rtp_session->send_msg.header.pt = htonl(payload); + + memcpy(rtp_session->send_msg.body, data, datalen); + bytes = sendto(rtp_session->sock, (void*)&rtp_session->send_msg, + datalen + rtp_header_len, 0, (struct sockaddr *)&rtp_session->remote_addr, sizeof (struct sockaddr_in)); + + return bytes; +} + +uint32_t switch_rtp_start(switch_rtp *rtp_session) +{ + switch_set_flag(rtp_session, SWITCH_RTP_FLAG_IO); + return 0; +} + +uint32_t switch_rtp_get_ssrc(switch_rtp *rtp_session) +{ + return rtp_session->send_msg.header.ssrc; +} + +void switch_rtp_set_private(switch_rtp *rtp_session, void *private_data) +{ + rtp_session->private_data = private_data; +} + +void *switch_rtp_get_private(switch_rtp *rtp_session) +{ + return rtp_session->private_data; +} +